blob: 951c8009802eda88ee7f8327bfba1b8d9a685e62 [file] [log] [blame]
Fabio Utzigba829042018-09-18 08:29:34 -03001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include "mcuboot_config/mcuboot_config.h"
21
22#if defined(MCUBOOT_ENC_IMAGES)
23#include <assert.h>
24#include <stddef.h>
25#include <inttypes.h>
26#include <string.h>
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020027#include <stdio.h>
Fabio Utzigba829042018-09-18 08:29:34 -030028
29#include "hal/hal_flash.h"
30
31#if defined(MCUBOOT_ENCRYPT_RSA)
32#include "mbedtls/rsa.h"
Fabio Utzig6f4d8f82019-12-12 18:46:06 -030033#include "mbedtls/rsa_internal.h"
Fabio Utzigba829042018-09-18 08:29:34 -030034#include "mbedtls/asn1.h"
35#endif
36
37#if defined(MCUBOOT_ENCRYPT_KW)
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020038# if defined(MCUBOOT_USE_MBED_TLS)
39# include "mbedtls/nist_kw.h"
40# include "mbedtls/aes.h"
41# else
42# include "tinycrypt/aes.h"
43# endif
Fabio Utzigba829042018-09-18 08:29:34 -030044#endif
45
Fabio Utzig5fde8322019-10-23 12:23:08 -030046#if defined(MCUBOOT_ENCRYPT_EC256)
47#include "tinycrypt/utils.h"
48#include "tinycrypt/constants.h"
49#include "tinycrypt/ecc.h"
50#include "tinycrypt/ecc_dh.h"
51#include "tinycrypt/ctr_mode.h"
52#include "tinycrypt/hmac.h"
53#include "mbedtls/oid.h"
54#include "mbedtls/asn1.h"
55#endif
56
Fabio Utzigba829042018-09-18 08:29:34 -030057#include "bootutil/image.h"
58#include "bootutil/enc_key.h"
59#include "bootutil/sign_key.h"
60
61#include "bootutil_priv.h"
62
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020063#if defined(MCUBOOT_ENCRYPT_KW)
64#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030065static int
Fabio Utzig4741c452019-12-19 15:32:41 -030066key_unwrap(const uint8_t *wrapped, uint8_t *enckey)
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020067{
68 mbedtls_nist_kw_context kw;
69 int rc;
70 size_t olen;
71
72 mbedtls_nist_kw_init(&kw);
73
74 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES,
75 bootutil_enc_key.key, *bootutil_enc_key.len * 8, 0);
76 if (rc) {
77 goto done;
78 }
79
80 rc = mbedtls_nist_kw_unwrap(&kw, MBEDTLS_KW_MODE_KW, wrapped, TLV_ENC_KW_SZ,
81 enckey, &olen, BOOT_ENC_KEY_SIZE);
82
83done:
84 mbedtls_nist_kw_free(&kw);
85 return rc;
86}
87#else /* !MCUBOOT_USE_MBED_TLS */
88/*
89 * Implements AES key unwrapping following RFC-3394 section 2.2.2, using
90 * tinycrypt for AES-128 decryption.
91 */
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030092static int
Fabio Utzig4741c452019-12-19 15:32:41 -030093key_unwrap(const uint8_t *wrapped, uint8_t *enckey)
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020094{
95 struct tc_aes_key_sched_struct aes;
96 uint8_t A[8];
97 uint8_t B[16];
98 int8_t i, j, k;
99
100 if (tc_aes128_set_decrypt_key(&aes, bootutil_enc_key.key) == 0) {
101 return -1;
102 }
103
104 for (k = 0; k < 8; k++) {
105 A[k] = wrapped[k];
106 enckey[k] = wrapped[8 + k];
107 enckey[8 + k] = wrapped[16 + k];
108 }
109
110 for (j = 5; j >= 0; j--) {
111 for (i = 2; i > 0; i--) {
112 for (k = 0; k < 8; k++) {
113 B[k] = A[k];
114 B[8 + k] = enckey[((i-1) * 8) + k];
115 }
116 B[7] ^= 2 * j + i;
117 if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, &aes) == 0) {
118 return -1;
119 }
120 for (k = 0; k < 8; k++) {
121 A[k] = B[k];
122 enckey[((i-1) * 8) + k] = B[8 + k];
123 }
124 }
125 }
126
127 for (i = 0, k = 0; i < 8; i++) {
128 k |= A[i] ^ 0xa6;
129 }
130 if (k) {
131 return -1;
132 }
133 return 0;
134}
135#endif /* MCUBOOT_USE_MBED_TLS */
136#endif /* MCUBOOT_ENCRYPT_KW */
137
Fabio Utzigba829042018-09-18 08:29:34 -0300138#if defined(MCUBOOT_ENCRYPT_RSA)
139static int
Fabio Utzig5fde8322019-10-23 12:23:08 -0300140parse_rsa_enckey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
Fabio Utzigba829042018-09-18 08:29:34 -0300141{
Fabio Utzigba829042018-09-18 08:29:34 -0300142 size_t len;
143
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300144 if (mbedtls_asn1_get_tag(p, end, &len,
145 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
Fabio Utzigba829042018-09-18 08:29:34 -0300146 return -1;
147 }
148
149 if (*p + len != end) {
150 return -2;
151 }
152
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300153 /* Non-optional fields. */
Fabio Utzigba829042018-09-18 08:29:34 -0300154 if ( /* version */
155 mbedtls_asn1_get_int(p, end, &ctx->ver) != 0 ||
156 /* public modulus */
157 mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0 ||
158 /* public exponent */
159 mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0 ||
160 /* private exponent */
161 mbedtls_asn1_get_mpi(p, end, &ctx->D) != 0 ||
162 /* primes */
163 mbedtls_asn1_get_mpi(p, end, &ctx->P) != 0 ||
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300164 mbedtls_asn1_get_mpi(p, end, &ctx->Q) != 0) {
165
Fabio Utzigba829042018-09-18 08:29:34 -0300166 return -3;
167 }
168
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300169#if !defined(MBEDTLS_RSA_NO_CRT)
170 /*
171 * DP/DQ/QP are only used inside mbedTLS if it was built with the
172 * Chinese Remainder Theorem enabled (default). In case it is disabled
173 * we parse, or if not available, we calculate those values.
174 */
175 if (*p < end) {
176 if ( /* d mod (p-1) and d mod (q-1) */
177 mbedtls_asn1_get_mpi(p, end, &ctx->DP) != 0 ||
178 mbedtls_asn1_get_mpi(p, end, &ctx->DQ) != 0 ||
179 /* q ^ (-1) mod p */
180 mbedtls_asn1_get_mpi(p, end, &ctx->QP) != 0) {
181
182 return -4;
183 }
184 } else {
185 if (mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
186 &ctx->DP, &ctx->DQ, &ctx->QP) != 0) {
187 return -5;
188 }
189 }
190#endif
191
Fabio Utzigba829042018-09-18 08:29:34 -0300192 ctx->len = mbedtls_mpi_size(&ctx->N);
193
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300194 if (mbedtls_rsa_check_privkey(ctx) != 0) {
195 return -6;
Fabio Utzigba829042018-09-18 08:29:34 -0300196 }
197
198 return 0;
199}
200#endif
201
Fabio Utzig5fde8322019-10-23 12:23:08 -0300202#if defined(MCUBOOT_ENCRYPT_EC256)
203static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
204static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
205
206/*
207 * Parses the output of `imgtool keygen`, which produces a PKCS#8 elliptic
208 * curve keypair. See RFC5208 and RFC5915.
209 */
210static int
211parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *pk)
212{
213 int rc;
214 size_t len;
215 int version;
216 mbedtls_asn1_buf alg;
217 mbedtls_asn1_buf param;
218
219 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
220 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
221 return -1;
222 }
223
224 if (*p + len != end) {
225 return -2;
226 }
227
228 version = 0;
229 if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
230 return -3;
231 }
232
233 if ((rc = mbedtls_asn1_get_alg(p, end, &alg, &param)) != 0) {
234 return -5;
235 }
236
237 if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
238 memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
239 return -6;
240 }
241 if (param.len != sizeof(ec_secp256r1_oid) - 1 ||
242 memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
243 return -7;
244 }
245
246 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
247 return -8;
248 }
249
250 /* RFC5915 - ECPrivateKey */
251
252 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
253 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
254 return -9;
255 }
256
257 version = 0;
258 if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
259 return -10;
260 }
261
262 /* privateKey */
263
264 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
265 return -11;
266 }
267
268 if (len != NUM_ECC_BYTES) {
269 return -12;
270 }
271
272 memcpy(pk, *p, len);
273
274 /* publicKey usually follows but is not parsed here */
275
276 return 0;
277}
278
279/*
280 * HKDF as described by RFC5869.
281 *
282 * @param ikm The input data to be derived.
283 * @param ikm_len Length of the input data.
284 * @param info An information tag.
285 * @param info_len Length of the information tag.
286 * @param okm Output of the KDF computation.
287 * @param okm_len On input the requested length; on output the generated length
288 */
289static int
290hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
291 uint8_t *okm, uint16_t *okm_len)
292{
293 struct tc_hmac_state_struct hmac;
294 uint8_t salt[TC_SHA256_DIGEST_SIZE];
295 uint8_t prk[TC_SHA256_DIGEST_SIZE];
296 uint8_t T[TC_SHA256_DIGEST_SIZE];
297 uint16_t off;
298 uint16_t len;
299 uint8_t counter;
300 bool first;
301 int rc;
302
303 /*
304 * Extract
305 */
306
307 if (ikm == NULL || okm == NULL || ikm_len == 0) {
308 return -1;
309 }
310
311 memset(salt, 0, TC_SHA256_DIGEST_SIZE);
312 rc = tc_hmac_set_key(&hmac, salt, TC_SHA256_DIGEST_SIZE);
313 if (rc != TC_CRYPTO_SUCCESS) {
314 return -1;
315 }
316
317 rc = tc_hmac_init(&hmac);
318 if (rc != TC_CRYPTO_SUCCESS) {
319 return -1;
320 }
321
322 rc = tc_hmac_update(&hmac, ikm, ikm_len);
323 if (rc != TC_CRYPTO_SUCCESS) {
324 return -1;
325 }
326
327 rc = tc_hmac_final(prk, TC_SHA256_DIGEST_SIZE, &hmac);
328 if (rc != TC_CRYPTO_SUCCESS) {
329 return -1;
330 }
331
332 /*
333 * Expand
334 */
335
336 len = *okm_len;
337 counter = 1;
338 first = true;
339 for (off = 0; len > 0; off += TC_SHA256_DIGEST_SIZE, ++counter) {
340 rc = tc_hmac_set_key(&hmac, prk, TC_SHA256_DIGEST_SIZE);
341 if (rc != TC_CRYPTO_SUCCESS) {
342 return -1;
343 }
344
345 rc = tc_hmac_init(&hmac);
346 if (rc != TC_CRYPTO_SUCCESS) {
347 return -1;
348 }
349
350 if (first) {
351 first = false;
352 } else {
353 rc = tc_hmac_update(&hmac, T, TC_SHA256_DIGEST_SIZE);
354 if (rc != TC_CRYPTO_SUCCESS) {
355 return -1;
356 }
357 }
358
359 rc = tc_hmac_update(&hmac, info, info_len);
360 if (rc != TC_CRYPTO_SUCCESS) {
361 return -1;
362 }
363
364 rc = tc_hmac_update(&hmac, &counter, 1);
365 if (rc != TC_CRYPTO_SUCCESS) {
366 return -1;
367 }
368
369 rc = tc_hmac_final(T, TC_SHA256_DIGEST_SIZE, &hmac);
370 if (rc != TC_CRYPTO_SUCCESS) {
371 return -1;
372 }
373
374 if (len > TC_SHA256_DIGEST_SIZE) {
375 memcpy(&okm[off], T, TC_SHA256_DIGEST_SIZE);
376 len -= TC_SHA256_DIGEST_SIZE;
377 } else {
378 memcpy(&okm[off], T, len);
379 len = 0;
380 }
381 }
382
383 return 0;
384}
385#endif
386
Fabio Utzigba829042018-09-18 08:29:34 -0300387int
Fabio Utzig4741c452019-12-19 15:32:41 -0300388boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
389 const struct boot_status *bs)
Fabio Utzigba829042018-09-18 08:29:34 -0300390{
391 int rc;
392
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200393#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300394 mbedtls_aes_init(&enc_state[slot].aes);
Fabio Utzig4741c452019-12-19 15:32:41 -0300395 rc = mbedtls_aes_setkey_enc(&enc_state[slot].aes, bs->enckey[slot],
396 BOOT_ENC_KEY_SIZE_BITS);
Fabio Utzigba829042018-09-18 08:29:34 -0300397 if (rc) {
398 mbedtls_aes_free(&enc_state[slot].aes);
399 return -1;
400 }
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200401#else
402 (void)rc;
403
404 /* set_encrypt and set_decrypt do the same thing in tinycrypt */
Fabio Utzig4741c452019-12-19 15:32:41 -0300405 tc_aes128_set_encrypt_key(&enc_state[slot].aes, bs->enckey[slot]);
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200406#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300407
408 enc_state[slot].valid = 1;
409
410 return 0;
411}
412
Fabio Utzig4741c452019-12-19 15:32:41 -0300413#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE
414
Fabio Utzigba829042018-09-18 08:29:34 -0300415#if defined(MCUBOOT_ENCRYPT_RSA)
416# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
Fabio Utzigba829042018-09-18 08:29:34 -0300417#elif defined(MCUBOOT_ENCRYPT_KW)
418# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
Fabio Utzig5fde8322019-10-23 12:23:08 -0300419#elif defined(MCUBOOT_ENCRYPT_EC256)
420# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
Fabio Utzig5fde8322019-10-23 12:23:08 -0300421# define EC_PUBK_INDEX (1)
422# define EC_TAG_INDEX (65)
423# define EC_CIPHERKEY_INDEX (65 + 32)
Fabio Utzig4741c452019-12-19 15:32:41 -0300424_Static_assert(EC_CIPHERKEY_INDEX + 16 == EXPECTED_ENC_LEN,
425 "Please fix ECIES-P256 component indexes");
Fabio Utzigba829042018-09-18 08:29:34 -0300426#endif
427
428/*
Fabio Utzig4741c452019-12-19 15:32:41 -0300429 * Decrypt an encryption key TLV.
430 *
431 * @param buf An encryption TLV read from flash (build time fixed length)
432 * @param enckey An AES-128 key sized buffer to store to plain key.
Fabio Utzigba829042018-09-18 08:29:34 -0300433 */
434int
Fabio Utzig4741c452019-12-19 15:32:41 -0300435boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey)
Fabio Utzigba829042018-09-18 08:29:34 -0300436{
437#if defined(MCUBOOT_ENCRYPT_RSA)
438 mbedtls_rsa_context rsa;
439 uint8_t *cp;
440 uint8_t *cpend;
Fabio Utzigba829042018-09-18 08:29:34 -0300441 size_t olen;
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200442#endif
Fabio Utzig5fde8322019-10-23 12:23:08 -0300443#if defined(MCUBOOT_ENCRYPT_EC256)
444 struct tc_hmac_state_struct hmac;
445 struct tc_aes_key_sched_struct aes;
446 uint8_t tag[TC_SHA256_DIGEST_SIZE];
447 uint8_t shared[NUM_ECC_BYTES];
448 uint8_t derived_key[TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE];
449 uint8_t *cp;
450 uint8_t *cpend;
451 uint8_t pk[NUM_ECC_BYTES];
452 uint8_t counter[TC_AES_BLOCK_SIZE];
Fabio Utzig61fd8882019-09-14 20:00:20 -0300453 uint16_t len;
Fabio Utzig4741c452019-12-19 15:32:41 -0300454#endif
455 int rc = -1;
Fabio Utzigba829042018-09-18 08:29:34 -0300456
Fabio Utzigba829042018-09-18 08:29:34 -0300457#if defined(MCUBOOT_ENCRYPT_RSA)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300458
Fabio Utzig233af7d2019-08-26 12:06:16 -0300459 mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
Fabio Utzigba829042018-09-18 08:29:34 -0300460
Fabio Utzig233af7d2019-08-26 12:06:16 -0300461 cp = (uint8_t *)bootutil_enc_key.key;
462 cpend = cp + *bootutil_enc_key.len;
Fabio Utzigba829042018-09-18 08:29:34 -0300463
Fabio Utzig5fde8322019-10-23 12:23:08 -0300464 rc = parse_rsa_enckey(&rsa, &cp, cpend);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300465 if (rc) {
Fabio Utzigba829042018-09-18 08:29:34 -0300466 mbedtls_rsa_free(&rsa);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300467 return rc;
468 }
469
470 rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
471 NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
472 mbedtls_rsa_free(&rsa);
Fabio Utzigba829042018-09-18 08:29:34 -0300473
474#elif defined(MCUBOOT_ENCRYPT_KW)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300475
Fabio Utzig233af7d2019-08-26 12:06:16 -0300476 assert(*bootutil_enc_key.len == 16);
477 rc = key_unwrap(buf, enckey);
Fabio Utzig5fde8322019-10-23 12:23:08 -0300478
479#elif defined(MCUBOOT_ENCRYPT_EC256)
480
481 cp = (uint8_t *)bootutil_enc_key.key;
482 cpend = cp + *bootutil_enc_key.len;
483
484 /*
485 * Load the stored EC256 decryption private key
486 */
487
488 rc = parse_ec256_enckey(&cp, cpend, pk);
489 if (rc) {
490 return rc;
491 }
492
493 /* is EC point uncompressed? */
494 if (buf[0] != 0x04) {
495 return -1;
496 }
497
498 /*
499 * First "element" in the TLV is the curve point (public key)
500 */
501 rc = uECC_valid_public_key(&buf[EC_PUBK_INDEX], uECC_secp256r1());
502 if (rc != 0) {
503 return -1;
504 }
505
506 rc = uECC_shared_secret(&buf[EC_PUBK_INDEX], pk, shared, uECC_secp256r1());
507 if (rc != TC_CRYPTO_SUCCESS) {
508 return -1;
509 }
510
511 /*
512 * Expand shared secret to create keys for AES-128-CTR + HMAC-SHA256
513 */
514
515 len = TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE;
Fabio Utzig23e99b02019-11-07 11:55:20 -0300516 rc = hkdf(shared, NUM_ECC_BYTES, (uint8_t *)"MCUBoot_ECIES_v1", 16,
Fabio Utzig5fde8322019-10-23 12:23:08 -0300517 derived_key, &len);
518 if (rc != 0 || len != (TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE)) {
519 return -1;
520 }
521
522 /*
523 * HMAC the key and check that our received MAC matches the generated tag
524 */
525
526 rc = tc_hmac_set_key(&hmac, &derived_key[16], 32);
527 if (rc != TC_CRYPTO_SUCCESS) {
528 return -1;
529 }
530
531 rc = tc_hmac_init(&hmac);
532 if (rc != TC_CRYPTO_SUCCESS) {
533 return -1;
534 }
535
536 rc = tc_hmac_update(&hmac, &buf[EC_CIPHERKEY_INDEX], 16);
537 if (rc != TC_CRYPTO_SUCCESS) {
538 return -1;
539 }
540
541 /* Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes */
542 rc = tc_hmac_final(tag, TC_SHA256_DIGEST_SIZE, &hmac);
543 if (rc != TC_CRYPTO_SUCCESS) {
544 return -1;
545 }
546
547 if (_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
548 return -1;
549 }
550
551 /*
552 * Finally decrypt the received ciphered key
553 */
554
555 rc = tc_aes128_set_decrypt_key(&aes, derived_key);
556 if (rc != TC_CRYPTO_SUCCESS) {
557 return -1;
558 }
559
560 memset(counter, 0, TC_AES_BLOCK_SIZE);
561 rc = tc_ctr_mode(enckey, TC_AES_KEY_SIZE, &buf[EC_CIPHERKEY_INDEX],
562 TC_AES_KEY_SIZE, counter, &aes);
563 if (rc != TC_CRYPTO_SUCCESS) {
564 return -1;
565 }
566
567 rc = 0;
568
Fabio Utzigba829042018-09-18 08:29:34 -0300569#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300570
Fabio Utzigba829042018-09-18 08:29:34 -0300571 return rc;
572}
573
Fabio Utzig4741c452019-12-19 15:32:41 -0300574/*
575 * Load encryption key.
576 */
577int
578boot_enc_load(struct enc_key_data *enc_state, int image_index,
579 const struct image_header *hdr, const struct flash_area *fap,
580 struct boot_status *bs)
581{
582 uint32_t off;
583 uint16_t len;
584 struct image_tlv_iter it;
585#if MCUBOOT_SWAP_SAVE_ENCTLV
586 uint8_t *buf;
587#else
588 uint8_t buf[EXPECTED_ENC_LEN];
589#endif
590 uint8_t slot;
591 int rc;
592
593 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
594 if (rc < 0) {
595 return rc;
596 }
597 slot = rc;
598
599 /* Already loaded... */
600 if (enc_state[slot].valid) {
601 return 1;
602 }
603
604 rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_ENC_TLV, false);
605 if (rc) {
606 return -1;
607 }
608
609 rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
610 if (rc != 0) {
611 return rc;
612 }
613
614 if (len != EXPECTED_ENC_LEN) {
615 return -1;
616 }
617
618#if MCUBOOT_SWAP_SAVE_ENCTLV
619 buf = bs->enctlv[slot];
620 memset(buf, 0xff, BOOT_ENC_TLV_ALIGN_SIZE);
621#endif
622
623 rc = flash_area_read(fap, off, buf, EXPECTED_ENC_LEN);
624 if (rc) {
625 return -1;
626 }
627
628 return boot_enc_decrypt(buf, bs->enckey[slot]);
629}
630
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100631bool
Fabio Utzig10ee6482019-08-01 12:04:52 -0300632boot_enc_valid(struct enc_key_data *enc_state, int image_index,
633 const struct flash_area *fap)
Fabio Utzigba829042018-09-18 08:29:34 -0300634{
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100635 int rc;
636
Fabio Utzigb0f04732019-07-31 09:49:19 -0300637 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100638 if (rc < 0) {
639 /* can't get proper slot number - skip encryption, */
Fabio Utzigb0f04732019-07-31 09:49:19 -0300640 /* postpone the error for a upper layer */
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100641 return false;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100642 }
643
644 return enc_state[rc].valid;
Fabio Utzigba829042018-09-18 08:29:34 -0300645}
646
647void
Fabio Utzig10ee6482019-08-01 12:04:52 -0300648boot_encrypt(struct enc_key_data *enc_state, int image_index,
649 const struct flash_area *fap, uint32_t off, uint32_t sz,
650 uint32_t blk_off, uint8_t *buf)
Fabio Utzigba829042018-09-18 08:29:34 -0300651{
652 struct enc_key_data *enc;
653 uint32_t i, j;
654 uint8_t u8;
655 uint8_t nonce[16];
656 uint8_t blk[16];
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100657 int rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300658
659 memset(nonce, 0, 12);
660 off >>= 4;
661 nonce[12] = (uint8_t)(off >> 24);
662 nonce[13] = (uint8_t)(off >> 16);
663 nonce[14] = (uint8_t)(off >> 8);
664 nonce[15] = (uint8_t)off;
665
Fabio Utzigb0f04732019-07-31 09:49:19 -0300666 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100667 if (rc < 0) {
668 assert(0);
669 return;
670 }
671
672 enc = &enc_state[rc];
Fabio Utzigba829042018-09-18 08:29:34 -0300673 assert(enc->valid == 1);
674 for (i = 0; i < sz; i++) {
675 if (i == 0 || blk_off == 0) {
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200676#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300677 mbedtls_aes_crypt_ecb(&enc->aes, MBEDTLS_AES_ENCRYPT, nonce, blk);
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200678#else
679 tc_aes_encrypt(blk, nonce, &enc->aes);
680#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300681
682 for (j = 16; j > 0; --j) {
683 if (++nonce[j - 1] != 0) {
684 break;
685 }
686 }
687 }
688
689 u8 = *buf;
690 *buf++ = u8 ^ blk[blk_off];
691 blk_off = (blk_off + 1) & 0x0f;
692 }
693}
694
Fabio Utzig10ee6482019-08-01 12:04:52 -0300695/**
696 * Clears encrypted state after use.
697 */
Fabio Utzigb63d9952019-08-19 14:20:52 -0300698void
699boot_enc_zeroize(struct enc_key_data *enc_state)
Fabio Utzigba829042018-09-18 08:29:34 -0300700{
Fabio Utzig10ee6482019-08-01 12:04:52 -0300701 memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
Fabio Utzigba829042018-09-18 08:29:34 -0300702}
703
704#endif /* MCUBOOT_ENC_IMAGES */