diff options
author | Bill Richardson <wfrichar@chromium.org> | 2015-02-03 17:07:15 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-03-10 20:44:43 +0000 |
commit | 4e4c19602edf3834b50d66d3ba067e895aca6fa0 (patch) | |
tree | 11b9408e5e6a9c3e3fde95c21656e67562bb3faf /host/lib21 | |
parent | 26af0da4f7e0fd5cc9410011ca05ff6539bbf42d (diff) | |
download | vboot-4e4c19602edf3834b50d66d3ba067e895aca6fa0.tar.gz |
futility: Add create command to make keypairs from RSA files
This command reads a single .pem file and emits the public and
private keys generated from it. It can produce both the old-style
vboot 1.0 keys (.vbpubk and .vbprivk), or the new vboot 2.1
format keys (.vbpubk2 and .vbprik2). The default is the new
format, but you can give futility the --vb1 arg to force the old
format.
A test is included.
BUG=chromium:231547
BRANCH=ToT
TEST=make runtests
Change-Id: I4713dc5bf34151052870f88ba52ddccf9d4dab50
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/246766
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'host/lib21')
-rw-r--r-- | host/lib21/host_key.c | 116 | ||||
-rw-r--r-- | host/lib21/host_misc.c | 69 | ||||
-rw-r--r-- | host/lib21/host_signature.c | 2 | ||||
-rw-r--r-- | host/lib21/include/host_key2.h | 67 | ||||
-rw-r--r-- | host/lib21/include/host_misc2.h | 36 |
5 files changed, 266 insertions, 24 deletions
diff --git a/host/lib21/host_key.c b/host/lib21/host_key.c index 5123b85d..4acba9cb 100644 --- a/host/lib21/host_key.c +++ b/host/lib21/host_key.c @@ -5,11 +5,10 @@ * Host functions for keys. */ +#include <stdio.h> + #define OPENSSL_NO_SHA -#include <openssl/engine.h> #include <openssl/pem.h> -#include <openssl/rsa.h> -#include <openssl/x509.h> #include "2sysincludes.h" #include "2common.h" @@ -20,6 +19,57 @@ #include "host_key2.h" #include "host_misc.h" +struct vb2_text_vs_enum vb2_text_vs_algorithm[] = { + {"RSA1024 SHA1", VB2_ALG_RSA1024_SHA1}, + {"RSA1024 SHA256", VB2_ALG_RSA1024_SHA256}, + {"RSA1024 SHA512", VB2_ALG_RSA1024_SHA512}, + {"RSA2048 SHA1", VB2_ALG_RSA2048_SHA1}, + {"RSA2048 SHA256", VB2_ALG_RSA2048_SHA256}, + {"RSA2048 SHA512", VB2_ALG_RSA2048_SHA512}, + {"RSA4096 SHA1", VB2_ALG_RSA4096_SHA1}, + {"RSA4096 SHA256", VB2_ALG_RSA4096_SHA256}, + {"RSA4096 SHA512", VB2_ALG_RSA4096_SHA512}, + {"RSA8192 SHA1", VB2_ALG_RSA8192_SHA1}, + {"RSA8192 SHA256", VB2_ALG_RSA8192_SHA256}, + {"RSA8192 SHA512", VB2_ALG_RSA8192_SHA512}, + {0, 0} +}; + +struct vb2_text_vs_enum vb2_text_vs_sig[] = { + {"RSA1024", VB2_SIG_RSA1024}, + {"RSA2048", VB2_SIG_RSA2048}, + {"RSA4096", VB2_SIG_RSA4096}, + {"RSA8192", VB2_SIG_RSA8192}, + {0, 0} +}; + +struct vb2_text_vs_enum vb2_text_vs_hash[] = { + {"SHA1", VB2_HASH_SHA1}, + {"SHA256", VB2_HASH_SHA256}, + {"SHA512", VB2_HASH_SHA512}, + {0, 0} +}; + +const struct vb2_text_vs_enum *vb2_lookup_by_num( + const struct vb2_text_vs_enum *table, + const unsigned int num) +{ + for (; table->name; table++) + if (table->num == num) + return table; + return 0; +} + +const struct vb2_text_vs_enum *vb2_lookup_by_name( + const struct vb2_text_vs_enum *table, + const char *name) +{ + for (; table->name; table++) + if (!strcasecmp(table->name, name)) + return table; + return 0; +} + void vb2_private_key_free(struct vb2_private_key *key) { if (!key) @@ -284,19 +334,8 @@ int vb2_private_key_hash(const struct vb2_private_key **key_ptr, } } -/** - * Allocate a public key buffer of sufficient size for the signature algorithm. - * - * This only initializes the sig_alg field and the guid field to an empty - * guid. It does not set any of the other fields in *key_ptr. - * - * @param key_ptr Destination for newly allocated key; this must be - * freed with vb2_public_key_free(). - * @param sig_alg Signature algorithm for key. - * @return VB2_SUCCESS, or non-zero error code if error. - */ -static int vb2_public_key_alloc(struct vb2_public_key **key_ptr, - enum vb2_signature_algorithm sig_alg) +int vb2_public_key_alloc(struct vb2_public_key **key_ptr, + enum vb2_signature_algorithm sig_alg) { struct vb2_public_key *key; uint32_t key_data_size = vb2_packed_key_size(sig_alg); @@ -322,18 +361,16 @@ static int vb2_public_key_alloc(struct vb2_public_key **key_ptr, void vb2_public_key_free(struct vb2_public_key *key) { + if (!key) + return; + if (key->desc) free((void *)key->desc); free(key); } -/** - * Return the packed data for a key allocated with vb2_public_key_alloc(). - * - * The packed data is in the same buffer, following the key struct and GUID. - */ -static uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key) +uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key) { return (uint8_t *)(key->guid + 1); } @@ -505,3 +542,38 @@ int vb2_public_key_hash(struct vb2_public_key *key, key->guid = vb2_hash_guid(hash_alg); return VB2_SUCCESS; } + +enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa) +{ + int bits = BN_num_bits(rsa->n); + + switch (bits) { + case 1024: + return VB2_SIG_RSA1024; + case 2048: + return VB2_SIG_RSA2048; + case 4096: + return VB2_SIG_RSA4096; + case 8192: + return VB2_SIG_RSA8192; + } + + /* no clue */ + return VB2_SIG_INVALID; +} + +int vb2_public_key_write(const struct vb2_public_key *key, + const char *filename) +{ + struct vb2_packed_key *pkey; + int ret; + + ret = vb2_public_key_pack(&pkey, key); + if (ret) + return ret; + + ret = vb2_write_object(filename, pkey); + + free(pkey); + return ret; +} diff --git a/host/lib21/host_misc.c b/host/lib21/host_misc.c index 555867a2..c55996eb 100644 --- a/host/lib21/host_misc.c +++ b/host/lib21/host_misc.c @@ -13,6 +13,7 @@ #include "2sha.h" #include "vb2_common.h" #include "host_common.h" +#include "host_misc2.h" int vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr) { @@ -93,3 +94,71 @@ uint32_t vb2_desc_size(const char *desc) return roundup32(strlen(desc) + 1); } +int vb2_str_to_guid(const char *str, struct vb2_guid *guid) +{ + uint32_t time_low; + uint16_t time_mid; + uint16_t time_high_and_version; + unsigned int chunk[11]; + + if (!str || + 11 != sscanf(str, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + chunk+0, + chunk+1, + chunk+2, + chunk+3, + chunk+4, + chunk+5, + chunk+6, + chunk+7, + chunk+8, + chunk+9, + chunk+10)) { + return VB2_ERROR_STR_TO_GUID; + } + + time_low = chunk[0] & 0xffffffff; + time_mid = chunk[1] & 0xffff; + time_high_and_version = chunk[2] & 0xffff; + + guid->uuid.time_low = htole32(time_low); + guid->uuid.time_mid = htole16(time_mid); + guid->uuid.time_high_and_version = htole16(time_high_and_version); + + guid->uuid.clock_seq_high_and_reserved = chunk[3] & 0xff; + guid->uuid.clock_seq_low = chunk[4] & 0xff; + guid->uuid.node[0] = chunk[5] & 0xff; + guid->uuid.node[1] = chunk[6] & 0xff; + guid->uuid.node[2] = chunk[7] & 0xff; + guid->uuid.node[3] = chunk[8] & 0xff; + guid->uuid.node[4] = chunk[9] & 0xff; + guid->uuid.node[5] = chunk[10] & 0xff; + + return VB2_SUCCESS; +} + +int vb2_guid_to_str(const struct vb2_guid *guid, + char *buf, unsigned int buflen) +{ + int n; + + if (!buf || buflen < VB2_GUID_MIN_STRLEN) + return VB2_ERROR_GUID_TO_STR; + + n = snprintf(buf, buflen, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + le32toh(guid->uuid.time_low), + le16toh(guid->uuid.time_mid), + le16toh(guid->uuid.time_high_and_version), + guid->uuid.clock_seq_high_and_reserved, + guid->uuid.clock_seq_low, + guid->uuid.node[0], guid->uuid.node[1], + guid->uuid.node[2], guid->uuid.node[3], + guid->uuid.node[4], guid->uuid.node[5]); + + if (n != VB2_GUID_MIN_STRLEN - 1) + return VB2_ERROR_GUID_TO_STR; + + return VB2_SUCCESS; +} diff --git a/host/lib21/host_signature.c b/host/lib21/host_signature.c index 553aa386..11785c71 100644 --- a/host/lib21/host_signature.c +++ b/host/lib21/host_signature.c @@ -6,8 +6,6 @@ */ #define OPENSSL_NO_SHA -#include <openssl/engine.h> -#include <openssl/pem.h> #include <openssl/rsa.h> #include "2sysincludes.h" diff --git a/host/lib21/include/host_key2.h b/host/lib21/include/host_key2.h index 7c48dcaf..b219ae63 100644 --- a/host/lib21/include/host_key2.h +++ b/host/lib21/include/host_key2.h @@ -21,6 +21,34 @@ struct vb2_private_key { struct vb2_guid guid; /* Key GUID */ }; +/* Convert between enums and human-readable form. Terminated with {0, 0}. */ +struct vb2_text_vs_enum { + const char *name; + unsigned int num; +}; + +/** + * @param table Table to search + * @param num Enum value to search for + * @return pointer to table entry or NULL if no match + */ +const struct vb2_text_vs_enum *vb2_lookup_by_num( + const struct vb2_text_vs_enum *table, + const unsigned int num); + +/** + * @param table Table to search + * @param name String value to search for + * @return pointer to table entry or NULL if no match + */ +const struct vb2_text_vs_enum *vb2_lookup_by_name( + const struct vb2_text_vs_enum *table, + const char *name); + +extern struct vb2_text_vs_enum vb2_text_vs_algorithm[]; +extern struct vb2_text_vs_enum vb2_text_vs_sig[]; +extern struct vb2_text_vs_enum vb2_text_vs_hash[]; + /** * Free a private key. * @@ -97,6 +125,27 @@ int vb2_private_key_hash(const struct vb2_private_key **key_ptr, enum vb2_hash_algorithm hash_alg); /** + * Allocate a public key buffer of sufficient size for the signature algorithm. + * + * This only initializes the sig_alg field and the guid field to an empty + * guid. It does not set any of the other fields in *key_ptr. + * + * @param key_ptr Destination for newly allocated key; this must be + * freed with vb2_public_key_free(). + * @param sig_alg Signature algorithm for key. + * @return VB2_SUCCESS, or non-zero error code if error. + */ +int vb2_public_key_alloc(struct vb2_public_key **key_ptr, + enum vb2_signature_algorithm sig_alg); + +/** + * Return the packed data for a key allocated with vb2_public_key_alloc(). + * + * The packed data is in the same buffer, following the key struct and GUID. + */ +uint8_t *vb2_public_key_packed_data(struct vb2_public_key *key); + +/** * Free a public key allocated by one of the functions below. * * Note that this should ONLY be called for public keys allocated via one @@ -165,4 +214,22 @@ int vb2_public_key_hash(struct vb2_public_key *key, enum vb2_hash_algorithm hash_alg); +/** + * Return the signature algorithm implied by the bit length of an RSA key + * + * @param rsa RSA key + * @return vb2 signature algorithm + */ +enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa); + +/** + * Write a public key to the vb2_packed_key format. + * + * @param key Key to write + * @param filename File to write key data to. + * @return VB2_SUCCESS, or non-zero error code if error. + */ +int vb2_public_key_write(const struct vb2_public_key *key, + const char *filename); + #endif /* VBOOT_REFERENCE_HOST_KEY2_H_ */ diff --git a/host/lib21/include/host_misc2.h b/host/lib21/include/host_misc2.h new file mode 100644 index 00000000..5d1679be --- /dev/null +++ b/host/lib21/include/host_misc2.h @@ -0,0 +1,36 @@ +/* Copyright 2015 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef VBOOT_REFERENCE_HOST_MISC2_H_ +#define VBOOT_REFERENCE_HOST_MISC2_H_ + +#include <stdint.h> +#include <stdio.h> + +#include "2guid.h" + +/* Length of string representation, including trailing '\0' */ +#define VB2_GUID_MIN_STRLEN 37 + +/** + * Convert string to struct vb2_guid. + * + * @param str Example: "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + * @param guid Destination for binary representation + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_str_to_guid(const char *str, struct vb2_guid *guid); + +/** + * Convert struct vb2_guid to string. + * + * @param guid Binary representation + * @param str Buffer for result "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_guid_to_str(const struct vb2_guid *guid, + char *buf, unsigned int buflen); + +#endif /* VBOOT_REFERENCE_HOST_MISC2_H_ */ |