| Index: src/platform/vboot_reference/vkernel/kernel_image.c
|
| diff --git a/src/platform/vboot_reference/vkernel/kernel_image.c b/src/platform/vboot_reference/vkernel/kernel_image.c
|
| index fc71f35bc0ad972f476ff4f1418ff3930fcb6007..5eeb784f679599b12eba5d2b92099f1466e7c29a 100644
|
| --- a/src/platform/vboot_reference/vkernel/kernel_image.c
|
| +++ b/src/platform/vboot_reference/vkernel/kernel_image.c
|
| @@ -222,8 +222,9 @@ uint8_t* GetKernelPreambleBlob(const KernelImage* image) {
|
| uint8_t* preamble_blob = NULL;
|
| MemcpyState st;
|
|
|
| - preamble_blob = (uint8_t*) Malloc(GetKernelPreambleLen());
|
| - st.remaining_len = GetKernelPreambleLen();
|
| + preamble_blob = (uint8_t*) Malloc(
|
| + GetKernelPreambleLen(image->kernel_sign_algorithm));
|
| + st.remaining_len = GetKernelPreambleLen(image->kernel_sign_algorithm);
|
| st.remaining_buf = preamble_blob;
|
| st.overrun = 0;
|
|
|
| @@ -233,6 +234,8 @@ uint8_t* GetKernelPreambleBlob(const KernelImage* image) {
|
| StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size));
|
| StatefulMemcpy_r(&st, &image->padded_header_size,
|
| FIELD_LEN(padded_header_size));
|
| + StatefulMemcpy_r(&st, image->kernel_signature,
|
| + siglen_map[image->kernel_sign_algorithm]);
|
|
|
| if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */
|
| Free(preamble_blob);
|
| @@ -255,8 +258,8 @@ uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) {
|
| *blob_len = (FIELD_LEN(magic) +
|
| GetKernelHeaderLen(image) +
|
| kernel_key_signature_len +
|
| - GetKernelPreambleLen() +
|
| - 2 * kernel_signature_len +
|
| + GetKernelPreambleLen(image->kernel_sign_algorithm) +
|
| + kernel_signature_len +
|
| image->kernel_len);
|
| kernel_blob = (uint8_t*) Malloc(*blob_len);
|
| st.remaining_len = *blob_len;
|
| @@ -276,13 +279,14 @@ uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) {
|
| StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size));
|
| StatefulMemcpy_r(&st, &image->padded_header_size,
|
| FIELD_LEN(padded_header_size));
|
| - StatefulMemcpy_r(&st, image->preamble_signature, kernel_signature_len);
|
| StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
|
| + StatefulMemcpy_r(&st, image->preamble_signature, kernel_signature_len);
|
| StatefulMemcpy_r(&st, image->kernel_data, image->kernel_len);
|
|
|
| Free(header_blob);
|
|
|
| if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
|
| + debug("GetKernelBlob() failed.\n");
|
| Free(kernel_blob);
|
| return NULL;
|
| }
|
| @@ -371,7 +375,6 @@ int VerifyKernelImage(const RSAPublicKey* firmware_key,
|
| int kernel_signature_size;
|
| int error_code = 0;
|
| DigestContext ctx;
|
| - DigestContext kernel_ctx;
|
| if (!image)
|
| return VERIFY_KERNEL_INVALID_IMAGE;
|
|
|
| @@ -433,6 +436,8 @@ int VerifyKernelImage(const RSAPublicKey* firmware_key,
|
| FIELD_LEN(bootloader_size));
|
| DigestUpdate(&ctx, (uint8_t*) &image->padded_header_size,
|
| FIELD_LEN(padded_header_size));
|
| + DigestUpdate(&ctx, (uint8_t*) image->kernel_signature,
|
| + kernel_signature_size);
|
| preamble_digest = DigestFinal(&ctx);
|
| if (!RSAVerify(kernel_sign_key, image->preamble_signature,
|
| kernel_signature_size, image->kernel_sign_algorithm,
|
| @@ -442,21 +447,14 @@ int VerifyKernelImage(const RSAPublicKey* firmware_key,
|
| }
|
|
|
| /* Verify kernel signature - kernel signature is computed on the contents
|
| - of kernel version + kernel options + kernel_data. */
|
| - DigestInit(&kernel_ctx, image->kernel_sign_algorithm);
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) &image->kernel_version,
|
| - FIELD_LEN(kernel_version));
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) &image->kernel_len,
|
| - FIELD_LEN(kernel_len));
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) &image->bootloader_offset,
|
| - FIELD_LEN(bootloader_offset));
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) &image->bootloader_size,
|
| - FIELD_LEN(bootloader_size));
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) &image->padded_header_size,
|
| - FIELD_LEN(padded_header_size));
|
| - DigestUpdate(&kernel_ctx, (uint8_t*) image->kernel_data,
|
| - image->kernel_len);
|
| - kernel_digest = DigestFinal(&kernel_ctx);
|
| + * of kernel_data.
|
| + * Association between the kernel_data and preamble is maintained by making
|
| + * the kernel signature a part of the preamble and verifying it as part
|
| + * of preamble signature checking. */
|
| +
|
| + kernel_digest = DigestBuf(image->kernel_data,
|
| + image->kernel_len,
|
| + image->kernel_sign_algorithm);
|
| if (!RSAVerify(kernel_sign_key, image->kernel_signature,
|
| kernel_signature_size, image->kernel_sign_algorithm,
|
| kernel_digest)) {
|
| @@ -505,33 +503,17 @@ int AddKernelSignature(KernelImage* image,
|
| uint8_t* preamble_signature = NULL;
|
| uint8_t* kernel_signature = NULL;
|
| uint8_t* kernel_buf;
|
| - int signature_len = siglen_map[image->kernel_sign_algorithm];
|
| + int algorithm = image->kernel_sign_algorithm;
|
| + int signature_len = siglen_map[algorithm];
|
|
|
| - preamble_blob = GetKernelPreambleBlob(image);
|
| - if (!(preamble_signature = SignatureBuf(preamble_blob,
|
| - GetKernelPreambleLen(),
|
| - kernel_signing_key_file,
|
| - image->kernel_sign_algorithm))) {
|
| - debug("Could not compute signature on the kernel preamble.\n");
|
| - Free(preamble_blob);
|
| - return 0;
|
| - }
|
| -
|
| - image->preamble_signature = (uint8_t*) Malloc(signature_len);
|
| - Memcpy(image->preamble_signature, preamble_signature, signature_len);
|
| - Free(preamble_signature);
|
| - /* Kernel signature muse be calculated on the kernel version, options and
|
| - * kernel data to avoid splicing attacks. */
|
| - kernel_buf = (uint8_t*) Malloc(GetKernelPreambleLen() +
|
| - image->kernel_len);
|
| - Memcpy(kernel_buf, preamble_blob, GetKernelPreambleLen());
|
| - Memcpy(kernel_buf + GetKernelPreambleLen(), image->kernel_data,
|
| - image->kernel_len);
|
| + /* Kernel signature must be calculated first as its used for computing the
|
| + * preamble signature. */
|
| + kernel_buf = (uint8_t*) Malloc(image->kernel_len);
|
| + Memcpy(kernel_buf, image->kernel_data, image->kernel_len);
|
| if (!(kernel_signature = SignatureBuf(kernel_buf,
|
| - GetKernelPreambleLen() +
|
| image->kernel_len,
|
| kernel_signing_key_file,
|
| - image->kernel_sign_algorithm))) {
|
| + algorithm))) {
|
| Free(preamble_blob);
|
| Free(kernel_buf);
|
| debug("Could not compute signature on the kernel.\n");
|
| @@ -539,9 +521,24 @@ int AddKernelSignature(KernelImage* image,
|
| }
|
| image->kernel_signature = (uint8_t*) Malloc(signature_len);
|
| Memcpy(image->kernel_signature, kernel_signature, signature_len);
|
| +
|
| +
|
| + preamble_blob = GetKernelPreambleBlob(image);
|
| + if (!(preamble_signature = SignatureBuf(preamble_blob,
|
| + GetKernelPreambleLen(algorithm),
|
| + kernel_signing_key_file,
|
| + algorithm))) {
|
| + debug("Could not compute signature on the kernel preamble.\n");
|
| + Free(preamble_blob);
|
| + return 0;
|
| + }
|
| + image->preamble_signature = (uint8_t*) Malloc(signature_len);
|
| + Memcpy(image->preamble_signature, preamble_signature, signature_len);
|
| +
|
| + Free(preamble_signature);
|
| + Free(preamble_blob);
|
| Free(kernel_signature);
|
| Free(kernel_buf);
|
| - Free(preamble_blob);
|
| return 1;
|
| }
|
|
|
|
|