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,