summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.