1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2018-2019 JUUL Labs
5  * Copyright (c) 2019-2024 Arm Limited
6  */
7 
8 #include "mcuboot_config/mcuboot_config.h"
9 
10 #if defined(MCUBOOT_ENC_IMAGES)
11 #include <stddef.h>
12 #include <inttypes.h>
13 #include <string.h>
14 
15 #if defined(MCUBOOT_ENCRYPT_RSA)
16 #define BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED
17 #include "bootutil/crypto/rsa.h"
18 #endif
19 
20 #if defined(MCUBOOT_ENCRYPT_KW)
21 #include "bootutil/crypto/aes_kw.h"
22 #endif
23 
24 #if defined(MCUBOOT_ENCRYPT_EC256)
25 #include "bootutil/crypto/ecdh_p256.h"
26 #endif
27 
28 #if defined(MCUBOOT_ENCRYPT_X25519)
29 #include "bootutil/crypto/ecdh_x25519.h"
30 #endif
31 
32 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
33 #include "bootutil/crypto/sha.h"
34 #include "bootutil/crypto/hmac_sha256.h"
35 #include "mbedtls/oid.h"
36 #include "mbedtls/asn1.h"
37 #endif
38 
39 #include "bootutil/image.h"
40 #include "bootutil/enc_key.h"
41 #include "bootutil/sign_key.h"
42 #include "bootutil/crypto/common.h"
43 
44 #include "bootutil_priv.h"
45 
46 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
47 #if defined(_compare)
bootutil_constant_time_compare(const uint8_t * a,const uint8_t * b,size_t size)48 static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
49 {
50     return _compare(a, b, size);
51 }
52 #else
bootutil_constant_time_compare(const uint8_t * a,const uint8_t * b,size_t size)53 static int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
54 {
55     const uint8_t *tempa = a;
56     const uint8_t *tempb = b;
57     uint8_t result = 0;
58     unsigned int i;
59 
60     for (i = 0; i < size; i++) {
61         result |= tempa[i] ^ tempb[i];
62     }
63     return result;
64 }
65 #endif
66 #endif
67 
68 #if defined(MCUBOOT_ENCRYPT_KW)
69 static int
key_unwrap(const uint8_t * wrapped,uint8_t * enckey,struct bootutil_key * bootutil_enc_key)70 key_unwrap(const uint8_t *wrapped, uint8_t *enckey, struct bootutil_key *bootutil_enc_key)
71 {
72     bootutil_aes_kw_context aes_kw;
73     int rc;
74 
75     bootutil_aes_kw_init(&aes_kw);
76     rc = bootutil_aes_kw_set_unwrap_key(&aes_kw, bootutil_enc_key->key, *bootutil_enc_key->len);
77     if (rc != 0) {
78         goto done;
79     }
80     rc = bootutil_aes_kw_unwrap(&aes_kw, wrapped, TLV_ENC_KW_SZ, enckey, BOOT_ENC_KEY_SIZE);
81     if (rc != 0) {
82         goto done;
83     }
84 
85 done:
86     bootutil_aes_kw_drop(&aes_kw);
87     return rc;
88 }
89 #endif /* MCUBOOT_ENCRYPT_KW */
90 
91 #if defined(MCUBOOT_ENCRYPT_EC256)
92 static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
93 static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
94 
95 #define SHARED_KEY_LEN NUM_ECC_BYTES
96 #define PRIV_KEY_LEN   NUM_ECC_BYTES
97 
98 /*
99  * Parses the output of `imgtool keygen`, which produces a PKCS#8 elliptic
100  * curve keypair. See RFC5208 and RFC5915.
101  */
102 static int
parse_ec256_enckey(uint8_t ** p,uint8_t * end,uint8_t * private_key)103 parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
104 {
105     int rc;
106     size_t len;
107     int version;
108     mbedtls_asn1_buf alg;
109     mbedtls_asn1_buf param;
110 
111     if ((rc = mbedtls_asn1_get_tag(p, end, &len,
112                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
113         return -1;
114     }
115 
116     if (*p + len != end) {
117         return -2;
118     }
119 
120     version = 0;
121     if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
122         return -3;
123     }
124 
125     if ((rc = mbedtls_asn1_get_alg(p, end, &alg, &param)) != 0) {
126         return -5;
127     }
128 
129     if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
130         memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
131         return -6;
132     }
133     if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
134         memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
135         return -7;
136     }
137 
138     if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
139         return -8;
140     }
141 
142     /* RFC5915 - ECPrivateKey */
143 
144     if ((rc = mbedtls_asn1_get_tag(p, end, &len,
145                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
146         return -9;
147     }
148 
149     version = 0;
150     if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
151         return -10;
152     }
153 
154     /* privateKey */
155 
156     if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
157         return -11;
158     }
159 
160     if (len != NUM_ECC_BYTES) {
161         return -12;
162     }
163 
164     memcpy(private_key, *p, len);
165 
166     /* publicKey usually follows but is not parsed here */
167 
168     return 0;
169 }
170 #endif /* defined(MCUBOOT_ENCRYPT_EC256) */
171 
172 #if defined(MCUBOOT_ENCRYPT_X25519)
173 #define X25519_OID "\x6e"
174 static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
175                                        MBEDTLS_OID_ORG_GOV X25519_OID;
176 
177 #define SHARED_KEY_LEN 32
178 #define PRIV_KEY_LEN   32
179 
180 static int
parse_x25519_enckey(uint8_t ** p,uint8_t * end,uint8_t * private_key)181 parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
182 {
183     size_t len;
184     int version;
185     mbedtls_asn1_buf alg;
186     mbedtls_asn1_buf param;
187 
188     if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
189                                            MBEDTLS_ASN1_SEQUENCE) != 0) {
190         return -1;
191     }
192 
193     if (*p + len != end) {
194         return -2;
195     }
196 
197     version = 0;
198     if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
199         return -3;
200     }
201 
202     if (mbedtls_asn1_get_alg(p, end, &alg, &param) != 0) {
203         return -4;
204     }
205 
206     if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
207         memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
208         return -5;
209     }
210 
211     if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
212         return -6;
213     }
214 
215     if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
216         return -7;
217     }
218 
219     if (len != PRIV_KEY_LEN) {
220         return -8;
221     }
222 
223     memcpy(private_key, *p, PRIV_KEY_LEN);
224     return 0;
225 }
226 #endif /* defined(MCUBOOT_ENCRYPT_X25519) */
227 
228 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
229 /*
230  * HKDF as described by RFC5869.
231  *
232  * @param ikm       The input data to be derived.
233  * @param ikm_len   Length of the input data.
234  * @param info      An information tag.
235  * @param info_len  Length of the information tag.
236  * @param okm       Output of the KDF computation.
237  * @param okm_len   On input the requested length; on output the generated length
238  */
239 static int
hkdf(uint8_t * ikm,uint16_t ikm_len,uint8_t * info,uint16_t info_len,uint8_t * okm,uint16_t * okm_len)240 hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
241         uint8_t *okm, uint16_t *okm_len)
242 {
243     bootutil_hmac_sha256_context hmac;
244     uint8_t salt[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
245     uint8_t prk[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
246     uint8_t T[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
247     uint16_t off;
248     uint16_t len;
249     uint8_t counter;
250     bool first;
251     int rc;
252 
253     /*
254      * Extract
255      */
256 
257     if (ikm == NULL || okm == NULL || ikm_len == 0) {
258         return -1;
259     }
260 
261     bootutil_hmac_sha256_init(&hmac);
262 
263     memset(salt, 0, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
264     rc = bootutil_hmac_sha256_set_key(&hmac, salt, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
265     if (rc != 0) {
266         goto error;
267     }
268 
269     rc = bootutil_hmac_sha256_update(&hmac, ikm, ikm_len);
270     if (rc != 0) {
271         goto error;
272     }
273 
274     rc = bootutil_hmac_sha256_finish(&hmac, prk, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
275     if (rc != 0) {
276         goto error;
277     }
278 
279     bootutil_hmac_sha256_drop(&hmac);
280 
281     /*
282      * Expand
283      */
284 
285     len = *okm_len;
286     counter = 1;
287     first = true;
288     for (off = 0; len > 0; off += BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, ++counter) {
289         bootutil_hmac_sha256_init(&hmac);
290 
291         rc = bootutil_hmac_sha256_set_key(&hmac, prk, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
292         if (rc != 0) {
293             goto error;
294         }
295 
296         if (first) {
297             first = false;
298         } else {
299             rc = bootutil_hmac_sha256_update(&hmac, T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
300             if (rc != 0) {
301                 goto error;
302             }
303         }
304 
305         rc = bootutil_hmac_sha256_update(&hmac, info, info_len);
306         if (rc != 0) {
307             goto error;
308         }
309 
310         rc = bootutil_hmac_sha256_update(&hmac, &counter, 1);
311         if (rc != 0) {
312             goto error;
313         }
314 
315         rc = bootutil_hmac_sha256_finish(&hmac, T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
316         if (rc != 0) {
317             goto error;
318         }
319 
320         bootutil_hmac_sha256_drop(&hmac);
321 
322         if (len > BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE) {
323             memcpy(&okm[off], T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
324             len -= BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE;
325         } else {
326             memcpy(&okm[off], T, len);
327             len = 0;
328         }
329     }
330 
331     return 0;
332 
333 error:
334     bootutil_hmac_sha256_drop(&hmac);
335     return -1;
336 }
337 #endif /* MCUBOOT_ENCRYPT_EC256 || MCUBOOT_ENCRYPT_X25519 */
338 
339 #if !defined(MCUBOOT_ENC_BUILTIN_KEY)
340 extern const struct bootutil_key bootutil_enc_key;
341 
342 /*
343  * Default implementation to retrieve the private encryption key which is
344  * embedded in the bootloader code (when MCUBOOT_ENC_BUILTIN_KEY is not defined).
345  */
boot_enc_retrieve_private_key(struct bootutil_key ** private_key)346 int boot_enc_retrieve_private_key(struct bootutil_key **private_key)
347 {
348     *private_key = (struct bootutil_key *)&bootutil_enc_key;
349 
350     return 0;
351 }
352 #endif /* !MCUBOOT_ENC_BUILTIN_KEY */
353 
354 int
boot_enc_init(struct enc_key_data * enc_state,uint8_t slot)355 boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
356 {
357     bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
358     return 0;
359 }
360 
361 int
boot_enc_drop(struct enc_key_data * enc_state,uint8_t slot)362 boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
363 {
364     bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
365     enc_state[slot].valid = 0;
366     return 0;
367 }
368 
369 int
boot_enc_set_key(struct enc_key_data * enc_state,uint8_t slot,const struct boot_status * bs)370 boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
371         const struct boot_status *bs)
372 {
373     int rc;
374 
375     rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
376     if (rc != 0) {
377         boot_enc_drop(enc_state, slot);
378         return -1;
379     }
380 
381     enc_state[slot].valid = 1;
382 
383     return 0;
384 }
385 
386 #define EXPECTED_ENC_LEN        BOOT_ENC_TLV_SIZE
387 
388 #if defined(MCUBOOT_ENCRYPT_RSA)
389 #    define EXPECTED_ENC_TLV    IMAGE_TLV_ENC_RSA2048
390 #elif defined(MCUBOOT_ENCRYPT_KW)
391 #    define EXPECTED_ENC_TLV    IMAGE_TLV_ENC_KW
392 #elif defined(MCUBOOT_ENCRYPT_EC256)
393 #    define EXPECTED_ENC_TLV    IMAGE_TLV_ENC_EC256
394 #    define EC_PUBK_INDEX       (0)
395 #    define EC_TAG_INDEX        (65)
396 #    define EC_CIPHERKEY_INDEX  (65 + 32)
397 _Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
398         "Please fix ECIES-P256 component indexes");
399 #elif defined(MCUBOOT_ENCRYPT_X25519)
400 #    define EXPECTED_ENC_TLV    IMAGE_TLV_ENC_X25519
401 #    define EC_PUBK_INDEX       (0)
402 #    define EC_TAG_INDEX        (32)
403 #    define EC_CIPHERKEY_INDEX  (32 + 32)
404 _Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
405         "Please fix ECIES-X25519 component indexes");
406 #endif
407 
408 #if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \
409       (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) )
410 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
fake_rng(void * p_rng,unsigned char * output,size_t len)411 static int fake_rng(void *p_rng, unsigned char *output, size_t len)
412 {
413     size_t i;
414 
415     (void)p_rng;
416     for (i = 0; i < len; i++) {
417         output[i] = (char)i;
418     }
419 
420     return 0;
421 }
422 #endif /* MBEDTLS_VERSION_NUMBER */
423 #endif /* (MCUBOOT_ENCRYPT_RSA && MCUBOOT_USE_MBED_TLS && !MCUBOOT_USE_PSA_CRYPTO) ||
424           (MCUBOOT_ENCRYPT_EC256 && MCUBOOT_USE_MBED_TLS) */
425 
426 /*
427  * Decrypt an encryption key TLV.
428  *
429  * @param buf An encryption TLV read from flash (build time fixed length)
430  * @param enckey An AES-128 or AES-256 key sized buffer to store to plain key.
431  */
432 int
boot_decrypt_key(const uint8_t * buf,uint8_t * enckey)433 boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)
434 {
435 #if defined(MCUBOOT_ENCRYPT_RSA)
436     bootutil_rsa_context rsa;
437     uint8_t *cp;
438     uint8_t *cpend;
439     size_t olen;
440 #endif
441 #if defined(MCUBOOT_ENCRYPT_EC256)
442     bootutil_ecdh_p256_context ecdh_p256;
443 #endif
444 #if defined(MCUBOOT_ENCRYPT_X25519)
445     bootutil_ecdh_x25519_context ecdh_x25519;
446 #endif
447 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
448     bootutil_hmac_sha256_context hmac;
449     bootutil_aes_ctr_context aes_ctr;
450     uint8_t tag[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
451     uint8_t shared[SHARED_KEY_LEN];
452     uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
453     uint8_t *cp;
454     uint8_t *cpend;
455     uint8_t private_key[PRIV_KEY_LEN];
456     uint8_t counter[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
457     uint16_t len;
458 #endif
459     struct bootutil_key *bootutil_enc_key = NULL;
460     int rc = -1;
461 
462     rc = boot_enc_retrieve_private_key(&bootutil_enc_key);
463     if (rc) {
464         return rc;
465     }
466 
467     if (bootutil_enc_key == NULL) {
468         return rc;
469     }
470 
471 #if defined(MCUBOOT_ENCRYPT_RSA)
472 
473     bootutil_rsa_init(&rsa);
474     cp = (uint8_t *)bootutil_enc_key->key;
475     cpend = cp + *bootutil_enc_key->len;
476 
477     /* The enckey is encrypted through RSA so for decryption we need the private key */
478     rc = bootutil_rsa_parse_private_key(&rsa, &cp, cpend);
479     if (rc) {
480         bootutil_rsa_drop(&rsa);
481         return rc;
482     }
483 
484     rc = bootutil_rsa_oaep_decrypt(&rsa, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
485     bootutil_rsa_drop(&rsa);
486     if (rc) {
487         return rc;
488     }
489 
490 #endif /* defined(MCUBOOT_ENCRYPT_RSA) */
491 
492 #if defined(MCUBOOT_ENCRYPT_KW)
493 
494     assert(*bootutil_enc_key->len == BOOT_ENC_KEY_SIZE);
495     rc = key_unwrap(buf, enckey, bootutil_enc_key);
496 
497 #endif /* defined(MCUBOOT_ENCRYPT_KW) */
498 
499 #if defined(MCUBOOT_ENCRYPT_EC256)
500 
501     cp = (uint8_t *)bootutil_enc_key->key;
502     cpend = cp + *bootutil_enc_key->len;
503 
504     /*
505      * Load the stored EC256 decryption private key
506      */
507 
508     rc = parse_ec256_enckey(&cp, cpend, private_key);
509     if (rc) {
510         return rc;
511     }
512 
513     /*
514      * First "element" in the TLV is the curve point (public key)
515      */
516     bootutil_ecdh_p256_init(&ecdh_p256);
517 
518     rc = bootutil_ecdh_p256_shared_secret(&ecdh_p256, &buf[EC_PUBK_INDEX], private_key, shared);
519     bootutil_ecdh_p256_drop(&ecdh_p256);
520     if (rc != 0) {
521         return -1;
522     }
523 
524 #endif /* defined(MCUBOOT_ENCRYPT_EC256) */
525 
526 #if defined(MCUBOOT_ENCRYPT_X25519)
527 
528     cp = (uint8_t *)bootutil_enc_key->key;
529     cpend = cp + *bootutil_enc_key->len;
530 
531     /*
532      * Load the stored X25519 decryption private key
533      */
534 
535     rc = parse_x25519_enckey(&cp, cpend, private_key);
536     if (rc) {
537         return rc;
538     }
539 
540     /*
541      * First "element" in the TLV is the curve point (public key)
542      */
543 
544     bootutil_ecdh_x25519_init(&ecdh_x25519);
545 
546     rc = bootutil_ecdh_x25519_shared_secret(&ecdh_x25519, &buf[EC_PUBK_INDEX], private_key, shared);
547     bootutil_ecdh_x25519_drop(&ecdh_x25519);
548     if (!rc) {
549         return -1;
550     }
551 
552 #endif /* defined(MCUBOOT_ENCRYPT_X25519) */
553 
554 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
555 
556     /*
557      * Expand shared secret to create keys for AES-128-CTR + HMAC-SHA256
558      */
559 
560     len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE;
561     rc = hkdf(shared, SHARED_KEY_LEN, (uint8_t *)"MCUBoot_ECIES_v1", 16,
562             derived_key, &len);
563     if (rc != 0 || len != (BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE)) {
564         return -1;
565     }
566 
567     /*
568      * HMAC the key and check that our received MAC matches the generated tag
569      */
570 
571     bootutil_hmac_sha256_init(&hmac);
572 
573     rc = bootutil_hmac_sha256_set_key(&hmac, &derived_key[BOOT_ENC_KEY_SIZE], 32);
574     if (rc != 0) {
575         (void)bootutil_hmac_sha256_drop(&hmac);
576         return -1;
577     }
578 
579     rc = bootutil_hmac_sha256_update(&hmac, &buf[EC_CIPHERKEY_INDEX], BOOT_ENC_KEY_SIZE);
580     if (rc != 0) {
581         (void)bootutil_hmac_sha256_drop(&hmac);
582         return -1;
583     }
584 
585     /* Assumes the tag buffer is at least sizeof(hmac_tag_size(state)) bytes */
586     rc = bootutil_hmac_sha256_finish(&hmac, tag, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
587     if (rc != 0) {
588         (void)bootutil_hmac_sha256_drop(&hmac);
589         return -1;
590     }
591 
592     if (bootutil_constant_time_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
593         (void)bootutil_hmac_sha256_drop(&hmac);
594         return -1;
595     }
596 
597     bootutil_hmac_sha256_drop(&hmac);
598 
599     /*
600      * Finally decrypt the received ciphered key
601      */
602 
603     bootutil_aes_ctr_init(&aes_ctr);
604     if (rc != 0) {
605         bootutil_aes_ctr_drop(&aes_ctr);
606         return -1;
607     }
608 
609     rc = bootutil_aes_ctr_set_key(&aes_ctr, derived_key);
610     if (rc != 0) {
611         bootutil_aes_ctr_drop(&aes_ctr);
612         return -1;
613     }
614 
615     memset(counter, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
616     rc = bootutil_aes_ctr_decrypt(&aes_ctr, counter, &buf[EC_CIPHERKEY_INDEX], BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, 0, enckey);
617     if (rc != 0) {
618         bootutil_aes_ctr_drop(&aes_ctr);
619         return -1;
620     }
621 
622     bootutil_aes_ctr_drop(&aes_ctr);
623 
624     rc = 0;
625 
626 #endif /* defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) */
627 
628     return rc;
629 }
630 
631 /*
632  * Load encryption key.
633  */
634 int
boot_enc_load(struct enc_key_data * enc_state,int slot,const struct image_header * hdr,const struct flash_area * fap,struct boot_status * bs)635 boot_enc_load(struct enc_key_data *enc_state, int slot,
636         const struct image_header *hdr, const struct flash_area *fap,
637         struct boot_status *bs)
638 {
639     uint32_t off;
640     uint16_t len;
641     struct image_tlv_iter it;
642 #if MCUBOOT_SWAP_SAVE_ENCTLV
643     uint8_t *buf;
644 #else
645     uint8_t buf[EXPECTED_ENC_LEN];
646 #endif
647     int rc;
648 
649     /* Already loaded... */
650     if (enc_state[slot].valid) {
651         return 1;
652     }
653 
654     /* Initialize the AES context */
655     boot_enc_init(enc_state, slot);
656 
657     rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_ENC_TLV, false);
658     if (rc) {
659         return -1;
660     }
661 
662     rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
663     if (rc != 0) {
664         return rc;
665     }
666 
667     if (len != EXPECTED_ENC_LEN) {
668         return -1;
669     }
670 
671 #if MCUBOOT_SWAP_SAVE_ENCTLV
672     buf = bs->enctlv[slot];
673     memset(buf, 0xff, BOOT_ENC_TLV_ALIGN_SIZE);
674 #endif
675 
676     rc = flash_area_read(fap, off, buf, EXPECTED_ENC_LEN);
677     if (rc) {
678         return -1;
679     }
680 
681     return boot_decrypt_key(buf, bs->enckey[slot]);
682 }
683 
684 bool
boot_enc_valid(struct enc_key_data * enc_state,int slot)685 boot_enc_valid(struct enc_key_data *enc_state, int slot)
686 {
687     return enc_state[slot].valid;
688 }
689 
690 void
boot_enc_encrypt(struct enc_key_data * enc_state,int slot,uint32_t off,uint32_t sz,uint32_t blk_off,uint8_t * buf)691 boot_enc_encrypt(struct enc_key_data *enc_state, int slot, uint32_t off,
692              uint32_t sz, uint32_t blk_off, uint8_t *buf)
693 {
694     struct enc_key_data *enc = &enc_state[slot];
695     uint8_t nonce[16];
696 
697     /* Nothing to do with size == 0 */
698     if (sz == 0) {
699        return;
700     }
701 
702     memset(nonce, 0, 12);
703     off >>= 4;
704     nonce[12] = (uint8_t)(off >> 24);
705     nonce[13] = (uint8_t)(off >> 16);
706     nonce[14] = (uint8_t)(off >> 8);
707     nonce[15] = (uint8_t)off;
708 
709     assert(enc->valid == 1);
710     bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
711 }
712 
713 void
boot_enc_decrypt(struct enc_key_data * enc_state,int slot,uint32_t off,uint32_t sz,uint32_t blk_off,uint8_t * buf)714 boot_enc_decrypt(struct enc_key_data *enc_state, int slot, uint32_t off,
715              uint32_t sz, uint32_t blk_off, uint8_t *buf)
716 {
717     struct enc_key_data *enc = &enc_state[slot];
718     uint8_t nonce[16];
719 
720     /* Nothing to do with size == 0 */
721     if (sz == 0) {
722        return;
723     }
724 
725     memset(nonce, 0, 12);
726     off >>= 4;
727     nonce[12] = (uint8_t)(off >> 24);
728     nonce[13] = (uint8_t)(off >> 16);
729     nonce[14] = (uint8_t)(off >> 8);
730     nonce[15] = (uint8_t)off;
731 
732     assert(enc->valid == 1);
733     bootutil_aes_ctr_decrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
734 }
735 
736 /**
737  * Clears encrypted state after use.
738  */
739 void
boot_enc_zeroize(struct enc_key_data * enc_state)740 boot_enc_zeroize(struct enc_key_data *enc_state)
741 {
742     uint8_t slot;
743     for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
744         (void)boot_enc_drop(enc_state, slot);
745     }
746     memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
747 }
748 
749 #endif /* MCUBOOT_ENC_IMAGES */
750