Home | History | Annotate | Download | only in lib21
      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    372 uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key)
    373 {
    374 	return (uint8_t *)(key->guid + 1);
    375 }
    376 
    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 
    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 
    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 
    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 
    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 
    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 
    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