futility: cmd_show uses only vboot 2.0 APIs

This removes the remaining vboot 1.0 API calls from cmd_show.

BUG=chromium:611535
BRANCH=none
TEST=make runtests

Change-Id: I03c4260aa034100efbbea1005367cd85dfff273d
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/350173
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
Randall Spangler
2016-06-03 14:00:27 -07:00
committed by chrome-bot
parent 46b77fb2f0
commit 158b29672a
11 changed files with 151 additions and 87 deletions

View File

@@ -293,7 +293,7 @@ INCLUDES += \
# If we're not building for a specific target, just stub out things like the
# TPM commands and various external functions that are provided by the BIOS.
ifeq (${FIRMWARE_ARCH},)
INCLUDES += -Ihost/include -Ihost/lib/include
INCLUDES += -Ihost/include -Ihost/lib/include -Ihost/lib21/include
endif
# Firmware library, used by the other firmware components (depthcharge,
@@ -1199,7 +1199,7 @@ ${TEST20_BINS}: ${FWLIB20}
${TEST20_BINS}: LIBS += ${FWLIB20}
${TEST21_BINS}: ${UTILLIB21}
${TEST21_BINS}: INCLUDES += -Ihost/lib21/include -Ifirmware/lib21/include
${TEST21_BINS}: INCLUDES += -Ifirmware/lib21/include
${TEST21_BINS}: LIBS += ${UTILLIB21}
${TESTBDB_BINS}: ${FWLIB2X} ${UTILBDB}

View File

@@ -204,4 +204,26 @@ int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
const struct vb2_public_key *key,
const struct vb2_workbuf *wb);
/**
* Retrieve the 16-bit vmlinuz header address and size from the preamble.
*
* Size 0 means there is no 16-bit vmlinuz header present. Old preamble
* versions (<2.1) return 0 for both fields.
*
* @param preamble Preamble to check
* @param vmlinuz_header_address Destination for header address
* @param vmlinuz_header_size Destination for header size
*/
void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble,
uint64_t *vmlinuz_header_address,
uint32_t *vmlinuz_header_size);
/**
* Get the flags for the kernel preamble.
*
* @param preamble Preamble to check
* @return Flags for the preamble. Old preamble versions (<2.2) return 0.
*/
uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble);
#endif /* VBOOT_REFERENCE_VB2_COMMON_H_ */

View File

@@ -268,6 +268,8 @@ struct vb2_kernel_preamble {
uint32_t flags;
} __attribute__((packed));
#define EXPECTED_VB2_KERNEL_PREAMBLE_SIZE 116
#define EXPECTED_VB2_KERNEL_PREAMBLE_2_0_SIZE 96
#define EXPECTED_VB2_KERNEL_PREAMBLE_2_1_SIZE 112
#define EXPECTED_VB2_KERNEL_PREAMBLE_2_2_SIZE 116
#endif /* VBOOT_REFERENCE_VB2_STRUCT_H_ */

View File

@@ -249,11 +249,12 @@ int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
const struct vb2_workbuf *wb)
{
struct vb2_signature *sig = &preamble->preamble_signature;
uint32_t min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_0_SIZE;
VB2_DEBUG("Verifying kernel preamble.\n");
/* Sanity checks before attempting signature of data */
if(size < sizeof(*preamble)) {
/* Make sure it's even safe to look at the struct */
if(size < min_size) {
VB2_DEBUG("Not enough data for preamble header.\n");
return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
}
@@ -262,9 +263,14 @@ int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
VB2_DEBUG("Incompatible kernel preamble header version.\n");
return VB2_ERROR_PREAMBLE_HEADER_VERSION;
}
if (preamble->header_version_minor < 2) {
VB2_DEBUG("Old preamble header format not supported\n");
return VB2_ERROR_PREAMBLE_HEADER_OLD;
if (preamble->header_version_minor >= 2)
min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_2_SIZE;
else if (preamble->header_version_minor == 1)
min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_1_SIZE;
if(preamble->preamble_size < min_size) {
VB2_DEBUG("Preamble size too small for header.\n");
return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
}
if (size < preamble->preamble_size) {
VB2_DEBUG("Not enough data for preamble.\n");
@@ -325,7 +331,8 @@ int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
* If vmlinuz header is present, verify it's covered by the body
* signature.
*/
if (preamble->vmlinuz_header_size) {
if (preamble->header_version_minor >= 1 &&
preamble->vmlinuz_header_size) {
const void *body_ptr =
(const void *)(uintptr_t)preamble->body_load_address;
const void *vmlinuz_header_ptr = (const void *)
@@ -442,3 +449,30 @@ int vb2_load_kernel_preamble(struct vb2_context *ctx)
return VB2_SUCCESS;
}
void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble,
uint64_t *vmlinuz_header_address,
uint32_t *vmlinuz_header_size)
{
if (preamble->header_version_minor < 1) {
*vmlinuz_header_address = 0;
*vmlinuz_header_size = 0;
} else {
/*
* Set header and size only if the preamble header version is >
* 2.1 as they don't exist in version 2.0 (Note that we don't
* need to check header_version_major; if that's not 2 then
* VerifyKernelPreamble() would have already failed.
*/
*vmlinuz_header_address = preamble->vmlinuz_header_address;
*vmlinuz_header_size = preamble->vmlinuz_header_size;
}
}
uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble)
{
if (preamble->header_version_minor < 2)
return 0;
return preamble->flags;
}

View File

@@ -30,11 +30,10 @@
#include "futility.h"
#include "futility_options.h"
#include "host_common.h"
#include "host_key2.h"
#include "util_misc.h"
#include "vb1_helper.h"
#include "vb2_common.h"
#include "vboot_common.h"
#include "host_key2.h"
/* Options */
struct show_option_s show_option = {
@@ -43,7 +42,7 @@ struct show_option_s show_option = {
};
/* Shared work buffer */
static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];
static struct vb2_workbuf wb;
void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp)
@@ -102,30 +101,24 @@ int ft_show_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data)
{
VbPrivateKey key;
const unsigned char *start;
struct vb2_packed_private_key *pkey =
(struct vb2_packed_private_key *)buf;
struct vb2_private_key key;
const unsigned char *start = pkey->key_data;
key.algorithm = *(typeof(key.algorithm) *)buf;
start = buf + sizeof(key.algorithm);
if (len <= sizeof(key.algorithm)) {
if (len <= sizeof(*pkey)) {
printf("%s looks bogus\n", name);
return 1;
}
len -= sizeof(key.algorithm);
len -= sizeof(*pkey);
key.rsa_private_key = d2i_RSAPrivateKey(NULL, &start, len);
printf("Private Key file: %s\n", name);
printf(" Vboot API: 1.0\n");
printf(" Algorithm: %" PRIu64 " %s\n", key.algorithm,
vb1_crypto_name(key.algorithm));
printf(" Key sha1sum: ");
if (key.rsa_private_key) {
PrintPrivKeySha1Sum(&key);
RSA_free(key.rsa_private_key);
} else {
printf("<error>");
}
printf("\n");
printf(" Algorithm: %u %s\n", pkey->algorithm,
vb1_crypto_name(pkey->algorithm));
printf(" Key sha1sum: %s\n",
private_key_sha1_string(&key));
return 0;
}
@@ -294,13 +287,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
{
struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
struct vb2_public_key *sign_key = show_option.k;
uint8_t *kernel_blob = 0;
uint64_t kernel_size = 0;
int good_sig = 0;
int retval = 0;
uint64_t vmlinuz_header_size = 0;
uint64_t vmlinuz_header_address = 0;
uint32_t flags = 0;
/* Check the hash... */
if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
@@ -309,6 +296,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
}
/* If we have a key, check the signature too */
int good_sig = 0;
if (sign_key && VB2_SUCCESS ==
vb2_verify_keyblock(keyblock, len, sign_key, &wb))
good_sig = 1;
@@ -319,57 +307,56 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
if (show_option.strict && (!sign_key || !good_sig))
retval = 1;
RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key);
if (!rsa) {
struct vb2_public_key data_key;
if (VB2_SUCCESS !=
vb2_unpack_key(&data_key, (const uint8_t *)&keyblock->data_key,
keyblock->data_key.key_offset +
keyblock->data_key.key_size)) {
fprintf(stderr, "Error parsing data key in %s\n", name);
return 1;
}
uint32_t more = keyblock->keyblock_size;
VbKernelPreambleHeader *preamble =
(VbKernelPreambleHeader *)(buf + more);
if (VBOOT_SUCCESS != VerifyKernelPreamble(preamble,
len - more, rsa)) {
uint32_t more = keyblock->keyblock_size;
struct vb2_kernel_preamble *pre2 =
(struct vb2_kernel_preamble *)(buf + more);
if (VB2_SUCCESS != vb2_verify_kernel_preamble(pre2, len - more,
&data_key, &wb)) {
printf("%s is invalid\n", name);
return 1;
}
printf("Kernel Preamble:\n");
printf(" Size: 0x%" PRIx64 "\n",
preamble->preamble_size);
printf(" Header version: %" PRIu32 ".%" PRIu32 "\n",
preamble->header_version_major,
preamble->header_version_minor);
printf(" Kernel version: %" PRIu64 "\n",
preamble->kernel_version);
printf(" Size: 0x%x\n", pre2->preamble_size);
printf(" Header version: %u.%u\n",
pre2->header_version_major,
pre2->header_version_minor);
printf(" Kernel version: %u\n", pre2->kernel_version);
printf(" Body load address: 0x%" PRIx64 "\n",
preamble->body_load_address);
printf(" Body size: 0x%" PRIx64 "\n",
preamble->body_signature.data_size);
pre2->body_load_address);
printf(" Body size: 0x%x\n",
pre2->body_signature.data_size);
printf(" Bootloader address: 0x%" PRIx64 "\n",
preamble->bootloader_address);
printf(" Bootloader size: 0x%" PRIx64 "\n",
preamble->bootloader_size);
pre2->bootloader_address);
printf(" Bootloader size: 0x%x\n", pre2->bootloader_size);
if (VbGetKernelVmlinuzHeader(preamble,
&vmlinuz_header_address,
&vmlinuz_header_size)
!= VBOOT_SUCCESS) {
fprintf(stderr, "Unable to retrieve Vmlinuz Header!");
return 1;
}
uint64_t vmlinuz_header_address = 0;
uint32_t vmlinuz_header_size = 0;
vb2_kernel_get_vmlinuz_header(pre2,
&vmlinuz_header_address,
&vmlinuz_header_size);
if (vmlinuz_header_size) {
printf(" Vmlinuz_header address: 0x%" PRIx64 "\n",
vmlinuz_header_address);
printf(" Vmlinuz header size: 0x%" PRIx64 "\n",
printf(" Vmlinuz header size: 0x%x\n",
vmlinuz_header_size);
}
if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS)
flags = preamble->flags;
printf(" Flags: 0x%" PRIx32 "\n", flags);
printf(" Flags: 0x%x\n", vb2_kernel_get_flags(pre2));
/* Verify kernel body */
uint8_t *kernel_blob = 0;
uint64_t kernel_size = 0;
if (show_option.fv) {
/* It's in a separate file, which we've already read in */
kernel_blob = show_option.fv;
@@ -386,15 +373,16 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
return 1;
}
if (0 != VerifyData(kernel_blob, kernel_size,
&preamble->body_signature, rsa)) {
if (VB2_SUCCESS !=
vb2_verify_data(kernel_blob, kernel_size, &pre2->body_signature,
&data_key, &wb)) {
fprintf(stderr, "Error verifying kernel body.\n");
return 1;
}
printf("Body verification succeeded.\n");
printf("Config:\n%s\n", kernel_blob + KernelCmdLineOffset(preamble));
printf("Config:\n%s\n", kernel_blob + kernel_cmd_line_offset(pre2));
return retval;
}

View File

@@ -130,7 +130,7 @@ static unsigned int find_cmdline_start(uint8_t *buf_ptr, unsigned int max_len)
}
/* Offset of kernel command line string from the start of the kernel blob */
uint64_t KernelCmdLineOffset(VbKernelPreambleHeader *preamble)
uint64_t kernel_cmd_line_offset(const struct vb2_kernel_preamble *preamble)
{
return preamble->bootloader_address - preamble->body_load_address -
CROS_CONFIG_SIZE - CROS_PARAMS_SIZE;
@@ -628,7 +628,8 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
}
printf("Body verification succeeded.\n");
printf("Config:\n%s\n", kernel_blob + KernelCmdLineOffset(g_preamble));
printf("Config:\n%s\n", kernel_blob + kernel_cmd_line_offset(
(struct vb2_kernel_preamble *)g_preamble));
rv = 0;
done:

View File

@@ -6,6 +6,7 @@
#ifndef VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_
#define VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_
struct vb2_kernel_preamble;
struct vb2_packed_key;
/**
@@ -54,6 +55,6 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
const char *keyblock_outfile,
uint64_t min_version);
uint64_t KernelCmdLineOffset(VbKernelPreambleHeader *preamble);
uint64_t kernel_cmd_line_offset(const struct vb2_kernel_preamble *preamble);
#endif /* VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_ */

View File

@@ -12,6 +12,7 @@
#include "vboot_struct.h"
struct rsa_st;
struct vb2_packed_key;
struct vb2_private_key;
/**
* Returns the SHA1 digest of the packed key data as a string.
@@ -26,8 +27,18 @@ struct vb2_packed_key;
*/
const char *packed_key_sha1_string(const struct vb2_packed_key *key);
/* Prints the sha1sum of a VbPrivateKey to stdout. */
void PrintPrivKeySha1Sum(VbPrivateKey *key);
/**
* Returns the SHA1 digest of the private key data as a string.
*
* The returned string is a global static buffer, so each call to this
* overwrites the previous digest string. So don't call this more than once
* per printf().
*
* @param key Key to print digest for
*
* @return A string containing the SHA1 digest.
*/
const char *private_key_sha1_string(const struct vb2_private_key *key);
/*
* Our packed RSBPublicKey buffer (historically in files ending with ".keyb",

View File

@@ -21,6 +21,7 @@
#include "host_common.h"
#include "util_misc.h"
#include "vb2_common.h"
#include "host_key2.h"
#include "vboot_common.h"
const char *packed_key_sha1_string(const struct vb2_packed_key *key)
@@ -29,10 +30,10 @@ const char *packed_key_sha1_string(const struct vb2_packed_key *key)
uint32_t buflen = key->key_size;
uint8_t digest[VB2_SHA1_DIGEST_SIZE];
static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
char *dnext = dest;
vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
char *dnext = dest;
int i;
for (i = 0; i < sizeof(digest); i++)
dnext += sprintf(dnext, "%02x", digest[i]);
@@ -40,24 +41,27 @@ const char *packed_key_sha1_string(const struct vb2_packed_key *key)
return dest;
}
void PrintPrivKeySha1Sum(VbPrivateKey *key)
const char *private_key_sha1_string(const struct vb2_private_key *key)
{
uint8_t *buf;
uint32_t buflen;
uint8_t digest[VB2_SHA1_DIGEST_SIZE];
int i;
static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
printf("<error>");
return;
if (!key->rsa_private_key ||
vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
return "<error>";
}
vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
char *dnext = dest;
int i;
for (i = 0; i < sizeof(digest); i++)
printf("%02x", digest[i]);
dnext += sprintf(dnext, "%02x", digest[i]);
free(buf);
return dest;
}
int vb_keyb_from_rsa(struct rsa_st *rsa_private_key,

View File

@@ -22,6 +22,14 @@ struct vb2_private_key {
struct vb2_id id; /* Key ID */
};
struct vb2_packed_private_key {
/* Signature algorithm used by the key (enum vb2_crypto_algorithm) */
uint32_t algorithm;
uint32_t reserved2;
/* Key data formatted for d2i_RSAPrivateKey() */
uint8_t key_data[0];
};
/* Convert between enums and human-readable form. Terminated with {0, 0}. */
struct vb2_text_vs_enum {
const char *name;

View File

@@ -425,13 +425,6 @@ static void test_verify_kernel_preamble(const VbPublicKey *public_key,
TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
"vb2_verify_kernel_preamble() minor++");
Memcpy(h, hdr, hsize);
h->header_version_minor--;
resign_kernel_preamble(h, private_key);
TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
VB2_ERROR_PREAMBLE_HEADER_OLD,
"vb2_verify_kernel_preamble() 2.1 not supported");
/* Check signature */
Memcpy(h, hdr, hsize);
h->preamble_signature.sig_offset = hsize;