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, ¶m)) != 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, ¶m) != 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