futility: Display public and private keys for both formats

This enhances the futility show command to recognize and identify
our public and private key files, for both the old vboot 1.0
format and the new vboot 2.1 format.

BUG=chromium:231547
BRANCH=ToT
TEST=make runtests

vboot 1.0:

  futility show tests/devkeys/*.vbp*

vboot 2.1:

  futility create tests/testkeys/key_rsa2048.pem foo
  futility show foo.vbp*

Change-Id: I9d7641db03e480b416790a7da6b473215444128a
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/246767
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Bill Richardson
2015-02-04 16:47:16 -08:00
committed by ChromeOS Commit Bot
parent 4e4c19602e
commit add997fa94
9 changed files with 157 additions and 10 deletions

View File

@@ -617,7 +617,8 @@ FUTIL_SRCS = \
futility/cmd_vbutil_keyblock.c \
futility/file_type.c \
futility/traversal.c \
futility/vb1_helper.c
futility/vb1_helper.c \
futility/vb2_helper.c
# List of commands built in futility and futility_s.
FUTIL_STATIC_CMD_LIST = ${BUILD}/gen/futility_static_cmds.c

View File

@@ -46,6 +46,7 @@ static struct local_data_s {
static void show_key(VbPublicKey *pubkey, const char *sp)
{
printf("%sVboot API: 1.0\n", sp);
printf("%sAlgorithm: %" PRIu64 " %s\n", sp, pubkey->algorithm,
(pubkey->algorithm < kNumAlgorithms ?
algo_strings[pubkey->algorithm] : "(invalid)"));
@@ -113,6 +114,7 @@ int futil_cb_show_privkey(struct futil_traverse_state_s *state)
key.algorithm = *(typeof(key.algorithm) *)state->my_area->buf;
printf("Private Key file: %s\n", state->in_filename);
printf(" Vboot API: 1.0\n");
alg_okay = key.algorithm < kNumAlgorithms;
printf(" Algorithm: %" PRIu64 " %s\n", key.algorithm,
alg_okay ? algo_strings[key.algorithm] : "(unknown)");

View File

@@ -32,6 +32,8 @@ static const char * const type_strings[] = {
"raw kernel",
"chromiumos disk image",
"VbPrivateKey",
"vb21 public key",
"vb21 private key",
};
BUILD_ASSERT(ARRAY_SIZE(type_strings) == NUM_FILE_TYPES);
@@ -49,7 +51,8 @@ enum futil_file_type (*recognizers[])(uint8_t *buf, uint32_t len) = {
&recognize_bios_image,
&recognize_gbb,
&recognize_vblock1,
&recognize_privkey,
&recognize_vb1_key,
&recognize_vb2_key,
};
/* Try to figure out what we're looking at */

View File

@@ -23,6 +23,8 @@ enum futil_file_type {
FILE_TYPE_CHROMIUMOS_DISK, /* At least it has a GPT */
FILE_TYPE_PRIVKEY, /* VbPrivateKey */
FILE_TYPE_VB2_PUBKEY, /* struct vb2_public_key */
FILE_TYPE_VB2_PRIVKEY, /* struct vb2_private_key */
NUM_FILE_TYPES
};
@@ -47,6 +49,7 @@ enum futil_file_type recognize_bios_image(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_gbb(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_vblock1(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_gpt(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_privkey(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_vb1_key(uint8_t *buf, uint32_t len);
enum futil_file_type recognize_vb2_key(uint8_t *buf, uint32_t len);
#endif /* VBOOT_REFERENCE_FUTILITY_FILE_TYPE_H_ */

View File

@@ -31,6 +31,8 @@ static int (* const cb_show_funcs[])(struct futil_traverse_state_s *state) = {
NULL, /* CB_RAW_FIRMWARE */
NULL, /* CB_RAW_KERNEL */
futil_cb_show_privkey, /* CB_PRIVKEY */
futil_cb_show_vb2_pubkey, /* CB_VB2_PUBKEY */
futil_cb_show_vb2_privkey, /* CB_VB2_PRIVKEY */
};
BUILD_ASSERT(ARRAY_SIZE(cb_show_funcs) == NUM_CB_COMPONENTS);
@@ -51,6 +53,8 @@ static int (* const cb_sign_funcs[])(struct futil_traverse_state_s *state) = {
futil_cb_sign_raw_firmware, /* CB_RAW_FIRMWARE */
futil_cb_create_kernel_part, /* CB_RAW_KERNEL */
NULL, /* CB_PRIVKEY */
NULL, /* CB_VB2_PUBKEY */
NULL, /* CB_VB2_PRIVKEY */
};
BUILD_ASSERT(ARRAY_SIZE(cb_sign_funcs) == NUM_CB_COMPONENTS);
@@ -80,6 +84,8 @@ static const struct {
{CB_RAW_KERNEL, "raw kernel"}, /* FILE_TYPE_RAW_KERNEL */
{0, "chromiumos disk"}, /* FILE_TYPE_CHROMIUMOS_DISK */
{CB_PRIVKEY, "VbPrivateKey"}, /* FILE_TYPE_PRIVKEY */
{CB_VB2_PUBKEY, "vb21 public key"}, /* FILE_TYPE_VB2_PUBKEY */
{CB_VB2_PRIVKEY, "vb21 private key"}, /* FILE_TYPE_VB2_PRIVKEY */
};
BUILD_ASSERT(ARRAY_SIZE(direct_callback) == NUM_FILE_TYPES);
@@ -152,6 +158,8 @@ static const char * const futil_cb_component_str[] = {
"CB_RAW_FIRMWARE",
"CB_RAW_KERNEL",
"CB_PRIVKEY",
"CB_VB2_PUBKEY",
"CB_VB2_PRIVKEY",
};
BUILD_ASSERT(ARRAY_SIZE(futil_cb_component_str) == NUM_CB_COMPONENTS);

View File

@@ -36,6 +36,8 @@ enum futil_cb_component {
CB_RAW_FIRMWARE,
CB_RAW_KERNEL,
CB_PRIVKEY,
CB_VB2_PUBKEY,
CB_VB2_PRIVKEY,
NUM_CB_COMPONENTS
};
@@ -83,6 +85,8 @@ int futil_cb_show_fw_main(struct futil_traverse_state_s *state);
int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state);
int futil_cb_show_kernel_preamble(struct futil_traverse_state_s *state);
int futil_cb_show_privkey(struct futil_traverse_state_s *state);
int futil_cb_show_vb2_pubkey(struct futil_traverse_state_s *state);
int futil_cb_show_vb2_privkey(struct futil_traverse_state_s *state);
int futil_cb_sign_pubkey(struct futil_traverse_state_s *state);
int futil_cb_sign_fw_main(struct futil_traverse_state_s *state);

View File

@@ -718,7 +718,6 @@ uint8_t *CreateKernelBlob(uint8_t *vmlinuz_buf, uint64_t vmlinuz_size,
enum futil_file_type recognize_vblock1(uint8_t *buf, uint32_t len)
{
VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf;
VbPublicKey *pubkey = (VbPublicKey *)buf;
VbFirmwarePreambleHeader *fw_preamble;
VbKernelPreambleHeader *kern_preamble;
RSAPublicKey *rsa;
@@ -743,18 +742,20 @@ enum futil_file_type recognize_vblock1(uint8_t *buf, uint32_t len)
return FILE_TYPE_KEYBLOCK;
}
/* Maybe just a VbPublicKey? */
if (PublicKeyLooksOkay(pubkey, len))
return FILE_TYPE_PUBKEY;
return FILE_TYPE_UNKNOWN;
}
enum futil_file_type recognize_privkey(uint8_t *buf, uint32_t len)
enum futil_file_type recognize_vb1_key(uint8_t *buf, uint32_t len)
{
VbPublicKey *pubkey = (VbPublicKey *)buf;
VbPrivateKey key;
const unsigned char *start;
/* Maybe just a VbPublicKey? */
if (len >= sizeof(VbPublicKey) && PublicKeyLooksOkay(pubkey, len))
return FILE_TYPE_PUBKEY;
/* How about a VbPrivateKey? */
if (len < sizeof(key.algorithm))
return FILE_TYPE_UNKNOWN;

125
futility/vb2_helper.c Normal file
View File

@@ -0,0 +1,125 @@
/*
* 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.
*/
#include "2sysincludes.h"
#include "2common.h"
#include "2guid.h"
#include "2rsa.h"
#include "vb2_common.h"
#include "vb2_struct.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_misc2.h"
#include "file_type.h"
#include "futility.h"
#include "traversal.h"
enum futil_file_type recognize_vb2_key(uint8_t *buf, uint32_t len)
{
struct vb2_public_key pubkey;
struct vb2_private_key *privkey = 0;
/* The pubkey points into buf, so nothing to free */
if (VB2_SUCCESS == vb2_unpack_key(&pubkey, buf, len))
return FILE_TYPE_VB2_PUBKEY;
/* The private key unpacks into new structs */
if (VB2_SUCCESS == vb2_private_key_unpack(&privkey, buf, len)) {
vb2_private_key_free(privkey);
return FILE_TYPE_VB2_PRIVKEY;
}
return FILE_TYPE_UNKNOWN;
}
static void vb2_print_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;
}
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);
}
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;
/* The key's members will point into the state buffer after this. Don't
* free anything. */
if (VB2_SUCCESS != vb2_unpack_key(&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)))
return 1;
printf("Public Key file: %s\n", state->in_filename);
printf(" Vboot API: 2.1\n");
printf(" Desc: \"%s\"\n", key.desc);
entry = vb2_lookup_by_num(vb2_text_vs_sig, key.sig_alg);
printf(" Signature Algorithm: %d %s\n", key.sig_alg,
entry ? entry->name : "(invalid)");
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("\n");
return 0;
}
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;
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;
}
printf("Private key file: %s\n", state->in_filename);
printf(" Vboot API: 2.1\n");
printf(" Desc: \"%s\"\n", key->desc ? key->desc : "");
entry = vb2_lookup_by_num(vb2_text_vs_sig, key->sig_alg);
printf(" Signature Algorithm: %d %s\n", key->sig_alg,
entry ? entry->name : "(invalid)");
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);
vb2_private_key_free(key);
return 0;
}

View File

@@ -270,7 +270,7 @@ int vb2_private_key_write(const struct vb2_private_key *key,
memcpy(buf, &pkey, sizeof(pkey));
/* strcpy() is ok here because we checked the length above */
if (key->desc)
if (pkey.c.desc_size)
strcpy((char *)buf + pkey.c.fixed_size, key->desc);
if (rsabuf) {