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