summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2015-03-03 18:45:10 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-23 08:58:02 +0000
commit8a3b1833af84933cff6d1398689e391c28b6298e (patch)
tree263c97807a7efa15ad00ee2805cd813edfa848df
parent37f830059cac9bf5745afb6666a9d920f9a12624 (diff)
downloadvboot-8a3b1833af84933cff6d1398689e391c28b6298e.tar.gz
vb21: Replace the key GUID with a sha1sum instead
We want a quick and human-friendly way to match keys with signatures, so we decided to give each key a unique GUID and carry that ID around when signing things. But then we realized that we could autogenerate a unique identifier from the .pem file itself, which is even better because then we can match our binary keypair structs with the openssl file used to generate them. This change replaces the GUID id with a sha1sum calculated from the public key's "keyb" blob. BUG=none BRANCH=none TEST=make runtests Also: futility show tests/testkeys/key_rsa4096.pem futility create tests/testkeys/key_rsa4096.pem foo futility show foo.vbp* Note that the GUID is the same for all files. Change-Id: Ie44e46c83433718b1ff0163c1e7c51ec331b99f9 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/256181 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/261743 Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--firmware/2lib/include/2guid.h31
-rw-r--r--firmware/lib21/common.c2
-rw-r--r--firmware/lib21/include/vb2_struct.h6
-rw-r--r--futility/cmd_create.c33
-rw-r--r--futility/vb2_helper.c77
-rw-r--r--host/lib21/host_misc.c105
-rw-r--r--host/lib21/include/host_misc2.h2
7 files changed, 122 insertions, 134 deletions
diff --git a/firmware/2lib/include/2guid.h b/firmware/2lib/include/2guid.h
index 3e892d9c..a8fd346b 100644
--- a/firmware/2lib/include/2guid.h
+++ b/firmware/2lib/include/2guid.h
@@ -9,34 +9,17 @@
#define VBOOT_REFERENCE_VBOOT_2GUID_H_
#include <stdint.h>
-#define UUID_NODE_LEN 6
-#define GUID_SIZE 16
+#define NUM_GUID_BYTES 20
struct vb2_guid {
- union {
- struct {
- uint32_t time_low;
- uint16_t time_mid;
- uint16_t time_high_and_version;
- uint8_t clock_seq_high_and_reserved;
- uint8_t clock_seq_low;
- uint8_t node[UUID_NODE_LEN];
- } uuid;
- uint8_t raw[GUID_SIZE];
- };
+ uint8_t raw[NUM_GUID_BYTES];
} __attribute__((packed));
-#define EXPECTED_GUID_SIZE GUID_SIZE
+#define EXPECTED_GUID_SIZE NUM_GUID_BYTES
-/* Key GUIDs to use for VB2_SIG_NONE and hash algorithms */
-
-#define VB2_GUID_NONE_SHA1 \
- {{{0xcfb5687a,0x6092,0x11e4,0x96,0xe1,{0x8f,0x3b,0x1a,0x60,0xa2,0x1d}}}}
-
-#define VB2_GUID_NONE_SHA256 \
- {{{0x0e4114e0,0x6093,0x11e4,0x9d,0xcb,{0x8f,0x8a,0xf4,0xca,0x2e,0x32}}}}
-
-#define VB2_GUID_NONE_SHA512 \
- {{{0x1c695960,0x6093,0x11e4,0x82,0x63,{0xdb,0xee,0xe9,0x3c,0xcd,0x7e}}}}
+/* GUIDs to use for "keys" with sig_alg==VB2_SIG_NONE */
+#define VB2_GUID_NONE_SHA1 {{0x00, 0x01,} }
+#define VB2_GUID_NONE_SHA256 {{0x02, 0x56,} }
+#define VB2_GUID_NONE_SHA512 {{0x05, 0x12,} }
#endif /* VBOOT_REFERENCE_VBOOT_2GUID_H_ */
diff --git a/firmware/lib21/common.c b/firmware/lib21/common.c
index 5adbf7ae..7a06c8c3 100644
--- a/firmware/lib21/common.c
+++ b/firmware/lib21/common.c
@@ -359,7 +359,7 @@ int vb2_verify_keyblock(struct vb2_keyblock *block,
return rv;
/* Skip signature if it doesn't match the key GUID */
- if (memcmp(&sig->guid, key->guid, GUID_SIZE))
+ if (memcmp(&sig->guid, key->guid, NUM_GUID_BYTES))
continue;
/* Make sure we signed the right amount of data */
diff --git a/firmware/lib21/include/vb2_struct.h b/firmware/lib21/include/vb2_struct.h
index 62e1a080..5bccfab7 100644
--- a/firmware/lib21/include/vb2_struct.h
+++ b/firmware/lib21/include/vb2_struct.h
@@ -142,7 +142,7 @@ struct vb2_packed_key {
} __attribute__((packed));
#define EXPECTED_VB2_PACKED_KEY_SIZE \
- (EXPECTED_VB2_STRUCT_COMMON_SIZE + EXPECTED_GUID_SIZE + 16)
+ (EXPECTED_VB2_STRUCT_COMMON_SIZE + 16 + EXPECTED_GUID_SIZE)
/* Current version of vb2_packed_private_key struct */
#define VB2_PACKED_PRIVATE_KEY_VERSION_MAJOR 3
@@ -181,7 +181,7 @@ struct vb2_packed_private_key {
} __attribute__((packed));
#define EXPECTED_VB2_PACKED_PRIVATE_KEY_SIZE \
- (EXPECTED_VB2_STRUCT_COMMON_SIZE + EXPECTED_GUID_SIZE + 12)
+ (EXPECTED_VB2_STRUCT_COMMON_SIZE + 12 + EXPECTED_GUID_SIZE)
/* Current version of vb2_signature struct */
#define VB2_SIGNATURE_VERSION_MAJOR 3
@@ -229,7 +229,7 @@ struct vb2_signature {
} __attribute__((packed));
#define EXPECTED_VB2_SIGNATURE_SIZE \
- (EXPECTED_VB2_STRUCT_COMMON_SIZE + EXPECTED_GUID_SIZE + 16)
+ (EXPECTED_VB2_STRUCT_COMMON_SIZE + 16 + EXPECTED_GUID_SIZE)
/* Current version of vb2_keyblock struct */
diff --git a/futility/cmd_create.c b/futility/cmd_create.c
index f4eb3f2a..32eed50a 100644
--- a/futility/cmd_create.c
+++ b/futility/cmd_create.c
@@ -41,6 +41,7 @@ static uint32_t opt_version = DEFAULT_VERSION;
enum vb2_hash_algorithm opt_hash_alg = DEFAULT_HASH;
static char *opt_desc;
static struct vb2_guid opt_guid;
+static int force_guid;
static const struct option long_opts[] = {
{"version", 1, 0, OPT_VERSION},
@@ -196,23 +197,15 @@ static int vb2_make_keypair()
fprintf(stderr, "Unable to allocate the private key\n");
goto done;
}
+
privkey->rsa_private_key = rsa_key;
privkey->sig_alg = sig_alg;
privkey->hash_alg = opt_hash_alg;
- privkey->guid = opt_guid;
if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) {
fprintf(stderr, "Unable to set the private key description\n");
goto done;
}
- /* Write it out */
- strcpy(outext, ".vbprik2");
- if (vb2_private_key_write(privkey, outfile)) {
- fprintf(stderr, "unable to write private key\n");
- goto done;
- }
- fprintf(stderr, "wrote %s\n", outfile);
-
/* Create the public key */
if (vb2_public_key_alloc(&pubkey, sig_alg)) {
fprintf(stderr, "Unable to allocate the public key\n");
@@ -240,13 +233,30 @@ static int vb2_make_keypair()
pubkey->hash_alg = opt_hash_alg;
pubkey->version = opt_version;
- memcpy((struct vb2_guid *)pubkey->guid, &opt_guid, sizeof(opt_guid));
if (opt_desc && vb2_public_key_set_desc(pubkey, opt_desc)) {
fprintf(stderr, "Unable to set pubkey description\n");
goto done;
}
- /* Write it out */
+ /* Update the IDs */
+ if (!force_guid) {
+ uint8_t *digest = DigestBuf(keyb_data, keyb_size,
+ SHA1_DIGEST_ALGORITHM);
+ memcpy(&opt_guid, digest, sizeof(opt_guid));
+ free(digest);
+ }
+
+ privkey->guid = opt_guid;
+ memcpy((struct vb2_guid *)pubkey->guid, &opt_guid, sizeof(opt_guid));
+
+ /* Write them out */
+ strcpy(outext, ".vbprik2");
+ if (vb2_private_key_write(privkey, outfile)) {
+ fprintf(stderr, "unable to write private key\n");
+ goto done;
+ }
+ fprintf(stderr, "wrote %s\n", outfile);
+
strcpy(outext, ".vbpubk2");
if (vb2_public_key_write(pubkey, outfile)) {
fprintf(stderr, "unable to write public key\n");
@@ -296,6 +306,7 @@ static int do_create(int argc, char *argv[])
optarg);
errorcnt = 1;
}
+ force_guid = 1;
break;
case OPT_HASH_ALG:
diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c
index 68287ce1..b3349af2 100644
--- a/futility/vb2_helper.c
+++ b/futility/vb2_helper.c
@@ -41,31 +41,34 @@ enum futil_file_type recognize_vb2_key(uint8_t *buf, uint32_t len)
return FILE_TYPE_UNKNOWN;
}
-static void vb2_print_public_key_sha1sum(struct vb2_public_key *key)
+static inline void vb2_print_bytes(const void *ptr, uint32_t len)
+{
+ const uint8_t *buf = (const uint8_t *)ptr;
+ int i;
+ for (i = 0; i < len; i++)
+ printf("%02x", *buf++);
+}
+
+static uint8_t *vb2_public_key_sha1sum(struct vb2_public_key *key)
{
struct vb2_packed_key *pkey;
uint8_t *digest;
- int i;
- if (vb2_public_key_pack(&pkey, key)) {
- printf("<error>");
- return;
- }
+ if (vb2_public_key_pack(&pkey, key))
+ return 0;
digest = DigestBuf((uint8_t *)pkey + pkey->key_offset,
pkey->key_size, SHA1_DIGEST_ALGORITHM);
- for (i = 0; i < SHA1_DIGEST_SIZE; i++)
- printf("%02x", digest[i]);
-
- free(digest);
free(pkey);
+
+ return digest;
}
int futil_cb_show_vb2_pubkey(struct futil_traverse_state_s *state)
{
struct vb2_public_key key;
- char guid_str[VB2_GUID_MIN_STRLEN];
const struct vb2_text_vs_enum *entry;
+ uint8_t *sha1sum;
/* The key's members will point into the state buffer after this. Don't
* free anything. */
@@ -73,9 +76,7 @@ int futil_cb_show_vb2_pubkey(struct futil_traverse_state_s *state)
state->my_area->len))
return 1;
- if (VB2_SUCCESS != vb2_guid_to_str(key.guid, guid_str,
- sizeof(guid_str)))
- return 1;
+ sha1sum = vb2_public_key_sha1sum(&key);
printf("Public Key file: %s\n", state->in_filename);
printf(" Vboot API: 2.1\n");
@@ -86,50 +87,44 @@ int futil_cb_show_vb2_pubkey(struct futil_traverse_state_s *state)
entry = vb2_lookup_by_num(vb2_text_vs_hash, key.hash_alg);
printf(" Hash Algorithm: %d %s\n", key.hash_alg,
entry ? entry->name : "(invalid)");
- printf(" GUID: %s\n", guid_str);
printf(" Version: 0x%08x\n", key.version);
- printf(" Key sha1sum: ");
- vb2_print_public_key_sha1sum(&key);
+ printf(" GUID: ");
+ vb2_print_bytes(key.guid, sizeof(*key.guid));
printf("\n");
-
+ if (sha1sum && memcmp(key.guid, sha1sum, sizeof(*key.guid))) {
+ printf(" Key sha1sum: ");
+ vb2_print_bytes(sha1sum, SHA1_DIGEST_SIZE);
+ printf("\n");
+ }
+ free(sha1sum);
return 0;
}
-static void vb2_print_private_key_sha1sum(struct vb2_private_key *key)
+static uint8_t *vb2_private_key_sha1sum(struct vb2_private_key *key)
{
uint8_t *buf, *digest;
uint32_t buflen;
- int i;
- if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
- printf("<error>");
- return;
- }
+ if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen))
+ return 0;
digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
- for (i = 0; i < SHA1_DIGEST_SIZE; i++)
- printf("%02x", digest[i]);
-
- free(digest);
free(buf);
+
+ return digest;
}
int futil_cb_show_vb2_privkey(struct futil_traverse_state_s *state)
{
struct vb2_private_key *key = 0;
- char guid_str[VB2_GUID_MIN_STRLEN];
const struct vb2_text_vs_enum *entry;
+ uint8_t *sha1sum;
if (VB2_SUCCESS != vb2_private_key_unpack(&key, state->my_area->buf,
state->my_area->len))
return 1;
- if (VB2_SUCCESS != vb2_guid_to_str(&key->guid, guid_str,
- sizeof(guid_str))) {
- vb2_private_key_free(key);
- return 1;
- }
-
+ sha1sum = vb2_private_key_sha1sum(key);
printf("Private key file: %s\n", state->in_filename);
printf(" Vboot API: 2.1\n");
@@ -140,11 +135,15 @@ int futil_cb_show_vb2_privkey(struct futil_traverse_state_s *state)
entry = vb2_lookup_by_num(vb2_text_vs_hash, key->hash_alg);
printf(" Hash Algorithm: %d %s\n", key->hash_alg,
entry ? entry->name : "(invalid)");
- printf(" GUID: %s\n", guid_str);
- printf(" Key sha1sum: ");
- vb2_print_private_key_sha1sum(key);
+ printf(" GUID: ");
+ vb2_print_bytes(&key->guid, sizeof(key->guid));
printf("\n");
-
+ if (sha1sum && memcmp(&key->guid, sha1sum, sizeof(key->guid))) {
+ printf(" Key sha1sum: ");
+ vb2_print_bytes(sha1sum, SHA1_DIGEST_SIZE);
+ printf("\n");
+ }
+ free(sha1sum);
vb2_private_key_free(key);
return 0;
}
diff --git a/host/lib21/host_misc.c b/host/lib21/host_misc.c
index c55996eb..5e8a7cb5 100644
--- a/host/lib21/host_misc.c
+++ b/host/lib21/host_misc.c
@@ -5,7 +5,9 @@
* Host functions for verified boot.
*/
+#include <ctype.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include "2sysincludes.h"
@@ -94,71 +96,64 @@ 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)
+static const char *onedigit(const char *str, uint8_t *vptr)
{
- 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;
- }
+ uint8_t val = 0;
+ char c;
- time_low = chunk[0] & 0xffffffff;
- time_mid = chunk[1] & 0xffff;
- time_high_and_version = chunk[2] & 0xffff;
+ for (; (c = *str++) && !isxdigit(c);)
+ ;
+ if (!c)
+ return 0;
- 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);
+ if (c >= '0' && c <= '9')
+ val = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ val = 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ val = 10 + c - 'a';
- 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;
+ *vptr = val;
+ return str;
+}
- return VB2_SUCCESS;
+static const char *onebyte(const char *str, uint8_t *vptr)
+{
+ uint8_t val;
+ uint8_t digit;
+
+ str = onedigit(str, &digit);
+ if (!str)
+ return 0;
+ val = digit << 4;
+
+ str = onedigit(str, &digit);
+ if (!str)
+ return 0;
+ val |= digit;
+
+ *vptr = val;
+ return str;
}
-int vb2_guid_to_str(const struct vb2_guid *guid,
- char *buf, unsigned int buflen)
+int vb2_str_to_guid(const char *str, struct vb2_guid *guid)
{
- int n;
+ uint8_t val;
+ int i;
- if (!buf || buflen < VB2_GUID_MIN_STRLEN)
- return VB2_ERROR_GUID_TO_STR;
+ if (!str)
+ return VB2_ERROR_STR_TO_GUID;
- 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]);
+ memset(guid, 0, sizeof(*guid));
- if (n != VB2_GUID_MIN_STRLEN - 1)
- return VB2_ERROR_GUID_TO_STR;
+ for (i = 0; i < NUM_GUID_BYTES; i++) {
- return VB2_SUCCESS;
+ str = onebyte(str, &val);
+ if (!str)
+ break;
+ guid->raw[i] = val;
+ }
+
+ /* If we get at least one valid byte, that's good enough. */
+ return i ? VB2_SUCCESS : VB2_ERROR_STR_TO_GUID;
}
diff --git a/host/lib21/include/host_misc2.h b/host/lib21/include/host_misc2.h
index 5d1679be..86ec13f0 100644
--- a/host/lib21/include/host_misc2.h
+++ b/host/lib21/include/host_misc2.h
@@ -12,7 +12,7 @@
#include "2guid.h"
/* Length of string representation, including trailing '\0' */
-#define VB2_GUID_MIN_STRLEN 37
+#define VB2_GUID_MIN_STRLEN (2 * NUM_GUID_BYTES + 1)
/**
* Convert string to struct vb2_guid.