Add a command line string field to verified boot kernel config image.
Also some cleanup of duplicated code.
BUG=670
TEST=Existing image verification tests still pass.
Review URL: http://codereview.chromium.org/874006
diff --git a/include/kernel_image.h b/include/kernel_image.h
index bcf980f..96c8f25 100644
--- a/include/kernel_image.h
+++ b/include/kernel_image.h
@@ -15,10 +15,13 @@
#define KERNEL_MAGIC "CHROMEOS"
#define KERNEL_MAGIC_SIZE 8
+#define KERNEL_CMD_LINE_SIZE 4096
/* Kernel config file options according to the Chrome OS drive map design. */
typedef struct kconfig_options {
uint32_t version[2]; /* Configuration file version. */
+ uint8_t cmd_line[KERNEL_CMD_LINE_SIZE]; /* Kernel command line option string
+ * terminated by a NULL character. */
uint64_t kernel_len; /* Size of the kernel. */
uint64_t kernel_load_addr; /* Load address in memory for the kernel image */
uint64_t kernel_entry_addr; /* Address to jump to after kernel is loaded. */
diff --git a/tests/firmware_image_tests.c b/tests/firmware_image_tests.c
index 82c4f37..2af267c 100644
--- a/tests/firmware_image_tests.c
+++ b/tests/firmware_image_tests.c
@@ -48,11 +48,7 @@
image->firmware_key_version = firmware_key_version;
/* Update correct header length. */
- image->header_len = (sizeof(image->header_len) +
- sizeof(image->firmware_sign_algorithm) +
- RSAProcessedKeySize(image->firmware_sign_algorithm) +
- sizeof(image->firmware_key_version) +
- sizeof(image->header_checksum));
+ image->header_len = GetFirmwareHeaderLen(image);
/* Calculate SHA-512 digest on header and populate header_checksum. */
DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
diff --git a/tests/kernel_image_tests.c b/tests/kernel_image_tests.c
index a900513..3cf9c4c 100644
--- a/tests/kernel_image_tests.c
+++ b/tests/kernel_image_tests.c
@@ -51,13 +51,7 @@
RSAProcessedKeySize(image->kernel_sign_algorithm));
/* Update correct header length. */
- image->header_len = (sizeof(image->header_version) +
- sizeof(image->header_len) +
- sizeof(image->firmware_sign_algorithm) +
- sizeof(image->kernel_sign_algorithm) +
- RSAProcessedKeySize(image->kernel_sign_algorithm) +
- sizeof(image->kernel_key_version) +
- sizeof(image->header_checksum));
+ image->header_len = GetKernelHeaderLen(image);
/* Calculate SHA-512 digest on header and populate header_checksum. */
DigestInit(&ctx, SHA512_DIGEST_ALGORITHM);
@@ -80,7 +74,8 @@
/* Populate kernel options and data with dummy data. */
image->kernel_version = kernel_version;
image->options.version[0] = 1;
- image->options.version[1] = 1;
+ image->options.version[1] = 0;
+ Memset(image->options.cmd_line, 0, sizeof(image->options.cmd_line));
image->options.kernel_len = kernel_len;
image->options.kernel_load_addr = 0;
image->options.kernel_entry_addr = 0;
diff --git a/utils/firmware_image.c b/utils/firmware_image.c
index cd8e942..e7dcde9 100644
--- a/utils/firmware_image.c
+++ b/utils/firmware_image.c
@@ -87,11 +87,7 @@
signature_len = siglen_map[image->firmware_sign_algorithm];
/* Check whether the header length is correct. */
- header_len = (FIELD_LEN(header_len) +
- FIELD_LEN(firmware_sign_algorithm) +
- firmware_sign_key_len +
- FIELD_LEN(firmware_key_version) +
- FIELD_LEN(header_checksum));
+ header_len = GetFirmwareHeaderLen(image);
if (header_len != image->header_len) {
fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n",
image->header_len, header_len);
@@ -215,7 +211,7 @@
StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
StatefulMemcpy_r(&st, header_blob, GetFirmwareHeaderLen(image));
StatefulMemcpy_r(&st, image->firmware_key_signature,
- FIELD_LEN(firmware_key_signature));
+ FIELD_LEN(firmware_key_signature));
StatefulMemcpy_r(&st, preamble_blob, GetFirmwarePreambleLen(image));
StatefulMemcpy_r(&st, image->preamble_signature, firmware_signature_len);
StatefulMemcpy_r(&st, image->firmware_signature, firmware_signature_len);
@@ -434,9 +430,7 @@
}
/* Only continue if firmware data verification succeeds. */
firmware_ptr = (preamble_ptr +
- FIELD_LEN(firmware_version) +
- FIELD_LEN(firmware_len) +
- FIELD_LEN(preamble) +
+ GetFirmwarePreambleLen(NULL) +
signature_len);
if ((error_code = VerifyFirmwareData(firmware_sign_key, firmware_ptr,
diff --git a/utils/kernel_image.c b/utils/kernel_image.c
index 8201137..a1b943f 100644
--- a/utils/kernel_image.c
+++ b/utils/kernel_image.c
@@ -132,6 +132,7 @@
/* Read the kernel config. */
StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version));
StatefulMemcpy(&st, &image->options.version, FIELD_LEN(options.version));
+ StatefulMemcpy(&st, &image->options.cmd_line, FIELD_LEN(options.cmd_line));
StatefulMemcpy(&st, &image->options.kernel_len,
FIELD_LEN(options.kernel_len));
StatefulMemcpy(&st, &image->options.kernel_load_addr,
@@ -193,7 +194,8 @@
}
int GetKernelConfigLen(const KernelImage* image) {
- return (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
+ return (FIELD_LEN(kernel_version) +
+ FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) +
FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) +
FIELD_LEN(options.kernel_entry_addr));
}
@@ -208,6 +210,7 @@
StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version));
+ StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line));
StatefulMemcpy_r(&st, &image->options.kernel_len,
FIELD_LEN(options.kernel_len));
StatefulMemcpy_r(&st, &image->options.kernel_load_addr,
@@ -314,11 +317,13 @@
/* Print preamble. */
printf("Kernel Version = %d\n"
"Kernel Config Version = %d.%d\n"
+ "Kernel Config command line = %s\n"
"kernel Length = %" PRId64 "\n"
"Kernel Load Address = %" PRId64 "\n"
"Kernel Entry Address = %" PRId64 "\n\n",
image->kernel_version,
image->options.version[0], image->options.version[1],
+ image->options.cmd_line,
image->options.kernel_len,
image->options.kernel_load_addr,
image->options.kernel_entry_addr);
@@ -420,11 +425,7 @@
int algorithm,
int* kernel_len) {
uint32_t len, config_len;
- config_len = (FIELD_LEN(kernel_version) +
- FIELD_LEN(options.version)+
- FIELD_LEN(options.kernel_len) +
- FIELD_LEN(options.kernel_load_addr) +
- FIELD_LEN(options.kernel_entry_addr));
+ config_len = GetKernelConfigLen(NULL);
if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */
config_blob, /* Data to verify */
config_len, /* Length of data */
@@ -432,8 +433,9 @@
algorithm))
return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
- Memcpy(&len, config_blob + (FIELD_LEN(kernel_version)+
- FIELD_LEN(options.version)),
+ Memcpy(&len,
+ config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
+ FIELD_LEN(options.cmd_line)),
sizeof(len));
*kernel_len = (int) len;
return 0;
@@ -506,11 +508,7 @@
}
/* Only continue if kernel data verification succeeds. */
kernel_ptr = (config_ptr +
- FIELD_LEN(kernel_version) +
- FIELD_LEN(options.version) +
- FIELD_LEN(options.kernel_len) +
- FIELD_LEN(options.kernel_entry_addr) +
- FIELD_LEN(options.kernel_load_addr) +
+ GetKernelConfigLen(NULL) + /* Skip config block/signature. */
kernel_signature_len);
if ((error_code = VerifyKernelData(kernel_sign_key, kernel_ptr, kernel_len,
@@ -587,8 +585,10 @@
DigestInit(&ctx, image->kernel_sign_algorithm);
DigestUpdate(&ctx, (uint8_t*) &image->kernel_version,
FIELD_LEN(kernel_version));
- DigestUpdate(&ctx, (uint8_t*) &image->options.version,
+ DigestUpdate(&ctx, (uint8_t*) image->options.version,
FIELD_LEN(options.version));
+ DigestUpdate(&ctx, (uint8_t*) image->options.cmd_line,
+ FIELD_LEN(options.cmd_line));
DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_len,
FIELD_LEN(options.kernel_len));
DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_load_addr,