mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 10:14:55 +00:00
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:
committed by
ChromeOS Commit Bot
parent
4e4c19602e
commit
add997fa94
3
Makefile
3
Makefile
@@ -617,7 +617,8 @@ FUTIL_SRCS = \
|
|||||||
futility/cmd_vbutil_keyblock.c \
|
futility/cmd_vbutil_keyblock.c \
|
||||||
futility/file_type.c \
|
futility/file_type.c \
|
||||||
futility/traversal.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.
|
# List of commands built in futility and futility_s.
|
||||||
FUTIL_STATIC_CMD_LIST = ${BUILD}/gen/futility_static_cmds.c
|
FUTIL_STATIC_CMD_LIST = ${BUILD}/gen/futility_static_cmds.c
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ static struct local_data_s {
|
|||||||
|
|
||||||
static void show_key(VbPublicKey *pubkey, const char *sp)
|
static void show_key(VbPublicKey *pubkey, const char *sp)
|
||||||
{
|
{
|
||||||
|
printf("%sVboot API: 1.0\n", sp);
|
||||||
printf("%sAlgorithm: %" PRIu64 " %s\n", sp, pubkey->algorithm,
|
printf("%sAlgorithm: %" PRIu64 " %s\n", sp, pubkey->algorithm,
|
||||||
(pubkey->algorithm < kNumAlgorithms ?
|
(pubkey->algorithm < kNumAlgorithms ?
|
||||||
algo_strings[pubkey->algorithm] : "(invalid)"));
|
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;
|
key.algorithm = *(typeof(key.algorithm) *)state->my_area->buf;
|
||||||
|
|
||||||
printf("Private Key file: %s\n", state->in_filename);
|
printf("Private Key file: %s\n", state->in_filename);
|
||||||
|
printf(" Vboot API: 1.0\n");
|
||||||
alg_okay = key.algorithm < kNumAlgorithms;
|
alg_okay = key.algorithm < kNumAlgorithms;
|
||||||
printf(" Algorithm: %" PRIu64 " %s\n", key.algorithm,
|
printf(" Algorithm: %" PRIu64 " %s\n", key.algorithm,
|
||||||
alg_okay ? algo_strings[key.algorithm] : "(unknown)");
|
alg_okay ? algo_strings[key.algorithm] : "(unknown)");
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ static const char * const type_strings[] = {
|
|||||||
"raw kernel",
|
"raw kernel",
|
||||||
"chromiumos disk image",
|
"chromiumos disk image",
|
||||||
"VbPrivateKey",
|
"VbPrivateKey",
|
||||||
|
"vb21 public key",
|
||||||
|
"vb21 private key",
|
||||||
};
|
};
|
||||||
BUILD_ASSERT(ARRAY_SIZE(type_strings) == NUM_FILE_TYPES);
|
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_bios_image,
|
||||||
&recognize_gbb,
|
&recognize_gbb,
|
||||||
&recognize_vblock1,
|
&recognize_vblock1,
|
||||||
&recognize_privkey,
|
&recognize_vb1_key,
|
||||||
|
&recognize_vb2_key,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Try to figure out what we're looking at */
|
/* Try to figure out what we're looking at */
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ enum futil_file_type {
|
|||||||
|
|
||||||
FILE_TYPE_CHROMIUMOS_DISK, /* At least it has a GPT */
|
FILE_TYPE_CHROMIUMOS_DISK, /* At least it has a GPT */
|
||||||
FILE_TYPE_PRIVKEY, /* VbPrivateKey */
|
FILE_TYPE_PRIVKEY, /* VbPrivateKey */
|
||||||
|
FILE_TYPE_VB2_PUBKEY, /* struct vb2_public_key */
|
||||||
|
FILE_TYPE_VB2_PRIVKEY, /* struct vb2_private_key */
|
||||||
|
|
||||||
NUM_FILE_TYPES
|
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_gbb(uint8_t *buf, uint32_t len);
|
||||||
enum futil_file_type recognize_vblock1(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_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_ */
|
#endif /* VBOOT_REFERENCE_FUTILITY_FILE_TYPE_H_ */
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ static int (* const cb_show_funcs[])(struct futil_traverse_state_s *state) = {
|
|||||||
NULL, /* CB_RAW_FIRMWARE */
|
NULL, /* CB_RAW_FIRMWARE */
|
||||||
NULL, /* CB_RAW_KERNEL */
|
NULL, /* CB_RAW_KERNEL */
|
||||||
futil_cb_show_privkey, /* CB_PRIVKEY */
|
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);
|
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_sign_raw_firmware, /* CB_RAW_FIRMWARE */
|
||||||
futil_cb_create_kernel_part, /* CB_RAW_KERNEL */
|
futil_cb_create_kernel_part, /* CB_RAW_KERNEL */
|
||||||
NULL, /* CB_PRIVKEY */
|
NULL, /* CB_PRIVKEY */
|
||||||
|
NULL, /* CB_VB2_PUBKEY */
|
||||||
|
NULL, /* CB_VB2_PRIVKEY */
|
||||||
};
|
};
|
||||||
BUILD_ASSERT(ARRAY_SIZE(cb_sign_funcs) == NUM_CB_COMPONENTS);
|
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 */
|
{CB_RAW_KERNEL, "raw kernel"}, /* FILE_TYPE_RAW_KERNEL */
|
||||||
{0, "chromiumos disk"}, /* FILE_TYPE_CHROMIUMOS_DISK */
|
{0, "chromiumos disk"}, /* FILE_TYPE_CHROMIUMOS_DISK */
|
||||||
{CB_PRIVKEY, "VbPrivateKey"}, /* FILE_TYPE_PRIVKEY */
|
{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);
|
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_FIRMWARE",
|
||||||
"CB_RAW_KERNEL",
|
"CB_RAW_KERNEL",
|
||||||
"CB_PRIVKEY",
|
"CB_PRIVKEY",
|
||||||
|
"CB_VB2_PUBKEY",
|
||||||
|
"CB_VB2_PRIVKEY",
|
||||||
};
|
};
|
||||||
BUILD_ASSERT(ARRAY_SIZE(futil_cb_component_str) == NUM_CB_COMPONENTS);
|
BUILD_ASSERT(ARRAY_SIZE(futil_cb_component_str) == NUM_CB_COMPONENTS);
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ enum futil_cb_component {
|
|||||||
CB_RAW_FIRMWARE,
|
CB_RAW_FIRMWARE,
|
||||||
CB_RAW_KERNEL,
|
CB_RAW_KERNEL,
|
||||||
CB_PRIVKEY,
|
CB_PRIVKEY,
|
||||||
|
CB_VB2_PUBKEY,
|
||||||
|
CB_VB2_PRIVKEY,
|
||||||
|
|
||||||
NUM_CB_COMPONENTS
|
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_fw_preamble(struct futil_traverse_state_s *state);
|
||||||
int futil_cb_show_kernel_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_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_pubkey(struct futil_traverse_state_s *state);
|
||||||
int futil_cb_sign_fw_main(struct futil_traverse_state_s *state);
|
int futil_cb_sign_fw_main(struct futil_traverse_state_s *state);
|
||||||
|
|||||||
@@ -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)
|
enum futil_file_type recognize_vblock1(uint8_t *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf;
|
VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf;
|
||||||
VbPublicKey *pubkey = (VbPublicKey *)buf;
|
|
||||||
VbFirmwarePreambleHeader *fw_preamble;
|
VbFirmwarePreambleHeader *fw_preamble;
|
||||||
VbKernelPreambleHeader *kern_preamble;
|
VbKernelPreambleHeader *kern_preamble;
|
||||||
RSAPublicKey *rsa;
|
RSAPublicKey *rsa;
|
||||||
@@ -743,18 +742,20 @@ enum futil_file_type recognize_vblock1(uint8_t *buf, uint32_t len)
|
|||||||
return FILE_TYPE_KEYBLOCK;
|
return FILE_TYPE_KEYBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Maybe just a VbPublicKey? */
|
|
||||||
if (PublicKeyLooksOkay(pubkey, len))
|
|
||||||
return FILE_TYPE_PUBKEY;
|
|
||||||
|
|
||||||
return FILE_TYPE_UNKNOWN;
|
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;
|
VbPrivateKey key;
|
||||||
const unsigned char *start;
|
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))
|
if (len < sizeof(key.algorithm))
|
||||||
return FILE_TYPE_UNKNOWN;
|
return FILE_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
|||||||
125
futility/vb2_helper.c
Normal file
125
futility/vb2_helper.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -270,7 +270,7 @@ int vb2_private_key_write(const struct vb2_private_key *key,
|
|||||||
memcpy(buf, &pkey, sizeof(pkey));
|
memcpy(buf, &pkey, sizeof(pkey));
|
||||||
|
|
||||||
/* strcpy() is ok here because we checked the length above */
|
/* 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);
|
strcpy((char *)buf + pkey.c.fixed_size, key->desc);
|
||||||
|
|
||||||
if (rsabuf) {
|
if (rsabuf) {
|
||||||
|
|||||||
Reference in New Issue
Block a user