blob: 1e04741f49fa6ca4f3cb745434d53b97a76c075c [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 Utzigba829042018-09-18 08:29:34 -030063#define TLV_ENC_RSA_SZ 256
64#define TLV_ENC_KW_SZ 24
65
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020066#if defined(MCUBOOT_ENCRYPT_KW)
67#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030068static int
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020069key_unwrap(uint8_t *wrapped, uint8_t *enckey)
70{
71 mbedtls_nist_kw_context kw;
72 int rc;
73 size_t olen;
74
75 mbedtls_nist_kw_init(&kw);
76
77 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES,
78 bootutil_enc_key.key, *bootutil_enc_key.len * 8, 0);
79 if (rc) {
80 goto done;
81 }
82
83 rc = mbedtls_nist_kw_unwrap(&kw, MBEDTLS_KW_MODE_KW, wrapped, TLV_ENC_KW_SZ,
84 enckey, &olen, BOOT_ENC_KEY_SIZE);
85
86done:
87 mbedtls_nist_kw_free(&kw);
88 return rc;
89}
90#else /* !MCUBOOT_USE_MBED_TLS */
91/*
92 * Implements AES key unwrapping following RFC-3394 section 2.2.2, using
93 * tinycrypt for AES-128 decryption.
94 */
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030095static int
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020096key_unwrap(uint8_t *wrapped, uint8_t *enckey)
97{
98 struct tc_aes_key_sched_struct aes;
99 uint8_t A[8];
100 uint8_t B[16];
101 int8_t i, j, k;
102
103 if (tc_aes128_set_decrypt_key(&aes, bootutil_enc_key.key) == 0) {
104 return -1;
105 }
106
107 for (k = 0; k < 8; k++) {
108 A[k] = wrapped[k];
109 enckey[k] = wrapped[8 + k];
110 enckey[8 + k] = wrapped[16 + k];
111 }
112
113 for (j = 5; j >= 0; j--) {
114 for (i = 2; i > 0; i--) {
115 for (k = 0; k < 8; k++) {
116 B[k] = A[k];
117 B[8 + k] = enckey[((i-1) * 8) + k];
118 }
119 B[7] ^= 2 * j + i;
120 if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, &aes) == 0) {
121 return -1;
122 }
123 for (k = 0; k < 8; k++) {
124 A[k] = B[k];
125 enckey[((i-1) * 8) + k] = B[8 + k];
126 }
127 }
128 }
129
130 for (i = 0, k = 0; i < 8; i++) {
131 k |= A[i] ^ 0xa6;
132 }
133 if (k) {
134 return -1;
135 }
136 return 0;
137}
138#endif /* MCUBOOT_USE_MBED_TLS */
139#endif /* MCUBOOT_ENCRYPT_KW */
140
Fabio Utzigba829042018-09-18 08:29:34 -0300141#if defined(MCUBOOT_ENCRYPT_RSA)
142static int
Fabio Utzig5fde8322019-10-23 12:23:08 -0300143parse_rsa_enckey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
Fabio Utzigba829042018-09-18 08:29:34 -0300144{
Fabio Utzigba829042018-09-18 08:29:34 -0300145 size_t len;
146
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300147 if (mbedtls_asn1_get_tag(p, end, &len,
148 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
Fabio Utzigba829042018-09-18 08:29:34 -0300149 return -1;
150 }
151
152 if (*p + len != end) {
153 return -2;
154 }
155
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300156 /* Non-optional fields. */
Fabio Utzigba829042018-09-18 08:29:34 -0300157 if ( /* version */
158 mbedtls_asn1_get_int(p, end, &ctx->ver) != 0 ||
159 /* public modulus */
160 mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0 ||
161 /* public exponent */
162 mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0 ||
163 /* private exponent */
164 mbedtls_asn1_get_mpi(p, end, &ctx->D) != 0 ||
165 /* primes */
166 mbedtls_asn1_get_mpi(p, end, &ctx->P) != 0 ||
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300167 mbedtls_asn1_get_mpi(p, end, &ctx->Q) != 0) {
168
Fabio Utzigba829042018-09-18 08:29:34 -0300169 return -3;
170 }
171
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300172#if !defined(MBEDTLS_RSA_NO_CRT)
173 /*
174 * DP/DQ/QP are only used inside mbedTLS if it was built with the
175 * Chinese Remainder Theorem enabled (default). In case it is disabled
176 * we parse, or if not available, we calculate those values.
177 */
178 if (*p < end) {
179 if ( /* d mod (p-1) and d mod (q-1) */
180 mbedtls_asn1_get_mpi(p, end, &ctx->DP) != 0 ||
181 mbedtls_asn1_get_mpi(p, end, &ctx->DQ) != 0 ||
182 /* q ^ (-1) mod p */
183 mbedtls_asn1_get_mpi(p, end, &ctx->QP) != 0) {
184
185 return -4;
186 }
187 } else {
188 if (mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
189 &ctx->DP, &ctx->DQ, &ctx->QP) != 0) {
190 return -5;
191 }
192 }
193#endif
194
Fabio Utzigba829042018-09-18 08:29:34 -0300195 ctx->len = mbedtls_mpi_size(&ctx->N);
196
Fabio Utzig6f4d8f82019-12-12 18:46:06 -0300197 if (mbedtls_rsa_check_privkey(ctx) != 0) {
198 return -6;
Fabio Utzigba829042018-09-18 08:29:34 -0300199 }
200
201 return 0;
202}
203#endif
204
Fabio Utzig5fde8322019-10-23 12:23:08 -0300205#if defined(MCUBOOT_ENCRYPT_EC256)
206static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
207static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
208
209/*
210 * Parses the output of `imgtool keygen`, which produces a PKCS#8 elliptic
211 * curve keypair. See RFC5208 and RFC5915.
212 */
213static int
214parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *pk)
215{
216 int rc;
217 size_t len;
218 int version;
219 mbedtls_asn1_buf alg;
220 mbedtls_asn1_buf param;
221
222 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
223 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
224 return -1;
225 }
226
227 if (*p + len != end) {
228 return -2;
229 }
230
231 version = 0;
232 if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
233 return -3;
234 }
235
236 if ((rc = mbedtls_asn1_get_alg(p, end, &alg, &param)) != 0) {
237 return -5;
238 }
239
240 if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
241 memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
242 return -6;
243 }
244 if (param.len != sizeof(ec_secp256r1_oid) - 1 ||
245 memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
246 return -7;
247 }
248
249 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
250 return -8;
251 }
252
253 /* RFC5915 - ECPrivateKey */
254
255 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
256 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
257 return -9;
258 }
259
260 version = 0;
261 if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
262 return -10;
263 }
264
265 /* privateKey */
266
267 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
268 return -11;
269 }
270
271 if (len != NUM_ECC_BYTES) {
272 return -12;
273 }
274
275 memcpy(pk, *p, len);
276
277 /* publicKey usually follows but is not parsed here */
278
279 return 0;
280}
281
282/*
283 * HKDF as described by RFC5869.
284 *
285 * @param ikm The input data to be derived.
286 * @param ikm_len Length of the input data.
287 * @param info An information tag.
288 * @param info_len Length of the information tag.
289 * @param okm Output of the KDF computation.
290 * @param okm_len On input the requested length; on output the generated length
291 */
292static int
293hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
294 uint8_t *okm, uint16_t *okm_len)
295{
296 struct tc_hmac_state_struct hmac;
297 uint8_t salt[TC_SHA256_DIGEST_SIZE];
298 uint8_t prk[TC_SHA256_DIGEST_SIZE];
299 uint8_t T[TC_SHA256_DIGEST_SIZE];
300 uint16_t off;
301 uint16_t len;
302 uint8_t counter;
303 bool first;
304 int rc;
305
306 /*
307 * Extract
308 */
309
310 if (ikm == NULL || okm == NULL || ikm_len == 0) {
311 return -1;
312 }
313
314 memset(salt, 0, TC_SHA256_DIGEST_SIZE);
315 rc = tc_hmac_set_key(&hmac, salt, TC_SHA256_DIGEST_SIZE);
316 if (rc != TC_CRYPTO_SUCCESS) {
317 return -1;
318 }
319
320 rc = tc_hmac_init(&hmac);
321 if (rc != TC_CRYPTO_SUCCESS) {
322 return -1;
323 }
324
325 rc = tc_hmac_update(&hmac, ikm, ikm_len);
326 if (rc != TC_CRYPTO_SUCCESS) {
327 return -1;
328 }
329
330 rc = tc_hmac_final(prk, TC_SHA256_DIGEST_SIZE, &hmac);
331 if (rc != TC_CRYPTO_SUCCESS) {
332 return -1;
333 }
334
335 /*
336 * Expand
337 */
338
339 len = *okm_len;
340 counter = 1;
341 first = true;
342 for (off = 0; len > 0; off += TC_SHA256_DIGEST_SIZE, ++counter) {
343 rc = tc_hmac_set_key(&hmac, prk, TC_SHA256_DIGEST_SIZE);
344 if (rc != TC_CRYPTO_SUCCESS) {
345 return -1;
346 }
347
348 rc = tc_hmac_init(&hmac);
349 if (rc != TC_CRYPTO_SUCCESS) {
350 return -1;
351 }
352
353 if (first) {
354 first = false;
355 } else {
356 rc = tc_hmac_update(&hmac, T, TC_SHA256_DIGEST_SIZE);
357 if (rc != TC_CRYPTO_SUCCESS) {
358 return -1;
359 }
360 }
361
362 rc = tc_hmac_update(&hmac, info, info_len);
363 if (rc != TC_CRYPTO_SUCCESS) {
364 return -1;
365 }
366
367 rc = tc_hmac_update(&hmac, &counter, 1);
368 if (rc != TC_CRYPTO_SUCCESS) {
369 return -1;
370 }
371
372 rc = tc_hmac_final(T, TC_SHA256_DIGEST_SIZE, &hmac);
373 if (rc != TC_CRYPTO_SUCCESS) {
374 return -1;
375 }
376
377 if (len > TC_SHA256_DIGEST_SIZE) {
378 memcpy(&okm[off], T, TC_SHA256_DIGEST_SIZE);
379 len -= TC_SHA256_DIGEST_SIZE;
380 } else {
381 memcpy(&okm[off], T, len);
382 len = 0;
383 }
384 }
385
386 return 0;
387}
388#endif
389
Fabio Utzigba829042018-09-18 08:29:34 -0300390int
Fabio Utzig10ee6482019-08-01 12:04:52 -0300391boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, uint8_t *enckey)
Fabio Utzigba829042018-09-18 08:29:34 -0300392{
393 int rc;
394
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200395#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300396 mbedtls_aes_init(&enc_state[slot].aes);
397 rc = mbedtls_aes_setkey_enc(&enc_state[slot].aes, enckey, BOOT_ENC_KEY_SIZE_BITS);
398 if (rc) {
399 mbedtls_aes_free(&enc_state[slot].aes);
400 return -1;
401 }
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200402#else
403 (void)rc;
404
405 /* set_encrypt and set_decrypt do the same thing in tinycrypt */
406 tc_aes128_set_encrypt_key(&enc_state[slot].aes, enckey);
407#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300408
409 enc_state[slot].valid = 1;
410
411 return 0;
412}
413
414#if defined(MCUBOOT_ENCRYPT_RSA)
415# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
416# define EXPECTED_ENC_LEN TLV_ENC_RSA_SZ
417#elif defined(MCUBOOT_ENCRYPT_KW)
418# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
419# define EXPECTED_ENC_LEN TLV_ENC_KW_SZ
Fabio Utzig5fde8322019-10-23 12:23:08 -0300420#elif defined(MCUBOOT_ENCRYPT_EC256)
421# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
422# define EXPECTED_ENC_LEN (65 + 32 + 16)
423# define EC_PUBK_INDEX (1)
424# define EC_TAG_INDEX (65)
425# define EC_CIPHERKEY_INDEX (65 + 32)
Fabio Utzigba829042018-09-18 08:29:34 -0300426#endif
427
428/*
429 * Load encryption key.
430 */
431int
Fabio Utzig10ee6482019-08-01 12:04:52 -0300432boot_enc_load(struct enc_key_data *enc_state, int image_index,
433 const struct image_header *hdr, const struct flash_area *fap,
434 uint8_t *enckey)
Fabio Utzigba829042018-09-18 08:29:34 -0300435{
436#if defined(MCUBOOT_ENCRYPT_RSA)
437 mbedtls_rsa_context rsa;
438 uint8_t *cp;
439 uint8_t *cpend;
Fabio Utzigba829042018-09-18 08:29:34 -0300440 size_t olen;
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200441#endif
Fabio Utzig5fde8322019-10-23 12:23:08 -0300442#if defined(MCUBOOT_ENCRYPT_EC256)
443 struct tc_hmac_state_struct hmac;
444 struct tc_aes_key_sched_struct aes;
445 uint8_t tag[TC_SHA256_DIGEST_SIZE];
446 uint8_t shared[NUM_ECC_BYTES];
447 uint8_t derived_key[TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE];
448 uint8_t *cp;
449 uint8_t *cpend;
450 uint8_t pk[NUM_ECC_BYTES];
451 uint8_t counter[TC_AES_BLOCK_SIZE];
452#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300453 uint32_t off;
Fabio Utzig61fd8882019-09-14 20:00:20 -0300454 uint16_t len;
455 struct image_tlv_iter it;
Fabio Utzig5fde8322019-10-23 12:23:08 -0300456 uint8_t buf[EXPECTED_ENC_LEN];
Fabio Utzigba829042018-09-18 08:29:34 -0300457 uint8_t slot;
Fabio Utzigba829042018-09-18 08:29:34 -0300458 int rc;
459
Fabio Utzigb0f04732019-07-31 09:49:19 -0300460 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100461 if (rc < 0) {
462 return rc;
463 }
464 slot = rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300465
466 /* Already loaded... */
467 if (enc_state[slot].valid) {
468 return 1;
469 }
470
Fabio Utzig61fd8882019-09-14 20:00:20 -0300471 rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_ENC_TLV, false);
Fabio Utzigba829042018-09-18 08:29:34 -0300472 if (rc) {
Fabio Utzigba829042018-09-18 08:29:34 -0300473 return -1;
474 }
Fabio Utzigba829042018-09-18 08:29:34 -0300475
Fabio Utzig61fd8882019-09-14 20:00:20 -0300476 rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
477 if (rc != 0) {
478 return rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300479 }
480
Fabio Utzig61fd8882019-09-14 20:00:20 -0300481 if (len != EXPECTED_ENC_LEN) {
Fabio Utzigba829042018-09-18 08:29:34 -0300482 return -1;
Fabio Utzig61fd8882019-09-14 20:00:20 -0300483 }
484
485 rc = flash_area_read(fap, off, buf, EXPECTED_ENC_LEN);
486 if (rc) {
487 return -1;
Fabio Utzigba829042018-09-18 08:29:34 -0300488 }
489
Fabio Utzigba829042018-09-18 08:29:34 -0300490#if defined(MCUBOOT_ENCRYPT_RSA)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300491
Fabio Utzig233af7d2019-08-26 12:06:16 -0300492 mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
Fabio Utzigba829042018-09-18 08:29:34 -0300493
Fabio Utzig233af7d2019-08-26 12:06:16 -0300494 cp = (uint8_t *)bootutil_enc_key.key;
495 cpend = cp + *bootutil_enc_key.len;
Fabio Utzigba829042018-09-18 08:29:34 -0300496
Fabio Utzig5fde8322019-10-23 12:23:08 -0300497 rc = parse_rsa_enckey(&rsa, &cp, cpend);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300498 if (rc) {
Fabio Utzigba829042018-09-18 08:29:34 -0300499 mbedtls_rsa_free(&rsa);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300500 return rc;
501 }
502
503 rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
504 NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
505 mbedtls_rsa_free(&rsa);
Fabio Utzigba829042018-09-18 08:29:34 -0300506
507#elif defined(MCUBOOT_ENCRYPT_KW)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300508
Fabio Utzig233af7d2019-08-26 12:06:16 -0300509 assert(*bootutil_enc_key.len == 16);
510 rc = key_unwrap(buf, enckey);
Fabio Utzig5fde8322019-10-23 12:23:08 -0300511
512#elif defined(MCUBOOT_ENCRYPT_EC256)
513
514 cp = (uint8_t *)bootutil_enc_key.key;
515 cpend = cp + *bootutil_enc_key.len;
516
517 /*
518 * Load the stored EC256 decryption private key
519 */
520
521 rc = parse_ec256_enckey(&cp, cpend, pk);
522 if (rc) {
523 return rc;
524 }
525
526 /* is EC point uncompressed? */
527 if (buf[0] != 0x04) {
528 return -1;
529 }
530
531 /*
532 * First "element" in the TLV is the curve point (public key)
533 */
534 rc = uECC_valid_public_key(&buf[EC_PUBK_INDEX], uECC_secp256r1());
535 if (rc != 0) {
536 return -1;
537 }
538
539 rc = uECC_shared_secret(&buf[EC_PUBK_INDEX], pk, shared, uECC_secp256r1());
540 if (rc != TC_CRYPTO_SUCCESS) {
541 return -1;
542 }
543
544 /*
545 * Expand shared secret to create keys for AES-128-CTR + HMAC-SHA256
546 */
547
548 len = TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE;
Fabio Utzig23e99b02019-11-07 11:55:20 -0300549 rc = hkdf(shared, NUM_ECC_BYTES, (uint8_t *)"MCUBoot_ECIES_v1", 16,
Fabio Utzig5fde8322019-10-23 12:23:08 -0300550 derived_key, &len);
551 if (rc != 0 || len != (TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE)) {
552 return -1;
553 }
554
555 /*
556 * HMAC the key and check that our received MAC matches the generated tag
557 */
558
559 rc = tc_hmac_set_key(&hmac, &derived_key[16], 32);
560 if (rc != TC_CRYPTO_SUCCESS) {
561 return -1;
562 }
563
564 rc = tc_hmac_init(&hmac);
565 if (rc != TC_CRYPTO_SUCCESS) {
566 return -1;
567 }
568
569 rc = tc_hmac_update(&hmac, &buf[EC_CIPHERKEY_INDEX], 16);
570 if (rc != TC_CRYPTO_SUCCESS) {
571 return -1;
572 }
573
574 /* Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes */
575 rc = tc_hmac_final(tag, TC_SHA256_DIGEST_SIZE, &hmac);
576 if (rc != TC_CRYPTO_SUCCESS) {
577 return -1;
578 }
579
580 if (_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
581 return -1;
582 }
583
584 /*
585 * Finally decrypt the received ciphered key
586 */
587
588 rc = tc_aes128_set_decrypt_key(&aes, derived_key);
589 if (rc != TC_CRYPTO_SUCCESS) {
590 return -1;
591 }
592
593 memset(counter, 0, TC_AES_BLOCK_SIZE);
594 rc = tc_ctr_mode(enckey, TC_AES_KEY_SIZE, &buf[EC_CIPHERKEY_INDEX],
595 TC_AES_KEY_SIZE, counter, &aes);
596 if (rc != TC_CRYPTO_SUCCESS) {
597 return -1;
598 }
599
600 rc = 0;
601
Fabio Utzigba829042018-09-18 08:29:34 -0300602#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300603
Fabio Utzigba829042018-09-18 08:29:34 -0300604 return rc;
605}
606
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100607bool
Fabio Utzig10ee6482019-08-01 12:04:52 -0300608boot_enc_valid(struct enc_key_data *enc_state, int image_index,
609 const struct flash_area *fap)
Fabio Utzigba829042018-09-18 08:29:34 -0300610{
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100611 int rc;
612
Fabio Utzigb0f04732019-07-31 09:49:19 -0300613 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100614 if (rc < 0) {
615 /* can't get proper slot number - skip encryption, */
Fabio Utzigb0f04732019-07-31 09:49:19 -0300616 /* postpone the error for a upper layer */
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100617 return false;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100618 }
619
620 return enc_state[rc].valid;
Fabio Utzigba829042018-09-18 08:29:34 -0300621}
622
623void
Fabio Utzig10ee6482019-08-01 12:04:52 -0300624boot_encrypt(struct enc_key_data *enc_state, int image_index,
625 const struct flash_area *fap, uint32_t off, uint32_t sz,
626 uint32_t blk_off, uint8_t *buf)
Fabio Utzigba829042018-09-18 08:29:34 -0300627{
628 struct enc_key_data *enc;
629 uint32_t i, j;
630 uint8_t u8;
631 uint8_t nonce[16];
632 uint8_t blk[16];
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100633 int rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300634
635 memset(nonce, 0, 12);
636 off >>= 4;
637 nonce[12] = (uint8_t)(off >> 24);
638 nonce[13] = (uint8_t)(off >> 16);
639 nonce[14] = (uint8_t)(off >> 8);
640 nonce[15] = (uint8_t)off;
641
Fabio Utzigb0f04732019-07-31 09:49:19 -0300642 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100643 if (rc < 0) {
644 assert(0);
645 return;
646 }
647
648 enc = &enc_state[rc];
Fabio Utzigba829042018-09-18 08:29:34 -0300649 assert(enc->valid == 1);
650 for (i = 0; i < sz; i++) {
651 if (i == 0 || blk_off == 0) {
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200652#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300653 mbedtls_aes_crypt_ecb(&enc->aes, MBEDTLS_AES_ENCRYPT, nonce, blk);
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200654#else
655 tc_aes_encrypt(blk, nonce, &enc->aes);
656#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300657
658 for (j = 16; j > 0; --j) {
659 if (++nonce[j - 1] != 0) {
660 break;
661 }
662 }
663 }
664
665 u8 = *buf;
666 *buf++ = u8 ^ blk[blk_off];
667 blk_off = (blk_off + 1) & 0x0f;
668 }
669}
670
Fabio Utzig10ee6482019-08-01 12:04:52 -0300671/**
672 * Clears encrypted state after use.
673 */
Fabio Utzigb63d9952019-08-19 14:20:52 -0300674void
675boot_enc_zeroize(struct enc_key_data *enc_state)
Fabio Utzigba829042018-09-18 08:29:34 -0300676{
Fabio Utzig10ee6482019-08-01 12:04:52 -0300677 memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
Fabio Utzigba829042018-09-18 08:29:34 -0300678}
679
680#endif /* MCUBOOT_ENC_IMAGES */