summaryrefslogtreecommitdiff
path: root/host/lib21
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2015-02-03 17:07:15 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-10 20:44:43 +0000
commit4e4c19602edf3834b50d66d3ba067e895aca6fa0 (patch)
tree11b9408e5e6a9c3e3fde95c21656e67562bb3faf /host/lib21
parent26af0da4f7e0fd5cc9410011ca05ff6539bbf42d (diff)
downloadvboot-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.c116
-rw-r--r--host/lib21/host_misc.c69
-rw-r--r--host/lib21/host_signature.c2
-rw-r--r--host/lib21/include/host_key2.h67
-rw-r--r--host/lib21/include/host_misc2.h36
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_ */