summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2016-06-03 14:00:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-08-03 17:47:13 -0700
commit158b29672a17c1d11e182f0285e0009dd39e5204 (patch)
treed15e4c2e873de2dede00a9cc5cc662b1a7a4c8a0
parent46b77fb2f04941c869c3a98cd17e9209c36b2917 (diff)
downloadvboot-158b29672a17c1d11e182f0285e0009dd39e5204.tar.gz
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>
-rw-r--r--Makefile4
-rw-r--r--firmware/lib20/include/vb2_common.h22
-rw-r--r--firmware/lib20/include/vb2_struct.h4
-rw-r--r--firmware/lib20/kernel.c46
-rw-r--r--futility/cmd_show.c106
-rw-r--r--futility/vb1_helper.c5
-rw-r--r--futility/vb1_helper.h3
-rw-r--r--host/lib/include/util_misc.h15
-rw-r--r--host/lib/util_misc.c18
-rw-r--r--host/lib21/include/host_key2.h8
-rw-r--r--tests/vb20_common3_tests.c7
11 files changed, 151 insertions, 87 deletions
diff --git a/Makefile b/Makefile
index 79c46684..04555427 100644
--- a/Makefile
+++ b/Makefile
@@ -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}
diff --git a/firmware/lib20/include/vb2_common.h b/firmware/lib20/include/vb2_common.h
index 0ab89cab..536fbbb0 100644
--- a/firmware/lib20/include/vb2_common.h
+++ b/firmware/lib20/include/vb2_common.h
@@ -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_ */
diff --git a/firmware/lib20/include/vb2_struct.h b/firmware/lib20/include/vb2_struct.h
index f644a5fa..eeaf0cec 100644
--- a/firmware/lib20/include/vb2_struct.h
+++ b/firmware/lib20/include/vb2_struct.h
@@ -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_ */
diff --git a/firmware/lib20/kernel.c b/firmware/lib20/kernel.c
index 609f2461..4ded5d55 100644
--- a/firmware/lib20/kernel.c
+++ b/firmware/lib20/kernel.c
@@ -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;
+}
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index b2781809..d3cfc7fd 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -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);
+ struct vb2_kernel_preamble *pre2 =
+ (struct vb2_kernel_preamble *)(buf + more);
- if (VBOOT_SUCCESS != VerifyKernelPreamble(preamble,
- len - more, rsa)) {
+ 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);
-
- if (VbGetKernelVmlinuzHeader(preamble,
- &vmlinuz_header_address,
- &vmlinuz_header_size)
- != VBOOT_SUCCESS) {
- fprintf(stderr, "Unable to retrieve Vmlinuz Header!");
- return 1;
- }
+ pre2->bootloader_address);
+ printf(" Bootloader size: 0x%x\n", pre2->bootloader_size);
+
+ 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;
}
diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c
index c4cdda21..13c5f5e6 100644
--- a/futility/vb1_helper.c
+++ b/futility/vb1_helper.c
@@ -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:
diff --git a/futility/vb1_helper.h b/futility/vb1_helper.h
index fbe36184..8f3b5000 100644
--- a/futility/vb1_helper.h
+++ b/futility/vb1_helper.h
@@ -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_ */
diff --git a/host/lib/include/util_misc.h b/host/lib/include/util_misc.h
index 648f2da8..b6372db1 100644
--- a/host/lib/include/util_misc.h
+++ b/host/lib/include/util_misc.h
@@ -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",
diff --git a/host/lib/util_misc.c b/host/lib/util_misc.c
index 2b0f91c8..56d21b38 100644
--- a/host/lib/util_misc.c
+++ b/host/lib/util_misc.c
@@ -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,
diff --git a/host/lib21/include/host_key2.h b/host/lib21/include/host_key2.h
index 7c95ac16..e58b37d7 100644
--- a/host/lib21/include/host_key2.h
+++ b/host/lib21/include/host_key2.h
@@ -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;
diff --git a/tests/vb20_common3_tests.c b/tests/vb20_common3_tests.c
index 0e135bda..95207382 100644
--- a/tests/vb20_common3_tests.c
+++ b/tests/vb20_common3_tests.c
@@ -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;