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