• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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