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