Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: src/platform/vboot_reference/vkernel/kernel_image.c

Issue 2292001: Make kernel signature a part of the kernel preamble. (Closed) Base URL: ssh://git@gitrw.chromium.org/chromiumos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/vboot_reference/vboot_firmware/linktest/main.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « src/platform/vboot_reference/vboot_firmware/linktest/main.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698