summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/include/vboot_struct.h10
-rw-r--r--firmware/lib/include/vboot_common.h11
-rw-r--r--firmware/lib/vboot_common.c19
-rw-r--r--futility/cmd_show.c5
-rw-r--r--futility/cmd_sign.c14
-rw-r--r--futility/cmd_vbutil_kernel.c19
-rw-r--r--futility/vb1_helper.c13
-rw-r--r--futility/vb1_helper.h2
-rw-r--r--host/lib/host_common.c2
-rw-r--r--host/lib/include/host_common.h1
-rw-r--r--host/linktest/main.c2
-rw-r--r--tests/vboot_common2_tests.c2
-rw-r--r--tests/vboot_common_tests.c2
13 files changed, 89 insertions, 13 deletions
diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h
index 9e845ef8..09abf138 100644
--- a/firmware/include/vboot_struct.h
+++ b/firmware/include/vboot_struct.h
@@ -180,7 +180,7 @@ typedef struct VbFirmwarePreambleHeader {
/****************************************************************************/
#define KERNEL_PREAMBLE_HEADER_VERSION_MAJOR 2
-#define KERNEL_PREAMBLE_HEADER_VERSION_MINOR 1
+#define KERNEL_PREAMBLE_HEADER_VERSION_MINOR 2
/* Preamble block for kernel, version 2.0
*
@@ -260,9 +260,17 @@ typedef struct VbKernelPreambleHeader {
/* Size of 16-bit header for vmlinuz in bytes. Readers should return 0
for header version < 2.1 */
uint64_t vmlinuz_header_size;
+ /*
+ * Flags passed in by the signer. Readers should return 0 for header
+ * version < 2.2. Flags field is currently defined as:
+ * [31:2] - Reserved (for future use)
+ * [1:0] - Kernel image type (0b00 - CrOS, 0b01 - bootimg)
+ */
+ uint32_t flags;
} __attribute__((packed)) VbKernelPreambleHeader;
#define EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE 112
+#define EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE 116
/****************************************************************************/
diff --git a/firmware/lib/include/vboot_common.h b/firmware/lib/include/vboot_common.h
index f792d1a2..4d50ff62 100644
--- a/firmware/lib/include/vboot_common.h
+++ b/firmware/lib/include/vboot_common.h
@@ -41,6 +41,8 @@ enum {
VBOOT_PREAMBLE_SIGNATURE,
/* Shared data is invalid. */
VBOOT_SHARED_DATA_INVALID,
+ /* Kernel Preamble does not contain flags */
+ VBOOT_KERNEL_PREAMBLE_NO_FLAGS,
VBOOT_ERROR_MAX,
};
extern const char *kVbootErrors[VBOOT_ERROR_MAX];
@@ -161,6 +163,15 @@ int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble,
uint64_t *vmlinuz_header_size);
/**
+ * Checks if the kernel preamble has flags field. This is available only if the
+ * Kernel Preamble Header version >=2.2. If give a header of 2.1 or lower, it
+ * will return VBOOT_KERNEL_PREAMBLE_NO_FLAGS.
+ *
+ * Returns VBOOT_SUCCESS if version is >=2.2.
+ */
+int VbKernelHasFlags(const VbKernelPreambleHeader *preamble);
+
+/**
* Verify that the Vmlinuz Header is contained inside of the kernel blob.
*
* Returns VBOOT_SUCCESS or VBOOT_PREAMBLE_INVALID on error
diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c
index 2cb01f37..226cdb7b 100644
--- a/firmware/lib/vboot_common.c
+++ b/firmware/lib/vboot_common.c
@@ -437,13 +437,20 @@ int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
/*
* If the preamble header version is at least 2.1, verify we have space
- * for the added fields from 2.1.
+ * for the added fields from >2.1.
*/
if (preamble->header_version_minor >= 1) {
- if(size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE) {
+ if((preamble->header_version_minor == 1) &&
+ (size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE)) {
VBDEBUG(("Not enough data for preamble header 2.1.\n"));
return VBOOT_PREAMBLE_INVALID;
}
+
+ if((preamble->header_version_minor == 2) &&
+ (size < EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE)) {
+ VBDEBUG(("Not enough data for preamble header 2.2.\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
}
/* Success */
@@ -469,6 +476,14 @@ int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble,
return VBOOT_SUCCESS;
}
+int VbKernelHasFlags(const VbKernelPreambleHeader *preamble)
+{
+ if (preamble->header_version_minor > 1)
+ return VBOOT_SUCCESS;
+
+ return VBOOT_KERNEL_PREAMBLE_NO_FLAGS;
+}
+
int VerifyVmlinuzInsideKBlob(uint64_t kblob, uint64_t kblob_size,
uint64_t header, uint64_t header_size)
{
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index dc7c8141..b6c2574a 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -419,6 +419,7 @@ int futil_cb_show_kernel_preamble(struct futil_traverse_state_s *state)
int retval = 0;
uint64_t vmlinuz_header_size = 0;
uint64_t vmlinuz_header_address = 0;
+ uint32_t flags = 0;
/* Check the hash... */
if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) {
@@ -483,6 +484,10 @@ int futil_cb_show_kernel_preamble(struct futil_traverse_state_s *state)
vmlinuz_header_size);
}
+ if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS)
+ flags = preamble->flags;
+ printf(" Flags: 0x%" PRIx32 "\n", flags);
+
/* Verify kernel body */
if (option.fv) {
/* It's in a separate file, which we've already read in */
diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c
index a960abd6..2d247bcd 100644
--- a/futility/cmd_sign.c
+++ b/futility/cmd_sign.c
@@ -219,7 +219,7 @@ int futil_cb_create_kernel_part(struct futil_traverse_state_s *state)
vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
option.version, option.kloadaddr,
option.keyblock, option.signprivate,
- &vblock_size);
+ option.flags, &vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
free(kblob_data);
@@ -288,6 +288,12 @@ int futil_cb_resign_kernel_part(struct futil_traverse_state_s *state)
if (!option.version_specified)
option.version = preamble->kernel_version;
+ /* Preserve the flags if not specified */
+ if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS) {
+ if (option.flags_specified == 0)
+ option.flags = preamble->flags;
+ }
+
/* Replace the keyblock if asked */
if (option.keyblock)
keyblock = option.keyblock;
@@ -296,7 +302,7 @@ int futil_cb_resign_kernel_part(struct futil_traverse_state_s *state)
vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
option.version, option.kloadaddr,
keyblock, option.signprivate,
- &vblock_size);
+ option.flags, &vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
return 1;
@@ -612,7 +618,8 @@ static const char usage_new_kpart[] = "\n"
" --pad NUM The vblock padding size in bytes\n"
" (default 0x%x)\n"
" --vblockonly Emit just the vblock (requires a\n"
- " distinct outfile)\n";
+ " distinct outfile)\n"
+ " -f|--flags NUM The preamble flags value\n";
static const char usage_old_kpart[] = "\n"
"-----------------------------------------------------------------\n"
@@ -634,6 +641,7 @@ static const char usage_old_kpart[] = "\n"
" [--outfile] OUTFILE Output kernel partition or vblock\n"
" --vblockonly Emit just the vblock (requires a\n"
" distinct OUTFILE)\n"
+ " -f|--flags NUM The preamble flags value\n"
"\n";
static void print_help(const char *prog)
diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c
index ae4fd3f9..3322e4b8 100644
--- a/futility/cmd_vbutil_kernel.c
+++ b/futility/cmd_vbutil_kernel.c
@@ -63,6 +63,7 @@ enum {
OPT_VERBOSE,
OPT_MINVERSION,
OPT_VMLINUZ_OUT,
+ OPT_FLAGS,
};
static const struct option long_opts[] = {
@@ -86,6 +87,7 @@ static const struct option long_opts[] = {
{"verbose", 0, &opt_verbose, 1},
{"debug", 0, &debugging_enabled, 1},
{"vmlinuz-out", 1, 0, OPT_VMLINUZ_OUT},
+ {"flags", 1, 0, OPT_FLAGS},
{NULL, 0, 0, 0}
};
@@ -109,6 +111,7 @@ static const char usage[] =
" --kloadaddr <address> Assign kernel body load address\n"
" --pad <number> Verification padding size in bytes\n"
" --vblockonly Emit just the verification blob\n"
+ " --flags NUM Flags to be passed in the header\n"
"\nOR\n\n"
"Usage: " MYNAME " %s --repack <file> [PARAMETERS]\n"
"\n"
@@ -253,6 +256,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
uint64_t kblob_size = 0;
uint8_t *vblock_data = NULL;
uint64_t vblock_size = 0;
+ uint32_t flags = 0;
FILE *f;
while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) &&
@@ -328,6 +332,14 @@ static int do_vbutil_kernel(int argc, char *argv[])
vmlinuz_file = optarg;
break;
+ case OPT_FLAGS:
+ flags = (uint32_t)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e)) {
+ fprintf(stderr, "Invalid --flags\n");
+ parse_error = 1;
+ }
+ break;
+
case OPT_BOOTLOADER:
bootloader_file = optarg;
break;
@@ -435,7 +447,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
vblock_data = SignKernelBlob(kblob_data, kblob_size, opt_pad,
version, kernel_body_load_address,
- t_keyblock, signpriv_key,
+ t_keyblock, signpriv_key, flags,
&vblock_size);
if (!vblock_data)
Fatal("Unable to sign kernel blob\n");
@@ -498,6 +510,9 @@ static int do_vbutil_kernel(int argc, char *argv[])
if (!version_str)
version = preamble->kernel_version;
+ if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS)
+ flags = preamble->flags;
+
if (keyblock_file) {
t_keyblock =
(VbKeyBlockHeader *)ReadFile(keyblock_file, 0);
@@ -509,7 +524,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
vblock_data = SignKernelBlob(kblob_data, kblob_size, opt_pad,
version, kernel_body_load_address,
t_keyblock ? t_keyblock : keyblock,
- signpriv_key, &vblock_size);
+ signpriv_key, flags, &vblock_size);
if (!vblock_data)
Fatal("Unable to sign kernel blob\n");
diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c
index f40b7ac8..3d3225a1 100644
--- a/futility/vb1_helper.c
+++ b/futility/vb1_helper.c
@@ -305,6 +305,7 @@ uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size,
uint64_t vmlinuz_header_size = 0;
uint64_t vmlinuz_header_address = 0;
uint64_t now = 0;
+ uint32_t flags = 0;
/* Sanity-check the keyblock */
keyblock = (VbKeyBlockHeader *)kpart_data;
@@ -347,6 +348,11 @@ uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size,
Debug(" bootloader_size = 0x%" PRIx64 "\n", preamble->bootloader_size);
Debug(" kern_blob_size = 0x%" PRIx64 "\n",
preamble->body_signature.data_size);
+
+ if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS)
+ flags = preamble->flags;
+ Debug(" flags = 0x%" PRIx32 "\n", flags);
+
g_preamble = preamble;
g_ondisk_bootloader_addr = g_preamble->bootloader_address;
@@ -392,7 +398,7 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
uint64_t padding,
int version, uint64_t kernel_body_load_address,
VbKeyBlockHeader *keyblock, VbPrivateKey *signpriv_key,
- uint64_t *vblock_size_ptr)
+ uint32_t flags, uint64_t *vblock_size_ptr)
{
VbSignature *body_sig;
VbKernelPreambleHeader *preamble;
@@ -416,6 +422,7 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
body_sig,
g_ondisk_vmlinuz_header_addr,
g_vmlinuz_header_size,
+ flags,
min_size,
signpriv_key);
if (!preamble) {
@@ -591,6 +598,10 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
vmlinuz_header_size);
}
+ if (VbKernelHasFlags(g_preamble) == VBOOT_SUCCESS)
+ printf(" Flags : 0x%" PRIx32 "\n",
+ g_preamble->flags);
+
if (g_preamble->kernel_version < (min_version & 0xFFFF)) {
fprintf(stderr,
"Kernel version %" PRIu64 " is lower than minimum %"
diff --git a/futility/vb1_helper.h b/futility/vb1_helper.h
index fd976e0e..2cf71f4e 100644
--- a/futility/vb1_helper.h
+++ b/futility/vb1_helper.h
@@ -18,7 +18,7 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
uint64_t padding,
int version, uint64_t kernel_body_load_address,
VbKeyBlockHeader *keyblock, VbPrivateKey *signpriv_key,
- uint64_t *vblock_size_ptr);
+ uint32_t flags, uint64_t *vblock_size_ptr);
int WriteSomeParts(const char *outfile,
void *part1_data, uint64_t part1_size,
diff --git a/host/lib/host_common.c b/host/lib/host_common.c
index b9c00cde..959b65a6 100644
--- a/host/lib/host_common.c
+++ b/host/lib/host_common.c
@@ -78,6 +78,7 @@ VbKernelPreambleHeader *CreateKernelPreamble(
const VbSignature *body_signature,
uint64_t vmlinuz_header_address,
uint64_t vmlinuz_header_size,
+ uint32_t flags,
uint64_t desired_size,
const VbPrivateKey *signing_key)
{
@@ -111,6 +112,7 @@ VbKernelPreambleHeader *CreateKernelPreamble(
h->bootloader_size = bootloader_size;
h->vmlinuz_header_address = vmlinuz_header_address;
h->vmlinuz_header_size = vmlinuz_header_size;
+ h->flags = flags;
/* Copy body signature */
SignatureInit(&h->body_signature, body_sig_dest,
diff --git a/host/lib/include/host_common.h b/host/lib/include/host_common.h
index b4693f84..895a675f 100644
--- a/host/lib/include/host_common.h
+++ b/host/lib/include/host_common.h
@@ -52,6 +52,7 @@ VbKernelPreambleHeader *CreateKernelPreamble(
const VbSignature *body_signature,
uint64_t vmlinuz_header_address,
uint64_t vmlinuz_header_size,
+ uint32_t flags,
uint64_t desired_size,
const VbPrivateKey *signing_key);
diff --git a/host/linktest/main.c b/host/linktest/main.c
index e24d5579..8e1525fa 100644
--- a/host/linktest/main.c
+++ b/host/linktest/main.c
@@ -41,7 +41,7 @@ int main(void)
/* host_common.h */
CreateFirmwarePreamble(0, 0, 0, 0, 0);
- CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
/* file_keys.h */
BufferFromFile(0, 0);
diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c
index 3a2b59f3..40953117 100644
--- a/tests/vboot_common2_tests.c
+++ b/tests/vboot_common2_tests.c
@@ -128,7 +128,7 @@ static void VerifyKernelPreambleTest(const VbPublicKey *public_key,
rsa = PublicKeyToRSA(public_key);
hdr = CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000, body_sig,
- 0, 0, 0, private_key);
+ 0, 0, 0, 0, private_key);
TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble() prerequisites");
if (!hdr)
return;
diff --git a/tests/vboot_common_tests.c b/tests/vboot_common_tests.c
index 8fd021a1..3c303a6c 100644
--- a/tests/vboot_common_tests.c
+++ b/tests/vboot_common_tests.c
@@ -31,7 +31,7 @@ static void StructPackingTest(void)
TEST_EQ(EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE,
sizeof(VbFirmwarePreambleHeader),
"sizeof(VbFirmwarePreambleHeader)");
- TEST_EQ(EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE,
+ TEST_EQ(EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE,
sizeof(VbKernelPreambleHeader),
"sizeof(VbKernelPreambleHeader)");