1 /* Copyright 2014 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Host functions for keys.
6 */
7
8 #include <stdio.h>
9
10 #include <openssl/pem.h>
11
12 #include "2common.h"
13 #include "2rsa.h"
14 #include "2sha.h"
15 #include "2sysincludes.h"
16 #include "host_common.h"
17 #include "host_common21.h"
18 #include "host_key21.h"
19 #include "host_misc.h"
20 #include "host_p11.h"
21 #include "openssl_compat.h"
22 #include "util_misc.h"
23
vb21_private_key_unpack_raw(const uint8_t * buf,uint32_t size,struct vb2_private_key * key)24 vb2_error_t vb21_private_key_unpack_raw(const uint8_t *buf, uint32_t size,
25 struct vb2_private_key *key)
26 {
27 const struct vb21_packed_private_key *pkey =
28 (const struct vb21_packed_private_key *)buf;
29 const unsigned char *start;
30 uint32_t min_offset = 0;
31
32 /*
33 * Check magic number.
34 *
35 * TODO: If it doesn't match, pass through to the old packed key format.
36 */
37 if (pkey->c.magic != VB21_MAGIC_PACKED_PRIVATE_KEY)
38 return VB2_ERROR_UNPACK_PRIVATE_KEY_MAGIC;
39
40 if (vb21_verify_common_header(buf, size))
41 return VB2_ERROR_UNPACK_PRIVATE_KEY_HEADER;
42
43 /* Make sure key data is inside */
44 if (vb21_verify_common_member(pkey, &min_offset,
45 pkey->key_offset, pkey->key_size))
46 return VB2_ERROR_UNPACK_PRIVATE_KEY_DATA;
47
48 /*
49 * Check for compatible version. No need to check minor version, since
50 * that's compatible across readers matching the major version, and we
51 * haven't added any new fields.
52 */
53 if (pkey->c.struct_version_major !=
54 VB21_PACKED_PRIVATE_KEY_VERSION_MAJOR)
55 return VB2_ERROR_UNPACK_PRIVATE_KEY_STRUCT_VERSION;
56
57 /* Copy key algorithms and ID */
58 key->key_location = PRIVATE_KEY_LOCAL;
59 key->sig_alg = pkey->sig_alg;
60 key->hash_alg = pkey->hash_alg;
61 key->id = pkey->id;
62
63 /* Unpack RSA key */
64 if (pkey->sig_alg == VB2_SIG_NONE) {
65 if (pkey->key_size != 0)
66 return VB2_ERROR_UNPACK_PRIVATE_KEY_HASH;
67 } else {
68 start = (const unsigned char *)(buf + pkey->key_offset);
69 key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
70 pkey->key_size);
71 if (!key->rsa_private_key)
72 return VB2_ERROR_UNPACK_PRIVATE_KEY_RSA;
73 }
74
75 /* Key description */
76 if (pkey->c.desc_size) {
77 if (vb2_private_key_set_desc(key, (const char *)(buf + pkey->c.fixed_size)))
78 return VB2_ERROR_UNPACK_PRIVATE_KEY_DESC;
79 }
80
81 return VB2_SUCCESS;
82 }
83
vb21_private_key_unpack(struct vb2_private_key ** key_ptr,const uint8_t * buf,uint32_t size)84 vb2_error_t vb21_private_key_unpack(struct vb2_private_key **key_ptr, const uint8_t *buf,
85 uint32_t size)
86 {
87 *key_ptr = NULL;
88 struct vb2_private_key *key = (struct vb2_private_key *)calloc(sizeof(*key), 1);
89 if (!key)
90 return VB2_ERROR_UNPACK_PRIVATE_KEY_ALLOC;
91
92 vb2_error_t rv = vb21_private_key_unpack_raw(buf, size, key);
93 if (rv != VB2_SUCCESS) {
94 vb2_free_private_key(key);
95 return rv;
96 }
97 *key_ptr = key;
98 return VB2_SUCCESS;
99 }
100
vb2_private_key_read_pem(struct vb2_private_key ** key_ptr,const char * filename)101 vb2_error_t vb2_private_key_read_pem(struct vb2_private_key **key_ptr,
102 const char *filename)
103 {
104 struct vb2_private_key *key;
105 FILE *f;
106
107 *key_ptr = NULL;
108
109 /* Allocate the new key */
110 key = calloc(1, sizeof(*key));
111 if (!key)
112 return VB2_ERROR_READ_PEM_ALLOC;
113
114 /* Read private key */
115 f = fopen(filename, "rb");
116 if (!f) {
117 free(key);
118 return VB2_ERROR_READ_PEM_FILE_OPEN;
119 }
120
121 key->rsa_private_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
122 fclose(f);
123
124 if (!key->rsa_private_key) {
125 free(key);
126 return VB2_ERROR_READ_PEM_RSA;
127 }
128
129 *key_ptr = key;
130 return VB2_SUCCESS;
131 }
132
vb2_private_key_set_desc(struct vb2_private_key * key,const char * desc)133 vb2_error_t vb2_private_key_set_desc(struct vb2_private_key *key,
134 const char *desc)
135 {
136 if (key->desc)
137 free(key->desc);
138
139 if (desc) {
140 key->desc = strdup(desc);
141 if (!key->desc)
142 return VB2_ERROR_PRIVATE_KEY_SET_DESC;
143 } else {
144 key->desc = NULL;
145 }
146
147 return VB2_SUCCESS;
148 }
149
vb21_private_key_write(const struct vb2_private_key * key,const char * filename)150 vb2_error_t vb21_private_key_write(const struct vb2_private_key *key,
151 const char *filename)
152 {
153 struct vb21_packed_private_key pkey = {
154 .c.magic = VB21_MAGIC_PACKED_PRIVATE_KEY,
155 .c.struct_version_major = VB21_PACKED_PRIVATE_KEY_VERSION_MAJOR,
156 .c.struct_version_minor = VB21_PACKED_PRIVATE_KEY_VERSION_MINOR,
157 .c.fixed_size = sizeof(pkey),
158 .sig_alg = key->sig_alg,
159 .hash_alg = key->hash_alg,
160 .id = key->id,
161 };
162 uint8_t *buf;
163 uint8_t *rsabuf = NULL;
164 int rsalen = 0;
165 vb2_error_t rv;
166
167 memcpy(&pkey.id, &key->id, sizeof(pkey.id));
168
169 pkey.c.desc_size = vb2_desc_size(key->desc);
170
171 if (key->sig_alg != VB2_SIG_NONE) {
172 /* Pack RSA key */
173 rsalen = i2d_RSAPrivateKey(key->rsa_private_key, &rsabuf);
174 if (rsalen <= 0 || !rsabuf)
175 return VB2_ERROR_PRIVATE_KEY_WRITE_RSA;
176 }
177
178 pkey.key_offset = pkey.c.fixed_size + pkey.c.desc_size;
179 pkey.key_size = roundup32(rsalen);
180 pkey.c.total_size = pkey.key_offset + pkey.key_size;
181
182 /* Pack private key */
183 buf = calloc(1, pkey.c.total_size);
184 if (!buf) {
185 free(rsabuf);
186 return VB2_ERROR_PRIVATE_KEY_WRITE_ALLOC;
187 }
188
189 memcpy(buf, &pkey, sizeof(pkey));
190
191 /* strcpy() is ok here because we checked the length above */
192 if (pkey.c.desc_size)
193 strcpy((char *)buf + pkey.c.fixed_size, key->desc);
194
195 if (rsabuf) {
196 memcpy(buf + pkey.key_offset, rsabuf, rsalen);
197 free(rsabuf);
198 }
199
200 rv = vb21_write_object(filename, buf);
201 free(buf);
202
203 return rv ? VB2_ERROR_PRIVATE_KEY_WRITE_FILE : VB2_SUCCESS;
204 }
205
vb2_private_key_hash(const struct vb2_private_key ** key_ptr,enum vb2_hash_algorithm hash_alg)206 vb2_error_t vb2_private_key_hash(const struct vb2_private_key **key_ptr,
207 enum vb2_hash_algorithm hash_alg)
208 {
209 *key_ptr = NULL;
210
211 switch (hash_alg) {
212 #if VB2_SUPPORT_SHA1
213 case VB2_HASH_SHA1:
214 {
215 static const struct vb2_private_key key = {
216 .hash_alg = VB2_HASH_SHA1,
217 .sig_alg = VB2_SIG_NONE,
218 .desc = (char *)"Unsigned SHA1",
219 .id = VB2_ID_NONE_SHA1,
220 };
221 *key_ptr = &key;
222 return VB2_SUCCESS;
223 }
224 #endif
225 #if VB2_SUPPORT_SHA256
226 case VB2_HASH_SHA256:
227 {
228 static const struct vb2_private_key key = {
229 .hash_alg = VB2_HASH_SHA256,
230 .sig_alg = VB2_SIG_NONE,
231 .desc = (char *)"Unsigned SHA-256",
232 .id = VB2_ID_NONE_SHA256,
233 };
234 *key_ptr = &key;
235 return VB2_SUCCESS;
236 }
237 #endif
238 #if VB2_SUPPORT_SHA512
239 case VB2_HASH_SHA512:
240 {
241 static const struct vb2_private_key key = {
242 .hash_alg = VB2_HASH_SHA512,
243 .sig_alg = VB2_SIG_NONE,
244 .desc = (char *)"Unsigned SHA-512",
245 .id = VB2_ID_NONE_SHA512,
246 };
247 *key_ptr = &key;
248 return VB2_SUCCESS;
249 }
250 #endif
251 default:
252 return VB2_ERROR_PRIVATE_KEY_HASH;
253 }
254 }
255
vb2_public_key_alloc(struct vb2_public_key ** key_ptr,enum vb2_signature_algorithm sig_alg)256 vb2_error_t vb2_public_key_alloc(struct vb2_public_key **key_ptr,
257 enum vb2_signature_algorithm sig_alg)
258 {
259 struct vb2_public_key *key;
260 uint32_t key_data_size = vb2_packed_key_size(sig_alg);
261
262 /* The buffer contains the key, its ID, and its packed data */
263 uint32_t buf_size = sizeof(*key) + sizeof(struct vb2_id) +
264 key_data_size;
265
266 if (!key_data_size)
267 return VB2_ERROR_PUBLIC_KEY_ALLOC_SIZE;
268
269 key = calloc(1, buf_size);
270 if (!key)
271 return VB2_ERROR_PUBLIC_KEY_ALLOC;
272
273 key->id = (struct vb2_id *)(key + 1);
274 key->sig_alg = sig_alg;
275
276 *key_ptr = key;
277
278 return VB2_SUCCESS;
279 }
280
vb2_public_key_free(struct vb2_public_key * key)281 void vb2_public_key_free(struct vb2_public_key *key)
282 {
283 if (!key)
284 return;
285
286 if (key->desc)
287 free((void *)key->desc);
288
289 free(key);
290 }
291
vb2_public_key_packed_data(struct vb2_public_key * key)292 uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key)
293 {
294 return (uint8_t *)(key->id + 1);
295 }
296
vb2_public_key_read_keyb(struct vb2_public_key ** key_ptr,const char * filename)297 vb2_error_t vb2_public_key_read_keyb(struct vb2_public_key **key_ptr,
298 const char *filename)
299 {
300 struct vb2_public_key *key = NULL;
301 uint8_t *key_data, *key_buf;
302 uint32_t key_size;
303 enum vb2_signature_algorithm sig_alg;
304
305 *key_ptr = NULL;
306
307 if (vb2_read_file(filename, &key_data, &key_size))
308 return VB2_ERROR_READ_KEYB_DATA;
309
310 /* Guess the signature algorithm from the key size
311 * Note: This only considers exponent F4 keys, as there is no way to
312 * distinguish between exp 3 and F4 based on size. Vboot API 2.1 is
313 * required to make proper use of exp 3 keys. */
314 for (sig_alg = VB2_SIG_RSA1024; sig_alg <= VB2_SIG_RSA8192; sig_alg++) {
315 if (key_size == vb2_packed_key_size(sig_alg))
316 break;
317 }
318 if (sig_alg > VB2_SIG_RSA8192) {
319 free(key_data);
320 return VB2_ERROR_READ_KEYB_SIZE;
321 }
322
323 if (vb2_public_key_alloc(&key, sig_alg)) {
324 free(key_data);
325 return VB2_ERROR_READ_KEYB_ALLOC;
326 }
327
328 /* Copy data from the file buffer to the public key buffer */
329 key_buf = vb2_public_key_packed_data(key);
330 memcpy(key_buf, key_data, key_size);
331 free(key_data);
332
333 if (vb2_unpack_key_data(key, key_buf, key_size)) {
334 vb2_public_key_free(key);
335 return VB2_ERROR_READ_KEYB_UNPACK;
336 }
337
338 *key_ptr = key;
339
340 return VB2_SUCCESS;
341 }
342
vb2_public_key_set_desc(struct vb2_public_key * key,const char * desc)343 vb2_error_t vb2_public_key_set_desc(struct vb2_public_key *key,
344 const char *desc)
345 {
346 if (key->desc)
347 free((void *)key->desc);
348
349 if (desc) {
350 key->desc = strdup(desc);
351 if (!key->desc)
352 return VB2_ERROR_PUBLIC_KEY_SET_DESC;
353 } else {
354 key->desc = NULL;
355 }
356
357 return VB2_SUCCESS;
358 }
359
vb21_packed_key_read(struct vb21_packed_key ** key_ptr,const char * filename)360 vb2_error_t vb21_packed_key_read(struct vb21_packed_key **key_ptr,
361 const char *filename)
362 {
363 struct vb2_public_key key;
364 uint8_t *buf;
365 uint32_t size;
366
367 *key_ptr = NULL;
368
369 if (vb2_read_file(filename, &buf, &size))
370 return VB2_ERROR_READ_PACKED_KEY_DATA;
371
372 /* Validity check: make sure key unpacks properly */
373 if (vb21_unpack_key(&key, buf, size))
374 return VB2_ERROR_READ_PACKED_KEY;
375
376 *key_ptr = (struct vb21_packed_key *)buf;
377
378 return VB2_SUCCESS;
379 }
380
vb21_public_key_pack(struct vb21_packed_key ** key_ptr,const struct vb2_public_key * pubk)381 vb2_error_t vb21_public_key_pack(struct vb21_packed_key **key_ptr,
382 const struct vb2_public_key *pubk)
383 {
384 struct vb21_packed_key key = {
385 .c.magic = VB21_MAGIC_PACKED_KEY,
386 .c.struct_version_major = VB21_PACKED_KEY_VERSION_MAJOR,
387 .c.struct_version_minor = VB21_PACKED_KEY_VERSION_MINOR,
388 };
389 uint8_t *buf;
390 uint32_t *buf32;
391
392 *key_ptr = NULL;
393
394 /* Calculate sizes and offsets */
395 key.c.fixed_size = sizeof(key);
396 key.c.desc_size = vb2_desc_size(pubk->desc);
397 key.key_offset = key.c.fixed_size + key.c.desc_size;
398
399 if (pubk->sig_alg != VB2_SIG_NONE) {
400 key.key_size = vb2_packed_key_size(pubk->sig_alg);
401 if (!key.key_size)
402 return VB2_ERROR_PUBLIC_KEY_PACK_SIZE;
403 }
404
405 key.c.total_size = key.key_offset + key.key_size;
406
407 /* Copy/initialize fields */
408 key.key_version = pubk->version;
409 key.sig_alg = pubk->sig_alg;
410 key.hash_alg = pubk->hash_alg;
411 key.id = *pubk->id;
412
413 /* Allocate the new buffer */
414 buf = calloc(1, key.c.total_size);
415
416 /* Copy data into the buffer */
417 memcpy(buf, &key, sizeof(key));
418
419 /* strcpy() is safe because we allocated above based on strlen() */
420 if (pubk->desc && *pubk->desc) {
421 strcpy((char *)(buf + key.c.fixed_size), pubk->desc);
422 buf[key.c.fixed_size + key.c.desc_size - 1] = 0;
423 }
424
425 if (pubk->sig_alg != VB2_SIG_NONE) {
426 /* Re-pack the key arrays */
427 buf32 = (uint32_t *)(buf + key.key_offset);
428 buf32[0] = pubk->arrsize;
429 buf32[1] = pubk->n0inv;
430 memcpy(buf32 + 2, pubk->n, pubk->arrsize * sizeof(uint32_t));
431 memcpy(buf32 + 2 + pubk->arrsize, pubk->rr,
432 pubk->arrsize * sizeof(uint32_t));
433 }
434
435 *key_ptr = (struct vb21_packed_key *)buf;
436
437 return VB2_SUCCESS;
438 }
439
vb2_public_key_hash(struct vb2_public_key * key,enum vb2_hash_algorithm hash_alg)440 vb2_error_t vb2_public_key_hash(struct vb2_public_key *key,
441 enum vb2_hash_algorithm hash_alg)
442 {
443 switch (hash_alg) {
444 #if VB2_SUPPORT_SHA1
445 case VB2_HASH_SHA1:
446 key->desc = "Unsigned SHA1";
447 break;
448 #endif
449 #if VB2_SUPPORT_SHA256
450 case VB2_HASH_SHA256:
451 key->desc = "Unsigned SHA-256";
452 break;
453 #endif
454 #if VB2_SUPPORT_SHA512
455 case VB2_HASH_SHA512:
456 key->desc = "Unsigned SHA-512";
457 break;
458 #endif
459 default:
460 return VB2_ERROR_PUBLIC_KEY_HASH;
461 }
462
463 key->sig_alg = VB2_SIG_NONE;
464 key->hash_alg = hash_alg;
465 key->id = vb2_hash_id(hash_alg);
466 return VB2_SUCCESS;
467 }
468
vb2_rsa_sig_alg(struct rsa_st * rsa)469 enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa)
470 {
471 const BIGNUM *e, *n;
472 uint32_t exp, bits;
473
474 RSA_get0_key(rsa, &n, &e, NULL);
475 exp = BN_get_word(e);
476 bits = BN_num_bits(n);
477
478 return vb2_get_sig_alg(exp, bits);
479 }
480
vb21_public_key_write(const struct vb2_public_key * key,const char * filename)481 vb2_error_t vb21_public_key_write(const struct vb2_public_key *key,
482 const char *filename)
483 {
484 struct vb21_packed_key *pkey;
485 int ret;
486
487 ret = vb21_public_key_pack(&pkey, key);
488 if (ret)
489 return ret;
490
491 ret = vb21_write_object(filename, pkey);
492
493 free(pkey);
494 return ret;
495 }
496
vb21_unpack_key(struct vb2_public_key * key,const uint8_t * buf,uint32_t size)497 vb2_error_t vb21_unpack_key(struct vb2_public_key *key, const uint8_t *buf,
498 uint32_t size)
499 {
500 const struct vb21_packed_key *pkey =
501 (const struct vb21_packed_key *)buf;
502 uint32_t sig_size;
503 uint32_t min_offset = 0;
504 vb2_error_t rv;
505
506 /* Check magic number */
507 if (pkey->c.magic != VB21_MAGIC_PACKED_KEY)
508 return VB2_ERROR_UNPACK_KEY_MAGIC;
509
510 rv = vb21_verify_common_header(buf, size);
511 if (rv)
512 return rv;
513
514 /* Make sure key data is inside */
515 rv = vb21_verify_common_member(pkey, &min_offset,
516 pkey->key_offset, pkey->key_size);
517 if (rv)
518 return rv;
519
520 /*
521 * Check for compatible version. No need to check minor version, since
522 * that's compatible across readers matching the major version, and we
523 * haven't added any new fields.
524 */
525 if (pkey->c.struct_version_major != VB21_PACKED_KEY_VERSION_MAJOR)
526 return VB2_ERROR_UNPACK_KEY_STRUCT_VERSION;
527
528 /* Copy key algorithms */
529 key->hash_alg = pkey->hash_alg;
530 if (!vb2_digest_size(key->hash_alg))
531 return VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM;
532
533 key->sig_alg = pkey->sig_alg;
534 if (key->sig_alg != VB2_SIG_NONE) {
535 sig_size = vb2_rsa_sig_size(key->sig_alg);
536 if (!sig_size)
537 return VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
538 rv = vb2_unpack_key_data(
539 key,
540 (const uint8_t *)pkey + pkey->key_offset,
541 pkey->key_size);
542 if (rv)
543 return rv;
544 }
545
546 /* Key description */
547 key->desc = vb21_common_desc(pkey);
548 key->version = pkey->key_version;
549 key->id = &pkey->id;
550
551 return VB2_SUCCESS;
552 }
553