blob: 012256e055b7b4cb60a0e232676011e6542ad654 [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"
33#include "mbedtls/asn1.h"
34#endif
35
36#if defined(MCUBOOT_ENCRYPT_KW)
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020037# if defined(MCUBOOT_USE_MBED_TLS)
38# include "mbedtls/nist_kw.h"
39# include "mbedtls/aes.h"
40# else
41# include "tinycrypt/aes.h"
42# endif
Fabio Utzigba829042018-09-18 08:29:34 -030043#endif
44
Fabio Utzig5fde8322019-10-23 12:23:08 -030045#if defined(MCUBOOT_ENCRYPT_EC256)
46#include "tinycrypt/utils.h"
47#include "tinycrypt/constants.h"
48#include "tinycrypt/ecc.h"
49#include "tinycrypt/ecc_dh.h"
50#include "tinycrypt/ctr_mode.h"
51#include "tinycrypt/hmac.h"
52#include "mbedtls/oid.h"
53#include "mbedtls/asn1.h"
54#endif
55
Fabio Utzigba829042018-09-18 08:29:34 -030056#include "bootutil/image.h"
57#include "bootutil/enc_key.h"
58#include "bootutil/sign_key.h"
59
60#include "bootutil_priv.h"
61
Fabio Utzigba829042018-09-18 08:29:34 -030062#define TLV_ENC_RSA_SZ 256
63#define TLV_ENC_KW_SZ 24
64
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020065#if defined(MCUBOOT_ENCRYPT_KW)
66#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030067static int
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020068key_unwrap(uint8_t *wrapped, uint8_t *enckey)
69{
70 mbedtls_nist_kw_context kw;
71 int rc;
72 size_t olen;
73
74 mbedtls_nist_kw_init(&kw);
75
76 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES,
77 bootutil_enc_key.key, *bootutil_enc_key.len * 8, 0);
78 if (rc) {
79 goto done;
80 }
81
82 rc = mbedtls_nist_kw_unwrap(&kw, MBEDTLS_KW_MODE_KW, wrapped, TLV_ENC_KW_SZ,
83 enckey, &olen, BOOT_ENC_KEY_SIZE);
84
85done:
86 mbedtls_nist_kw_free(&kw);
87 return rc;
88}
89#else /* !MCUBOOT_USE_MBED_TLS */
90/*
91 * Implements AES key unwrapping following RFC-3394 section 2.2.2, using
92 * tinycrypt for AES-128 decryption.
93 */
Fabio Utzig6ace9ee2019-08-19 11:11:07 -030094static int
Fabio Utzig38f5ffe2018-12-27 16:12:58 -020095key_unwrap(uint8_t *wrapped, uint8_t *enckey)
96{
97 struct tc_aes_key_sched_struct aes;
98 uint8_t A[8];
99 uint8_t B[16];
100 int8_t i, j, k;
101
102 if (tc_aes128_set_decrypt_key(&aes, bootutil_enc_key.key) == 0) {
103 return -1;
104 }
105
106 for (k = 0; k < 8; k++) {
107 A[k] = wrapped[k];
108 enckey[k] = wrapped[8 + k];
109 enckey[8 + k] = wrapped[16 + k];
110 }
111
112 for (j = 5; j >= 0; j--) {
113 for (i = 2; i > 0; i--) {
114 for (k = 0; k < 8; k++) {
115 B[k] = A[k];
116 B[8 + k] = enckey[((i-1) * 8) + k];
117 }
118 B[7] ^= 2 * j + i;
119 if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, &aes) == 0) {
120 return -1;
121 }
122 for (k = 0; k < 8; k++) {
123 A[k] = B[k];
124 enckey[((i-1) * 8) + k] = B[8 + k];
125 }
126 }
127 }
128
129 for (i = 0, k = 0; i < 8; i++) {
130 k |= A[i] ^ 0xa6;
131 }
132 if (k) {
133 return -1;
134 }
135 return 0;
136}
137#endif /* MCUBOOT_USE_MBED_TLS */
138#endif /* MCUBOOT_ENCRYPT_KW */
139
Fabio Utzigba829042018-09-18 08:29:34 -0300140#if defined(MCUBOOT_ENCRYPT_RSA)
141static int
Fabio Utzig5fde8322019-10-23 12:23:08 -0300142parse_rsa_enckey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
Fabio Utzigba829042018-09-18 08:29:34 -0300143{
144 int rc;
145 size_t len;
146
147 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
148 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
149 return -1;
150 }
151
152 if (*p + len != end) {
153 return -2;
154 }
155
156 if ( /* version */
157 mbedtls_asn1_get_int(p, end, &ctx->ver) != 0 ||
158 /* public modulus */
159 mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0 ||
160 /* public exponent */
161 mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0 ||
162 /* private exponent */
163 mbedtls_asn1_get_mpi(p, end, &ctx->D) != 0 ||
164 /* primes */
165 mbedtls_asn1_get_mpi(p, end, &ctx->P) != 0 ||
166 mbedtls_asn1_get_mpi(p, end, &ctx->Q) != 0 ||
167 /* d mod (p-1) and d mod (q-1) */
168 mbedtls_asn1_get_mpi(p, end, &ctx->DP) != 0 ||
169 mbedtls_asn1_get_mpi(p, end, &ctx->DQ) != 0 ||
170 /* q ^ (-1) mod p */
171 mbedtls_asn1_get_mpi(p, end, &ctx->QP) != 0) {
172 return -3;
173 }
174
175 ctx->len = mbedtls_mpi_size(&ctx->N);
176
177 if (*p != end) {
178 return -4;
179 }
180
181 if (mbedtls_rsa_check_pubkey(ctx) != 0 ||
182 mbedtls_rsa_check_privkey(ctx) != 0) {
183 return -5;
184 }
185
186 return 0;
187}
188#endif
189
Fabio Utzig5fde8322019-10-23 12:23:08 -0300190#if defined(MCUBOOT_ENCRYPT_EC256)
191static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
192static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
193
194/*
195 * Parses the output of `imgtool keygen`, which produces a PKCS#8 elliptic
196 * curve keypair. See RFC5208 and RFC5915.
197 */
198static int
199parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *pk)
200{
201 int rc;
202 size_t len;
203 int version;
204 mbedtls_asn1_buf alg;
205 mbedtls_asn1_buf param;
206
207 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
208 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
209 return -1;
210 }
211
212 if (*p + len != end) {
213 return -2;
214 }
215
216 version = 0;
217 if (mbedtls_asn1_get_int(p, end, &version) || version != 0) {
218 return -3;
219 }
220
221 if ((rc = mbedtls_asn1_get_alg(p, end, &alg, &param)) != 0) {
222 return -5;
223 }
224
225 if (alg.len != sizeof(ec_pubkey_oid) - 1 ||
226 memcmp(alg.p, ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
227 return -6;
228 }
229 if (param.len != sizeof(ec_secp256r1_oid) - 1 ||
230 memcmp(param.p, ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
231 return -7;
232 }
233
234 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
235 return -8;
236 }
237
238 /* RFC5915 - ECPrivateKey */
239
240 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
241 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
242 return -9;
243 }
244
245 version = 0;
246 if (mbedtls_asn1_get_int(p, end, &version) || version != 1) {
247 return -10;
248 }
249
250 /* privateKey */
251
252 if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
253 return -11;
254 }
255
256 if (len != NUM_ECC_BYTES) {
257 return -12;
258 }
259
260 memcpy(pk, *p, len);
261
262 /* publicKey usually follows but is not parsed here */
263
264 return 0;
265}
266
267/*
268 * HKDF as described by RFC5869.
269 *
270 * @param ikm The input data to be derived.
271 * @param ikm_len Length of the input data.
272 * @param info An information tag.
273 * @param info_len Length of the information tag.
274 * @param okm Output of the KDF computation.
275 * @param okm_len On input the requested length; on output the generated length
276 */
277static int
278hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
279 uint8_t *okm, uint16_t *okm_len)
280{
281 struct tc_hmac_state_struct hmac;
282 uint8_t salt[TC_SHA256_DIGEST_SIZE];
283 uint8_t prk[TC_SHA256_DIGEST_SIZE];
284 uint8_t T[TC_SHA256_DIGEST_SIZE];
285 uint16_t off;
286 uint16_t len;
287 uint8_t counter;
288 bool first;
289 int rc;
290
291 /*
292 * Extract
293 */
294
295 if (ikm == NULL || okm == NULL || ikm_len == 0) {
296 return -1;
297 }
298
299 memset(salt, 0, TC_SHA256_DIGEST_SIZE);
300 rc = tc_hmac_set_key(&hmac, salt, TC_SHA256_DIGEST_SIZE);
301 if (rc != TC_CRYPTO_SUCCESS) {
302 return -1;
303 }
304
305 rc = tc_hmac_init(&hmac);
306 if (rc != TC_CRYPTO_SUCCESS) {
307 return -1;
308 }
309
310 rc = tc_hmac_update(&hmac, ikm, ikm_len);
311 if (rc != TC_CRYPTO_SUCCESS) {
312 return -1;
313 }
314
315 rc = tc_hmac_final(prk, TC_SHA256_DIGEST_SIZE, &hmac);
316 if (rc != TC_CRYPTO_SUCCESS) {
317 return -1;
318 }
319
320 /*
321 * Expand
322 */
323
324 len = *okm_len;
325 counter = 1;
326 first = true;
327 for (off = 0; len > 0; off += TC_SHA256_DIGEST_SIZE, ++counter) {
328 rc = tc_hmac_set_key(&hmac, prk, TC_SHA256_DIGEST_SIZE);
329 if (rc != TC_CRYPTO_SUCCESS) {
330 return -1;
331 }
332
333 rc = tc_hmac_init(&hmac);
334 if (rc != TC_CRYPTO_SUCCESS) {
335 return -1;
336 }
337
338 if (first) {
339 first = false;
340 } else {
341 rc = tc_hmac_update(&hmac, T, TC_SHA256_DIGEST_SIZE);
342 if (rc != TC_CRYPTO_SUCCESS) {
343 return -1;
344 }
345 }
346
347 rc = tc_hmac_update(&hmac, info, info_len);
348 if (rc != TC_CRYPTO_SUCCESS) {
349 return -1;
350 }
351
352 rc = tc_hmac_update(&hmac, &counter, 1);
353 if (rc != TC_CRYPTO_SUCCESS) {
354 return -1;
355 }
356
357 rc = tc_hmac_final(T, TC_SHA256_DIGEST_SIZE, &hmac);
358 if (rc != TC_CRYPTO_SUCCESS) {
359 return -1;
360 }
361
362 if (len > TC_SHA256_DIGEST_SIZE) {
363 memcpy(&okm[off], T, TC_SHA256_DIGEST_SIZE);
364 len -= TC_SHA256_DIGEST_SIZE;
365 } else {
366 memcpy(&okm[off], T, len);
367 len = 0;
368 }
369 }
370
371 return 0;
372}
373#endif
374
Fabio Utzigba829042018-09-18 08:29:34 -0300375int
Fabio Utzig10ee6482019-08-01 12:04:52 -0300376boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot, uint8_t *enckey)
Fabio Utzigba829042018-09-18 08:29:34 -0300377{
378 int rc;
379
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200380#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300381 mbedtls_aes_init(&enc_state[slot].aes);
382 rc = mbedtls_aes_setkey_enc(&enc_state[slot].aes, enckey, BOOT_ENC_KEY_SIZE_BITS);
383 if (rc) {
384 mbedtls_aes_free(&enc_state[slot].aes);
385 return -1;
386 }
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200387#else
388 (void)rc;
389
390 /* set_encrypt and set_decrypt do the same thing in tinycrypt */
391 tc_aes128_set_encrypt_key(&enc_state[slot].aes, enckey);
392#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300393
394 enc_state[slot].valid = 1;
395
396 return 0;
397}
398
399#if defined(MCUBOOT_ENCRYPT_RSA)
400# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
401# define EXPECTED_ENC_LEN TLV_ENC_RSA_SZ
402#elif defined(MCUBOOT_ENCRYPT_KW)
403# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
404# define EXPECTED_ENC_LEN TLV_ENC_KW_SZ
Fabio Utzig5fde8322019-10-23 12:23:08 -0300405#elif defined(MCUBOOT_ENCRYPT_EC256)
406# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
407# define EXPECTED_ENC_LEN (65 + 32 + 16)
408# define EC_PUBK_INDEX (1)
409# define EC_TAG_INDEX (65)
410# define EC_CIPHERKEY_INDEX (65 + 32)
Fabio Utzigba829042018-09-18 08:29:34 -0300411#endif
412
413/*
414 * Load encryption key.
415 */
416int
Fabio Utzig10ee6482019-08-01 12:04:52 -0300417boot_enc_load(struct enc_key_data *enc_state, int image_index,
418 const struct image_header *hdr, const struct flash_area *fap,
419 uint8_t *enckey)
Fabio Utzigba829042018-09-18 08:29:34 -0300420{
421#if defined(MCUBOOT_ENCRYPT_RSA)
422 mbedtls_rsa_context rsa;
423 uint8_t *cp;
424 uint8_t *cpend;
Fabio Utzigba829042018-09-18 08:29:34 -0300425 size_t olen;
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200426#endif
Fabio Utzig5fde8322019-10-23 12:23:08 -0300427#if defined(MCUBOOT_ENCRYPT_EC256)
428 struct tc_hmac_state_struct hmac;
429 struct tc_aes_key_sched_struct aes;
430 uint8_t tag[TC_SHA256_DIGEST_SIZE];
431 uint8_t shared[NUM_ECC_BYTES];
432 uint8_t derived_key[TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE];
433 uint8_t *cp;
434 uint8_t *cpend;
435 uint8_t pk[NUM_ECC_BYTES];
436 uint8_t counter[TC_AES_BLOCK_SIZE];
437#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300438 uint32_t off;
Fabio Utzig61fd8882019-09-14 20:00:20 -0300439 uint16_t len;
440 struct image_tlv_iter it;
Fabio Utzig5fde8322019-10-23 12:23:08 -0300441 uint8_t buf[EXPECTED_ENC_LEN];
Fabio Utzigba829042018-09-18 08:29:34 -0300442 uint8_t slot;
Fabio Utzigba829042018-09-18 08:29:34 -0300443 int rc;
444
Fabio Utzigb0f04732019-07-31 09:49:19 -0300445 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100446 if (rc < 0) {
447 return rc;
448 }
449 slot = rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300450
451 /* Already loaded... */
452 if (enc_state[slot].valid) {
453 return 1;
454 }
455
Fabio Utzig61fd8882019-09-14 20:00:20 -0300456 rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_ENC_TLV, false);
Fabio Utzigba829042018-09-18 08:29:34 -0300457 if (rc) {
Fabio Utzigba829042018-09-18 08:29:34 -0300458 return -1;
459 }
Fabio Utzigba829042018-09-18 08:29:34 -0300460
Fabio Utzig61fd8882019-09-14 20:00:20 -0300461 rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
462 if (rc != 0) {
463 return rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300464 }
465
Fabio Utzig61fd8882019-09-14 20:00:20 -0300466 if (len != EXPECTED_ENC_LEN) {
Fabio Utzigba829042018-09-18 08:29:34 -0300467 return -1;
Fabio Utzig61fd8882019-09-14 20:00:20 -0300468 }
469
470 rc = flash_area_read(fap, off, buf, EXPECTED_ENC_LEN);
471 if (rc) {
472 return -1;
Fabio Utzigba829042018-09-18 08:29:34 -0300473 }
474
Fabio Utzigba829042018-09-18 08:29:34 -0300475#if defined(MCUBOOT_ENCRYPT_RSA)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300476
Fabio Utzig233af7d2019-08-26 12:06:16 -0300477 mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
Fabio Utzigba829042018-09-18 08:29:34 -0300478
Fabio Utzig233af7d2019-08-26 12:06:16 -0300479 cp = (uint8_t *)bootutil_enc_key.key;
480 cpend = cp + *bootutil_enc_key.len;
Fabio Utzigba829042018-09-18 08:29:34 -0300481
Fabio Utzig5fde8322019-10-23 12:23:08 -0300482 rc = parse_rsa_enckey(&rsa, &cp, cpend);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300483 if (rc) {
Fabio Utzigba829042018-09-18 08:29:34 -0300484 mbedtls_rsa_free(&rsa);
Fabio Utzig233af7d2019-08-26 12:06:16 -0300485 return rc;
486 }
487
488 rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
489 NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
490 mbedtls_rsa_free(&rsa);
Fabio Utzigba829042018-09-18 08:29:34 -0300491
492#elif defined(MCUBOOT_ENCRYPT_KW)
Fabio Utzig5fde8322019-10-23 12:23:08 -0300493
Fabio Utzig233af7d2019-08-26 12:06:16 -0300494 assert(*bootutil_enc_key.len == 16);
495 rc = key_unwrap(buf, enckey);
Fabio Utzig5fde8322019-10-23 12:23:08 -0300496
497#elif defined(MCUBOOT_ENCRYPT_EC256)
498
499 cp = (uint8_t *)bootutil_enc_key.key;
500 cpend = cp + *bootutil_enc_key.len;
501
502 /*
503 * Load the stored EC256 decryption private key
504 */
505
506 rc = parse_ec256_enckey(&cp, cpend, pk);
507 if (rc) {
508 return rc;
509 }
510
511 /* is EC point uncompressed? */
512 if (buf[0] != 0x04) {
513 return -1;
514 }
515
516 /*
517 * First "element" in the TLV is the curve point (public key)
518 */
519 rc = uECC_valid_public_key(&buf[EC_PUBK_INDEX], uECC_secp256r1());
520 if (rc != 0) {
521 return -1;
522 }
523
524 rc = uECC_shared_secret(&buf[EC_PUBK_INDEX], pk, shared, uECC_secp256r1());
525 if (rc != TC_CRYPTO_SUCCESS) {
526 return -1;
527 }
528
529 /*
530 * Expand shared secret to create keys for AES-128-CTR + HMAC-SHA256
531 */
532
533 len = TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE;
Fabio Utzig23e99b02019-11-07 11:55:20 -0300534 rc = hkdf(shared, NUM_ECC_BYTES, (uint8_t *)"MCUBoot_ECIES_v1", 16,
Fabio Utzig5fde8322019-10-23 12:23:08 -0300535 derived_key, &len);
536 if (rc != 0 || len != (TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE)) {
537 return -1;
538 }
539
540 /*
541 * HMAC the key and check that our received MAC matches the generated tag
542 */
543
544 rc = tc_hmac_set_key(&hmac, &derived_key[16], 32);
545 if (rc != TC_CRYPTO_SUCCESS) {
546 return -1;
547 }
548
549 rc = tc_hmac_init(&hmac);
550 if (rc != TC_CRYPTO_SUCCESS) {
551 return -1;
552 }
553
554 rc = tc_hmac_update(&hmac, &buf[EC_CIPHERKEY_INDEX], 16);
555 if (rc != TC_CRYPTO_SUCCESS) {
556 return -1;
557 }
558
559 /* Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes */
560 rc = tc_hmac_final(tag, TC_SHA256_DIGEST_SIZE, &hmac);
561 if (rc != TC_CRYPTO_SUCCESS) {
562 return -1;
563 }
564
565 if (_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
566 return -1;
567 }
568
569 /*
570 * Finally decrypt the received ciphered key
571 */
572
573 rc = tc_aes128_set_decrypt_key(&aes, derived_key);
574 if (rc != TC_CRYPTO_SUCCESS) {
575 return -1;
576 }
577
578 memset(counter, 0, TC_AES_BLOCK_SIZE);
579 rc = tc_ctr_mode(enckey, TC_AES_KEY_SIZE, &buf[EC_CIPHERKEY_INDEX],
580 TC_AES_KEY_SIZE, counter, &aes);
581 if (rc != TC_CRYPTO_SUCCESS) {
582 return -1;
583 }
584
585 rc = 0;
586
Fabio Utzigba829042018-09-18 08:29:34 -0300587#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300588
Fabio Utzigba829042018-09-18 08:29:34 -0300589 return rc;
590}
591
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100592bool
Fabio Utzig10ee6482019-08-01 12:04:52 -0300593boot_enc_valid(struct enc_key_data *enc_state, int image_index,
594 const struct flash_area *fap)
Fabio Utzigba829042018-09-18 08:29:34 -0300595{
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100596 int rc;
597
Fabio Utzigb0f04732019-07-31 09:49:19 -0300598 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100599 if (rc < 0) {
600 /* can't get proper slot number - skip encryption, */
Fabio Utzigb0f04732019-07-31 09:49:19 -0300601 /* postpone the error for a upper layer */
Andrzej Puzdrowskicf97dd02019-03-14 15:10:10 +0100602 return false;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100603 }
604
605 return enc_state[rc].valid;
Fabio Utzigba829042018-09-18 08:29:34 -0300606}
607
608void
Fabio Utzig10ee6482019-08-01 12:04:52 -0300609boot_encrypt(struct enc_key_data *enc_state, int image_index,
610 const struct flash_area *fap, uint32_t off, uint32_t sz,
611 uint32_t blk_off, uint8_t *buf)
Fabio Utzigba829042018-09-18 08:29:34 -0300612{
613 struct enc_key_data *enc;
614 uint32_t i, j;
615 uint8_t u8;
616 uint8_t nonce[16];
617 uint8_t blk[16];
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100618 int rc;
Fabio Utzigba829042018-09-18 08:29:34 -0300619
620 memset(nonce, 0, 12);
621 off >>= 4;
622 nonce[12] = (uint8_t)(off >> 24);
623 nonce[13] = (uint8_t)(off >> 16);
624 nonce[14] = (uint8_t)(off >> 8);
625 nonce[15] = (uint8_t)off;
626
Fabio Utzigb0f04732019-07-31 09:49:19 -0300627 rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +0100628 if (rc < 0) {
629 assert(0);
630 return;
631 }
632
633 enc = &enc_state[rc];
Fabio Utzigba829042018-09-18 08:29:34 -0300634 assert(enc->valid == 1);
635 for (i = 0; i < sz; i++) {
636 if (i == 0 || blk_off == 0) {
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200637#if defined(MCUBOOT_USE_MBED_TLS)
Fabio Utzigba829042018-09-18 08:29:34 -0300638 mbedtls_aes_crypt_ecb(&enc->aes, MBEDTLS_AES_ENCRYPT, nonce, blk);
Fabio Utzig38f5ffe2018-12-27 16:12:58 -0200639#else
640 tc_aes_encrypt(blk, nonce, &enc->aes);
641#endif
Fabio Utzigba829042018-09-18 08:29:34 -0300642
643 for (j = 16; j > 0; --j) {
644 if (++nonce[j - 1] != 0) {
645 break;
646 }
647 }
648 }
649
650 u8 = *buf;
651 *buf++ = u8 ^ blk[blk_off];
652 blk_off = (blk_off + 1) & 0x0f;
653 }
654}
655
Fabio Utzig10ee6482019-08-01 12:04:52 -0300656/**
657 * Clears encrypted state after use.
658 */
Fabio Utzigb63d9952019-08-19 14:20:52 -0300659void
660boot_enc_zeroize(struct enc_key_data *enc_state)
Fabio Utzigba829042018-09-18 08:29:34 -0300661{
Fabio Utzig10ee6482019-08-01 12:04:52 -0300662 memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
Fabio Utzigba829042018-09-18 08:29:34 -0300663}
664
665#endif /* MCUBOOT_ENC_IMAGES */