From 4f393869029cae57aeaab0ee093c7c69b8b649a2 Mon Sep 17 00:00:00 2001 From: Gaurav Shah Date: Fri, 12 Mar 2010 18:13:24 -0800 Subject: [PATCH] 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 --- include/kernel_image.h | 3 +++ tests/firmware_image_tests.c | 6 +----- tests/kernel_image_tests.c | 11 +++-------- utils/firmware_image.c | 12 +++--------- utils/kernel_image.c | 28 ++++++++++++++-------------- 5 files changed, 24 insertions(+), 36 deletions(-) diff --git a/include/kernel_image.h b/include/kernel_image.h index bcf980f40d..96c8f25696 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 82c4f37d49..2af267cb72 100644 --- a/tests/firmware_image_tests.c +++ b/tests/firmware_image_tests.c @@ -48,11 +48,7 @@ FirmwareImage* GenerateTestFirmwareImage(int algorithm, 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 a900513565..3cf9c4ce0c 100644 --- a/tests/kernel_image_tests.c +++ b/tests/kernel_image_tests.c @@ -51,13 +51,7 @@ KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, 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 @@ KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, /* 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 cd8e942dda..e7dcde93eb 100644 --- a/utils/firmware_image.c +++ b/utils/firmware_image.c @@ -87,11 +87,7 @@ FirmwareImage* ReadFirmwareImage(const char* input_file) { 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 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { 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 @@ int VerifyFirmware(const uint8_t* root_key_blob, } /* 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 8201137a4f..a1b943f83a 100644 --- a/utils/kernel_image.c +++ b/utils/kernel_image.c @@ -132,6 +132,7 @@ KernelImage* ReadKernelImage(const char* input_file) { /* 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 @@ uint8_t* GetKernelHeaderBlob(const KernelImage* image) { } 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 @@ uint8_t* GetKernelConfigBlob(const KernelImage* image) { 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 @@ void PrintKernelImage(const KernelImage* image) { /* 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 VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 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 @@ int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 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 @@ int VerifyKernel(const uint8_t* firmware_key_blob, } /* 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 @@ int VerifyKernelImage(const RSAPublicKey* firmware_key, 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,