blob: 5cf26030d7d237b847c69e9ea9b0299ebba61a47 [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>
27
28#include "hal/hal_flash.h"
29
30#if defined(MCUBOOT_ENCRYPT_RSA)
31#include "mbedtls/rsa.h"
32#include "mbedtls/asn1.h"
33#endif
34
35#if defined(MCUBOOT_ENCRYPT_KW)
36#include "mbedtls/nist_kw.h"
37#endif
38
39#include "mbedtls/aes.h"
40
41#include "bootutil/image.h"
42#include "bootutil/enc_key.h"
43#include "bootutil/sign_key.h"
44
45#include "bootutil_priv.h"
46
47static struct enc_key_data enc_state[BOOT_NUM_SLOTS];
48
49#define TLV_ENC_RSA_SZ 256
50#define TLV_ENC_KW_SZ 24
51
52#if defined(MCUBOOT_ENCRYPT_RSA)
53static int
54parse_enckey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
55{
56 int rc;
57 size_t len;
58
59 if ((rc = mbedtls_asn1_get_tag(p, end, &len,
60 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
61 return -1;
62 }
63
64 if (*p + len != end) {
65 return -2;
66 }
67
68 if ( /* version */
69 mbedtls_asn1_get_int(p, end, &ctx->ver) != 0 ||
70 /* public modulus */
71 mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0 ||
72 /* public exponent */
73 mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0 ||
74 /* private exponent */
75 mbedtls_asn1_get_mpi(p, end, &ctx->D) != 0 ||
76 /* primes */
77 mbedtls_asn1_get_mpi(p, end, &ctx->P) != 0 ||
78 mbedtls_asn1_get_mpi(p, end, &ctx->Q) != 0 ||
79 /* d mod (p-1) and d mod (q-1) */
80 mbedtls_asn1_get_mpi(p, end, &ctx->DP) != 0 ||
81 mbedtls_asn1_get_mpi(p, end, &ctx->DQ) != 0 ||
82 /* q ^ (-1) mod p */
83 mbedtls_asn1_get_mpi(p, end, &ctx->QP) != 0) {
84 return -3;
85 }
86
87 ctx->len = mbedtls_mpi_size(&ctx->N);
88
89 if (*p != end) {
90 return -4;
91 }
92
93 if (mbedtls_rsa_check_pubkey(ctx) != 0 ||
94 mbedtls_rsa_check_privkey(ctx) != 0) {
95 return -5;
96 }
97
98 return 0;
99}
100#endif
101
102int
103boot_enc_set_key(uint8_t slot, uint8_t *enckey)
104{
105 int rc;
106
107 mbedtls_aes_init(&enc_state[slot].aes);
108 rc = mbedtls_aes_setkey_enc(&enc_state[slot].aes, enckey, BOOT_ENC_KEY_SIZE_BITS);
109 if (rc) {
110 mbedtls_aes_free(&enc_state[slot].aes);
111 return -1;
112 }
113
114 enc_state[slot].valid = 1;
115
116 return 0;
117}
118
119#if defined(MCUBOOT_ENCRYPT_RSA)
120# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
121# define EXPECTED_ENC_LEN TLV_ENC_RSA_SZ
122#elif defined(MCUBOOT_ENCRYPT_KW)
123# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
124# define EXPECTED_ENC_LEN TLV_ENC_KW_SZ
125#endif
126
127/*
128 * Load encryption key.
129 */
130int
131boot_enc_load(const struct image_header *hdr, const struct flash_area *fap,
132 uint8_t *enckey)
133{
134#if defined(MCUBOOT_ENCRYPT_RSA)
135 mbedtls_rsa_context rsa;
136 uint8_t *cp;
137 uint8_t *cpend;
138#endif
139#if defined(MCUBOOT_ENCRYPT_KW)
140 mbedtls_nist_kw_context kw;
141#endif
142 size_t olen;
143 uint32_t off;
144 uint32_t end;
145 struct image_tlv_info info;
146 struct image_tlv tlv;
147 uint8_t buf[TLV_ENC_RSA_SZ];
148 uint8_t slot;
149 uint8_t enckey_type;
150 int rc;
151
152 slot = fap->fa_id - FLASH_AREA_IMAGE_0;
153
154 /* Already loaded... */
155 if (enc_state[slot].valid) {
156 return 1;
157 }
158
159 off = hdr->ih_img_size + hdr->ih_hdr_size;
160
161 rc = flash_area_read(fap, off, &info, sizeof(info));
162 if (rc) {
163 return rc;
164 }
165 if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
166 return -1;
167 }
168 end = off + info.it_tlv_tot;
169 off += sizeof(info);
170
171 enckey_type = 0;
172 for (; off < end; off += sizeof(tlv) + tlv.it_len) {
173 rc = flash_area_read(fap, off, &tlv, sizeof tlv);
174 if (rc) {
175 return rc;
176 }
177
178 if (tlv.it_type == EXPECTED_ENC_TLV) {
179 if (tlv.it_len != EXPECTED_ENC_LEN) {
180 return -1;
181 }
182 rc = flash_area_read(fap, off + sizeof(tlv), buf, EXPECTED_ENC_LEN);
183 if (rc) {
184 return rc;
185 }
186 enckey_type = EXPECTED_ENC_TLV;
187 break;
188 }
189 }
190
191 if (enckey_type == 0) {
192 return -1;
193 }
194
195 if (enckey_type == EXPECTED_ENC_TLV) {
196#if defined(MCUBOOT_ENCRYPT_RSA)
197 mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
198
199 cp = (uint8_t *)bootutil_enc_key.key;
200 cpend = cp + *bootutil_enc_key.len;
201
202 rc = parse_enckey(&rsa, &cp, cpend);
203 if (rc) {
204 mbedtls_rsa_free(&rsa);
205 goto done;
206 }
207
208 rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
209 NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
210 mbedtls_rsa_free(&rsa);
211
212#elif defined(MCUBOOT_ENCRYPT_KW)
213 mbedtls_nist_kw_init(&kw);
214
215 assert(*bootutil_enc_key.len == 16);
216 rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES,
217 bootutil_enc_key.key, *bootutil_enc_key.len * 8, 0);
218 if (rc) {
219 mbedtls_nist_kw_free(&kw);
220 goto done;
221 }
222
223 rc = mbedtls_nist_kw_unwrap(&kw, MBEDTLS_KW_MODE_KW, buf, TLV_ENC_KW_SZ,
224 enckey, &olen, BOOT_ENC_KEY_SIZE);
225
226 mbedtls_nist_kw_free(&kw);
227#endif
228 }
229
230done:
231 return rc;
232}
233
234int
235boot_enc_valid(const struct flash_area *fap)
236{
237 return enc_state[fap->fa_id - FLASH_AREA_IMAGE_0].valid;
238}
239
240void
241boot_encrypt(const struct flash_area *fap, uint32_t off, uint32_t sz,
242 uint32_t blk_off, uint8_t *buf)
243{
244 struct enc_key_data *enc;
245 uint32_t i, j;
246 uint8_t u8;
247 uint8_t nonce[16];
248 uint8_t blk[16];
249
250 memset(nonce, 0, 12);
251 off >>= 4;
252 nonce[12] = (uint8_t)(off >> 24);
253 nonce[13] = (uint8_t)(off >> 16);
254 nonce[14] = (uint8_t)(off >> 8);
255 nonce[15] = (uint8_t)off;
256
257 enc = &enc_state[fap->fa_id - FLASH_AREA_IMAGE_0];
258 assert(enc->valid == 1);
259 for (i = 0; i < sz; i++) {
260 if (i == 0 || blk_off == 0) {
261 mbedtls_aes_crypt_ecb(&enc->aes, MBEDTLS_AES_ENCRYPT, nonce, blk);
262
263 for (j = 16; j > 0; --j) {
264 if (++nonce[j - 1] != 0) {
265 break;
266 }
267 }
268 }
269
270 u8 = *buf;
271 *buf++ = u8 ^ blk[blk_off];
272 blk_off = (blk_off + 1) & 0x0f;
273 }
274}
275
276void boot_enc_zeroize(void)
277{
278 memset(&enc_state, 0, sizeof(enc_state));
279}
280
281#endif /* MCUBOOT_ENC_IMAGES */