Vboot Reference: Refactor Code.
This CL does the following:
1) It adds a SignatureBuf function which uses the OpenSSL library to generate RSA signature. This is more robust than the previous way of invoking the command line "openssl" utility and capturing its output. No more unnecessary temporary files for signature operations.
2) It adds functions that allow direct manipulation of binary verified Firmware and Kernel Image blobs in memory.
3) It changes the structure field members for FirmwareImage to make it consistent with KernelImage. Now it's clearer which key is used when.
4) Minor bug fixes and slightly improved API for dealing verified boot firmware and kernel images.
5) Renames the RSA_verify function to prevent conflicts with OpenSSL since it's linked into the firmware utility binary.
Review URL: http://codereview.chromium.org/661353
diff --git a/utils/Makefile b/utils/Makefile
index d0f8ea5..14158fd 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -8,26 +8,25 @@
INCLUDES ?= -I../include/
TOP ?= ../
-LIBS = -lcrypto
+LIBS = firmware_image.o kernel_image.o signature_digest.o file_keys.o
FIRMWARELIBS = $(TOP)/crypto/libcrypto.a $(TOP)/common/libcommon.a
-all: dumpRSAPublicKey verify_data signature_digest firmware_utility \
- file_keys.o firmware_image.o kernel_image.o
+all: dumpRSAPublicKey verify_data file_keys.o signature_digest.o firmware_image.o \
+ kernel_image.o signature_digest.o firmware_utility
dumpRSAPublicKey: dumpRSAPublicKey.c
- $(CC) $(CFLAGS) $(LIBS) $< -o $@
+ $(CC) $(CFLAGS) $< -o $@ -lcrypto
-verify_data: verify_data.c file_keys.c
- $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(FIRMWARELIBS)
+verify_data: verify_data.c $(LIBS) $(FIRMWARELIBS)
+ $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) $(FIRMWARELIBS) -lcrypto
-signature_digest: signature_digest.c
- $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(FIRMWARELIBS)
+firmware_utility: firmware_utility.cc $(LIBS) $(FIRMWARELIBS)
+ $(CXX) $(CFLAGS) $(INCLUDES) -ggdb -D__STDC_LIMIT_MACROS $< \
+ -o $@ $(FIRMWARELIBS) $(LIBS) -lcrypto
-firmware_utility: firmware_utility.cc firmware_image.o file_keys.o
- $(CXX) $(CFLAGS) $(INCLUDES) -ggdb -D__STDC_LIMIT_MACROS $^ \
- -o $@ $(FIRMWARELIBS)
+signature_digest.o: signature_digest.c
+ $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
-# Used by tests.
file_keys.o: file_keys.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
@@ -37,6 +36,5 @@
kernel_image.o: kernel_image.c
$(CC) $(CFLAGS) -ansi $(INCLUDES) -c $< -o $@
clean:
- rm -f dumpRSAPublicKey verify_data signature_digest firmware_image.o \
- kernel_image.o file_keys.o firmware_utility
-
+ rm -f dumpRSAPublicKey verify_data signature_digest firmware_utility \
+ $(LIBS)
diff --git a/utils/file_keys.c b/utils/file_keys.c
index 98e878a..4eafd52 100644
--- a/utils/file_keys.c
+++ b/utils/file_keys.c
@@ -17,6 +17,7 @@
#include "padding.h"
#include "rsa_utility.h"
+#include "signature_digest.h"
#include "utility.h"
uint8_t* BufferFromFile(const char* input_file, uint32_t* len) {
diff --git a/utils/firmware_image.c b/utils/firmware_image.c
index d5b0549..0aa44f1 100644
--- a/utils/firmware_image.c
+++ b/utils/firmware_image.c
@@ -18,6 +18,7 @@
#include "padding.h"
#include "rsa_utility.h"
#include "sha_utility.h"
+#include "signature_digest.h"
#include "utility.h"
/* Macro to determine the size of a field structure in the FirmwareImage
@@ -27,7 +28,7 @@
FirmwareImage* FirmwareImageNew(void) {
FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
if (image) {
- image->sign_key = NULL;
+ image->firmware_sign_key = NULL;
image->preamble_signature = NULL;
image->firmware_signature = NULL;
image->firmware_data = NULL;
@@ -37,10 +38,11 @@
void FirmwareImageFree(FirmwareImage* image) {
if (image) {
- Free(image->sign_key);
+ Free(image->firmware_sign_key);
Free(image->preamble_signature);
Free(image->firmware_signature);
Free(image->firmware_data);
+ Free(image);
}
}
@@ -48,7 +50,7 @@
uint32_t file_size;
int image_len = 0; /* Total size of the firmware image. */
int header_len = 0;
- int sign_key_len;
+ int firmware_sign_key_len;
int signature_len;
uint8_t* firmware_buf;
MemcpyState st;
@@ -64,46 +66,49 @@
st.remaining_buf = firmware_buf;
/* Read and compare magic bytes. */
- if (!StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE))
- goto parse_failure;
-
+ StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE);
if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) {
fprintf(stderr, "Wrong Firmware Magic.\n");
- goto parse_failure;
+ Free(firmware_buf);
+ return NULL;
}
-
StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
- StatefulMemcpy(&st, &image->sign_algorithm, FIELD_LEN(sign_algorithm));
+ StatefulMemcpy(&st, &image->firmware_sign_algorithm,
+ FIELD_LEN(firmware_sign_algorithm));
/* Valid Algorithm? */
- if (image->sign_algorithm >= kNumAlgorithms)
- goto parse_failure;
+ if (image->firmware_sign_algorithm >= kNumAlgorithms) {
+ Free(firmware_buf);
+ return NULL;
+ }
/* Compute size of pre-processed RSA public key and signature. */
- sign_key_len = RSAProcessedKeySize(image->sign_algorithm);
- signature_len = siglen_map[image->sign_algorithm];
-
+ firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm);
+ signature_len = siglen_map[image->firmware_sign_algorithm];
/* Check whether the header length is correct. */
header_len = (FIELD_LEN(header_len) +
- FIELD_LEN(sign_algorithm) +
- sign_key_len +
- FIELD_LEN(key_version) +
+ FIELD_LEN(firmware_sign_algorithm) +
+ firmware_sign_key_len +
+ FIELD_LEN(firmware_key_version) +
FIELD_LEN(header_checksum));
if (header_len != image->header_len) {
fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n",
image->header_len, header_len);
- goto parse_failure;
+ Free(firmware_buf);
+ return NULL;
}
/* Read pre-processed public half of the sign key. */
- image->sign_key = (uint8_t*) Malloc(sign_key_len);
- StatefulMemcpy(&st, image->sign_key, sign_key_len);
- StatefulMemcpy(&st, &image->key_version, FIELD_LEN(key_version));
+ image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len);
+ StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len);
+ StatefulMemcpy(&st, &image->firmware_key_version,
+ FIELD_LEN(firmware_key_version));
StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
/* Read key signature. */
- StatefulMemcpy(&st, image->key_signature, FIELD_LEN(key_signature));
+ StatefulMemcpy(&st, image->firmware_key_signature,
+ FIELD_LEN(firmware_key_signature));
/* Read the firmware preamble. */
StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version));
@@ -120,62 +125,141 @@
image->firmware_data = (uint8_t*) Malloc(image->firmware_len);
StatefulMemcpy(&st, image->firmware_data, image->firmware_len);
- if(st.remaining_len != 0) /* Overrun or underrun. */
- goto parse_failure;
-
- Free(firmware_buf);
- return image;
-
-parse_failure:
- Free(firmware_buf);
- return NULL;
-}
-
-void WriteFirmwareHeader(int fd, FirmwareImage* image) {
- int sign_key_len;
- write(fd, &image->header_len, FIELD_LEN(header_len));
- write(fd, &image->sign_algorithm, FIELD_LEN(header_len));
- sign_key_len = (image->header_len - FIELD_LEN(header_len) -
- FIELD_LEN(sign_algorithm) -
- FIELD_LEN(key_version) -
- FIELD_LEN(header_checksum));
- write(fd, image->sign_key, sign_key_len);
- write(fd, &image->key_version, FIELD_LEN(key_version));
- write(fd, &image->header_checksum, FIELD_LEN(header_checksum));
-}
-
-void WriteFirmwarePreamble(int fd, FirmwareImage* image) {
- write(fd, &image->firmware_version,
- FIELD_LEN(firmware_version));
- write(fd, &image->firmware_len, FIELD_LEN(firmware_len));
- write(fd, image->preamble, FIELD_LEN(preamble));
-}
-
-FirmwareImage* WriteFirmwareImage(const char* input_file,
- FirmwareImage* image) {
- int fd;
- int signature_len;
-
- if (!image)
- return NULL;
- if (-1 == (fd = creat(input_file, S_IRWXU))) {
- fprintf(stderr, "Couldn't open file for writing.\n");
+ if(st.remaining_len != 0) { /* Overrun or underrun. */
+ Free(firmware_buf);
return NULL;
}
- write(fd, image->magic, FIELD_LEN(magic));
- WriteFirmwareHeader(fd, image);
- write(fd, image->key_signature, FIELD_LEN(key_signature));
- signature_len = siglen_map[image->sign_algorithm];
- WriteFirmwarePreamble(fd, image);
- write(fd, image->preamble_signature, signature_len);
- write(fd, image->firmware_signature, signature_len);
- write(fd, image->firmware_data, image->firmware_len);
-
- close(fd);
+ Free(firmware_buf);
return image;
}
+int GetFirmwareHeaderLen(const FirmwareImage* image) {
+ return (FIELD_LEN(header_len) + FIELD_LEN(header_len) +
+ RSAProcessedKeySize(image->firmware_sign_algorithm) +
+ FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum));
+}
+
+uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) {
+ uint8_t* header_blob = NULL;
+ MemcpyState st;
+
+ header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image));
+ st.remaining_len = GetFirmwareHeaderLen(image);
+ st.remaining_buf = header_blob;
+
+ StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len));
+ StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len));
+ StatefulMemcpy_r(&st, image->firmware_sign_key,
+ RSAProcessedKeySize(image->firmware_sign_algorithm));
+ StatefulMemcpy_r(&st, &image->firmware_key_version,
+ FIELD_LEN(firmware_key_version));
+ StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
+
+ if (st.remaining_len != 0) { /* Underrun or Overrun. */
+ Free(header_blob);
+ return NULL;
+ }
+ return header_blob;
+}
+
+int GetFirmwarePreambleLen(const FirmwareImage* image) {
+ return (FIELD_LEN(firmware_version) + FIELD_LEN(firmware_len) +
+ FIELD_LEN(preamble));
+}
+
+uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) {
+ uint8_t* preamble_blob = NULL;
+ MemcpyState st;
+
+ preamble_blob = (uint8_t*) Malloc(GetFirmwarePreambleLen(image));
+ st.remaining_len = GetFirmwarePreambleLen(image);
+ st.remaining_buf = preamble_blob;
+
+ StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version));
+ StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len));
+ StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble));
+
+ if (st.remaining_len != 0 ) { /* Underrun or Overrun. */
+ Free(preamble_blob);
+ return NULL;
+ }
+ return preamble_blob;
+}
+
+
+uint8_t* GetFirmwareBlob(const FirmwareImage* image, int* blob_len) {
+ int firmware_signature_len;
+ uint8_t* firmware_blob = NULL;
+ uint8_t* header_blob = NULL;
+ uint8_t* preamble_blob = NULL;
+ MemcpyState st;
+
+ if (!image)
+ return NULL;
+
+ firmware_signature_len = siglen_map[image->firmware_sign_algorithm];
+ *blob_len = (FIELD_LEN(magic) +
+ GetFirmwareHeaderLen(image) +
+ FIELD_LEN(firmware_key_signature) +
+ GetFirmwarePreambleLen(image) +
+ 2 * firmware_signature_len +
+ image->firmware_len);
+ firmware_blob = (uint8_t*) Malloc(*blob_len);
+ st.remaining_len = *blob_len;
+ st.remaining_buf = firmware_blob;
+
+ header_blob = GetFirmwareHeaderBlob(image);
+ preamble_blob = GetFirmwarePreambleBlob(image);
+
+ 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));
+ 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);
+ StatefulMemcpy_r(&st, image->firmware_data, image->firmware_len);
+
+ Free(preamble_blob);
+ Free(header_blob);
+
+ if (st.remaining_len != 0) { /* Underrun or Overrun. */
+ Free(firmware_blob);
+ return NULL;
+ }
+ return firmware_blob;
+}
+
+int WriteFirmwareImage(const char* input_file,
+ const FirmwareImage* image) {
+ int fd;
+ uint8_t* firmware_blob;
+ int blob_len;
+
+ if (!image)
+ return 0;
+ if (-1 == (fd = creat(input_file, S_IRWXU))) {
+ fprintf(stderr, "Couldn't open file for writing.\n");
+ return 0;
+ }
+
+ firmware_blob = GetFirmwareBlob(image, &blob_len);
+ if (!firmware_blob) {
+ fprintf(stderr, "Couldn't create firmware blob from FirmwareImage.\n");
+ return 0;
+ }
+ if (blob_len != write(fd, firmware_blob, blob_len)) {
+ fprintf(stderr, "Couldn't write Firmware Image to file: %s\n", input_file);
+ Free(firmware_blob);
+ close(fd);
+ return 0;
+ }
+ Free(firmware_blob);
+ close(fd);
+ return 1;
+}
+
void PrintFirmwareImage(const FirmwareImage* image) {
if (!image)
return;
@@ -186,9 +270,9 @@
"Signature Algorithm = %s\n"
"Key Version = %d\n\n",
image->header_len,
- image->sign_algorithm,
- algo_strings[image->sign_algorithm],
- image->key_version);
+ image->firmware_sign_algorithm,
+ algo_strings[image->firmware_sign_algorithm],
+ image->firmware_key_version);
/* TODO(gauravsh): Output hash and key signature here? */
/* Print preamble. */
printf("Firmware Version = %d\n"
@@ -213,31 +297,31 @@
const int dev_mode,
int* algorithm,
int* header_len) {
- int sign_key_len;
+ int firmware_sign_key_len;
int root_key_len;
uint16_t hlen, algo;
uint8_t* header_checksum = NULL;
/* Base Offset for the header_checksum field. Actual offset is
- * this + sign_key_len. */
+ * this + firmware_sign_key_len. */
int base_header_checksum_offset = (FIELD_LEN(header_len) +
- FIELD_LEN(sign_algorithm) +
- FIELD_LEN(key_version));
+ FIELD_LEN(firmware_sign_algorithm) +
+ FIELD_LEN(firmware_key_version));
root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM);
Memcpy(&hlen, header_blob, sizeof(hlen));
Memcpy(&algo,
- header_blob + FIELD_LEN(sign_algorithm),
+ header_blob + FIELD_LEN(firmware_sign_algorithm),
sizeof(algo));
if (algo >= kNumAlgorithms)
return VERIFY_FIRMWARE_INVALID_ALGORITHM;
*algorithm = (int) algo;
- sign_key_len = RSAProcessedKeySize(*algorithm);
+ firmware_sign_key_len = RSAProcessedKeySize(*algorithm);
/* Verify if header len is correct? */
if (hlen != (base_header_checksum_offset +
- sign_key_len +
+ firmware_sign_key_len +
FIELD_LEN(header_checksum)))
return VERIFY_FIRMWARE_INVALID_IMAGE;
@@ -248,7 +332,8 @@
*header_len - FIELD_LEN(header_checksum),
SHA512_DIGEST_ALGORITHM);
if (SafeMemcmp(header_checksum,
- header_blob + (base_header_checksum_offset + sign_key_len),
+ header_blob + (base_header_checksum_offset +
+ firmware_sign_key_len),
FIELD_LEN(header_checksum))) {
Free(header_checksum);
return VERIFY_FIRMWARE_INVALID_IMAGE;
@@ -267,7 +352,7 @@
return 0;
}
-int VerifyFirmwarePreamble(RSAPublicKey* sign_key,
+int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key,
const uint8_t* preamble_blob,
int algorithm,
int* firmware_len) {
@@ -276,7 +361,7 @@
preamble_len = (FIELD_LEN(firmware_version) +
FIELD_LEN(firmware_len) +
FIELD_LEN(preamble));
- if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use */
+ if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */
preamble_blob, /* Data to verify */
preamble_len, /* Length of data */
preamble_blob + preamble_len, /* Expected Signature */
@@ -289,12 +374,12 @@
return 0;
}
-int VerifyFirmwareData(RSAPublicKey* sign_key,
+int VerifyFirmwareData(RSAPublicKey* firmware_sign_key,
const uint8_t* firmware_data_start,
int firmware_len,
int algorithm) {
int signature_len = siglen_map[algorithm];
- if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use. */
+ if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use. */
firmware_data_start + signature_len, /* Data to
* verify */
firmware_len, /* Length of data. */
@@ -309,10 +394,10 @@
const int dev_mode) {
int error_code;
int algorithm; /* Signing key algorithm. */
- RSAPublicKey* sign_key;
- int sign_key_len, signature_len, header_len, firmware_len;
+ RSAPublicKey* firmware_sign_key;
+ int firmware_sign_key_len, signature_len, header_len, firmware_len;
const uint8_t* header_ptr; /* Pointer to header. */
- const uint8_t* sign_key_ptr; /* Pointer to signing key. */
+ const uint8_t* firmware_sign_key_ptr; /* Pointer to signing key. */
const uint8_t* preamble_ptr; /* Pointer to preamble block. */
const uint8_t* firmware_ptr; /* Pointer to firmware signature/data. */
@@ -331,16 +416,18 @@
/* Parse signing key into RSAPublicKey structure since it is required multiple
* times. */
- sign_key_len = RSAProcessedKeySize(algorithm);
- sign_key_ptr = header_ptr + (FIELD_LEN(header_len) +
- FIELD_LEN(sign_algorithm));
- sign_key = RSAPublicKeyFromBuf(sign_key_ptr, sign_key_len);
+ firmware_sign_key_len = RSAProcessedKeySize(algorithm);
+ firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) +
+ FIELD_LEN(firmware_sign_algorithm));
+ firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr,
+ firmware_sign_key_len);
signature_len = siglen_map[algorithm];
/* Only continue if preamble verification succeeds. */
preamble_ptr = (header_ptr + header_len +
- FIELD_LEN(key_signature));
- if ((error_code = VerifyFirmwarePreamble(sign_key, preamble_ptr, algorithm,
+ FIELD_LEN(firmware_key_signature));
+ if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr,
+ algorithm,
&firmware_len)))
return error_code; /* AKA jump to recovery. */
@@ -351,7 +438,8 @@
FIELD_LEN(preamble) +
signature_len);
- if ((error_code = VerifyFirmwareData(sign_key, firmware_ptr, firmware_len,
+ if ((error_code = VerifyFirmwareData(firmware_sign_key, firmware_ptr,
+ firmware_len,
algorithm)))
return error_code; /* AKA jump to recovery. */
@@ -361,11 +449,11 @@
int VerifyFirmwareImage(const RSAPublicKey* root_key,
const FirmwareImage* image,
const int dev_mode) {
- RSAPublicKey* sign_key;
+ RSAPublicKey* firmware_sign_key;
uint8_t* header_digest = NULL;
uint8_t* preamble_digest = NULL;
uint8_t* firmware_digest = NULL;
- int sign_key_size;
+ int firmware_sign_key_size;
int signature_size;
int error_code = 0;
DigestContext ctx;
@@ -384,17 +472,17 @@
DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
DigestUpdate(&ctx, (uint8_t*) &image->header_len,
FIELD_LEN(header_len));
- DigestUpdate(&ctx, (uint8_t*) &image->sign_algorithm,
- FIELD_LEN(sign_algorithm));
- DigestUpdate(&ctx, image->sign_key,
- RSAProcessedKeySize(image->sign_algorithm));
- DigestUpdate(&ctx, (uint8_t*) &image->key_version,
- FIELD_LEN(key_version));
+ DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm,
+ FIELD_LEN(firmware_sign_algorithm));
+ DigestUpdate(&ctx, image->firmware_sign_key,
+ RSAProcessedKeySize(image->firmware_sign_algorithm));
+ DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version,
+ FIELD_LEN(firmware_key_version));
DigestUpdate(&ctx, image->header_checksum,
FIELD_LEN(header_checksum));
header_digest = DigestFinal(&ctx);
- if (!RSA_verify(root_key, image->key_signature,
- FIELD_LEN(key_signature),
+ if (!RSAVerify(root_key, image->firmware_key_signature,
+ FIELD_LEN(firmware_key_signature),
ROOT_SIGNATURE_ALGORITHM,
header_digest)) {
error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
@@ -403,16 +491,16 @@
}
/* Get sign key to verify the rest of the firmware. */
- sign_key_size = RSAProcessedKeySize(image->sign_algorithm);
- sign_key = RSAPublicKeyFromBuf(image->sign_key,
- sign_key_size);
- signature_size = siglen_map[image->sign_algorithm];
+ firmware_sign_key_size = RSAProcessedKeySize(image->firmware_sign_algorithm);
+ firmware_sign_key = RSAPublicKeyFromBuf(image->firmware_sign_key,
+ firmware_sign_key_size);
+ signature_size = siglen_map[image->firmware_sign_algorithm];
- if (image->sign_algorithm >= kNumAlgorithms)
+ if (image->firmware_sign_algorithm >= kNumAlgorithms)
return VERIFY_FIRMWARE_INVALID_ALGORITHM;
/* Verify firmware preamble signature. */
- DigestInit(&ctx, image->sign_algorithm);
+ DigestInit(&ctx, image->firmware_sign_algorithm);
DigestUpdate(&ctx, (uint8_t*) &image->firmware_version,
FIELD_LEN(firmware_version));
DigestUpdate(&ctx, (uint8_t*) &image->firmware_len,
@@ -420,8 +508,8 @@
DigestUpdate(&ctx, (uint8_t*) &image->preamble,
FIELD_LEN(preamble));
preamble_digest = DigestFinal(&ctx);
- if (!RSA_verify(sign_key, image->preamble_signature,
- signature_size, image->sign_algorithm,
+ if (!RSAVerify(firmware_sign_key, image->preamble_signature,
+ signature_size, image->firmware_sign_algorithm,
preamble_digest)) {
error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
goto verify_failure;
@@ -430,9 +518,9 @@
/* Verify firmware signature. */
firmware_digest = DigestBuf(image->firmware_data,
image->firmware_len,
- image->sign_algorithm);
- if(!RSA_verify(sign_key, image->firmware_signature,
- signature_size, image->sign_algorithm,
+ image->firmware_sign_algorithm);
+ if (!RSAVerify(firmware_sign_key, image->firmware_signature,
+ signature_size, image->firmware_sign_algorithm,
firmware_digest)) {
error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED;
goto verify_failure;
@@ -450,64 +538,49 @@
}
int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) {
- int tmp_hdr_fd;
- char* tmp_hdr_file = ".tmpHdrFile";
+ uint8_t* header_blob = NULL;
uint8_t* signature;
-
- if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "firmware header.\n");
+ if (!image || !root_key_file)
+ return 0;
+ header_blob = GetFirmwareHeaderBlob(image);
+ if (!header_blob)
+ return 0;
+ if (!(signature = SignatureBuf(header_blob,
+ GetFirmwareHeaderLen(image),
+ root_key_file,
+ ROOT_SIGNATURE_ALGORITHM))) {
+ Free(header_blob);
return 0;
}
- WriteFirmwareHeader(tmp_hdr_fd, image);
- close(tmp_hdr_fd);
-
- if (!(signature = SignatureFile(tmp_hdr_file, root_key_file,
- ROOT_SIGNATURE_ALGORITHM)))
- return 0;
- Memcpy(image->key_signature, signature, RSA8192NUMBYTES);
+ Memcpy(image->firmware_key_signature, signature, RSA8192NUMBYTES);
+ Free(header_blob);
+ Free(signature);
return 1;
}
-int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file,
- int algorithm) {
- int tmp_preamble_fd;
- char* tmp_preamble_file = ".tmpPreambleFile";
- int tmp_firmware_fd;
- char* tmp_firmware_file = ".tmpFirmwareFile";
+int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) {
+ uint8_t* preamble_blob;
uint8_t* preamble_signature;
uint8_t* firmware_signature;
- int signature_len = siglen_map[algorithm];
+ int signature_len = siglen_map[image->firmware_sign_algorithm];
- /* Write preamble to a file. */
- if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "firmware preamble.\n");
+ preamble_blob = GetFirmwarePreambleBlob(image);
+ if (!(preamble_signature = SignatureBuf(preamble_blob,
+ GetFirmwarePreambleLen(image),
+ signing_key_file,
+ image->firmware_sign_algorithm))) {
+ Free(preamble_blob);
return 0;
}
- WriteFirmwarePreamble(tmp_preamble_fd, image);
- close(tmp_preamble_fd);
- if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file,
- algorithm)))
- return 0;
image->preamble_signature = (uint8_t*) Malloc(signature_len);
Memcpy(image->preamble_signature, preamble_signature, signature_len);
Free(preamble_signature);
- if (-1 == (tmp_firmware_fd = creat(tmp_firmware_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "firmware.\n");
+ if (!(firmware_signature = SignatureBuf(image->firmware_data,
+ image->firmware_len,
+ signing_key_file,
+ image->firmware_sign_algorithm)))
return 0;
- }
- write(tmp_firmware_fd, image->firmware_data, image->firmware_len);
- close(tmp_firmware_fd);
-
- if (!(firmware_signature = SignatureFile(tmp_firmware_file, signing_key_file,
- algorithm))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "firmware.\n");
- return 0;
- }
image->firmware_signature = (uint8_t*) Malloc(signature_len);
Memcpy(image->firmware_signature, firmware_signature, signature_len);
Free(firmware_signature);
diff --git a/utils/firmware_utility.cc b/utils/firmware_utility.cc
index a25be2f..2563fc8 100644
--- a/utils/firmware_utility.cc
+++ b/utils/firmware_utility.cc
@@ -33,8 +33,8 @@
image_(NULL),
root_key_pub_(NULL),
firmware_version_(-1),
- key_version_(-1),
- sign_algorithm_(-1),
+ firmware_key_version_(-1),
+ firmware_sign_algorithm_(-1),
is_generate_(false),
is_verify_(false) {
}
@@ -54,11 +54,11 @@
"to use for verification.\n\n"
"For \"--generate\", required OPTIONS are:\n"
"--root_key <privkeyfile>\tPrivate root key file\n"
- "--sign_key <privkeyfile>\tPrivate signing key file\n"
- "--sign_key_pub <pubkeyfile>\tPre-processed public signing"
+ "--firmware_sign_key <privkeyfile>\tPrivate signing key file\n"
+ "--firmware_sign_key_pub <pubkeyfile>\tPre-processed public signing"
" key\n"
- "--sign_algorithm <algoid>\tSigning algorithm to use\n"
- "--key_version <version#>\tSigning Key Version#\n"
+ "--firmware_sign_algorithm <algoid>\tSigning algorithm to use\n"
+ "--firmware_key_version <version#>\tSigning Key Version#\n"
"--firmware_version <version#>\tFirmware Version#\n"
"--in <infile>\t\t\tFirmware Image to sign\n"
"--out <outfile>\t\t\tOutput file for verified boot firmware image\n\n"
@@ -74,10 +74,10 @@
static struct option long_options[] = {
{"root_key", 1, 0, 0},
{"root_key_pub", 1, 0, 0},
- {"sign_key", 1, 0, 0},
- {"sign_key_pub", 1, 0, 0},
- {"sign_algorithm", 1, 0, 0},
- {"key_version", 1, 0, 0},
+ {"firmware_sign_key", 1, 0, 0},
+ {"firmware_sign_key_pub", 1, 0, 0},
+ {"firmware_sign_algorithm", 1, 0, 0},
+ {"firmware_key_version", 1, 0, 0},
{"firmware_version", 1, 0, 0},
{"in", 1, 0, 0},
{"out", 1, 0, 0},
@@ -100,21 +100,21 @@
case 1: // root_key_pub
root_key_pub_file_ = optarg;
break;
- case 2: // sign_key
- sign_key_file_ = optarg;
+ case 2: // firmware_sign_key
+ firmware_sign_key_file_ = optarg;
break;
- case 3: // sign_key_pub
- sign_key_pub_file_ = optarg;
+ case 3: // firmware_sign_key_pub
+ firmware_sign_key_pub_file_ = optarg;
break;
- case 4: // sign_algorithm
+ case 4: // firmware_sign_algorithm
errno = 0; // strtol() returns an error via errno
- sign_algorithm_ = strtol(optarg, (char**) NULL, 10);
+ firmware_sign_algorithm_ = strtol(optarg, (char**) NULL, 10);
if (errno)
return false;
break;
- case 5: // key_version
+ case 5: // firmware_key_version
errno = 0;
- key_version_ = strtol(optarg, (char**) NULL, 10);
+ firmware_key_version_ = strtol(optarg, (char**) NULL, 10);
if (errno)
return false;
break;
@@ -153,7 +153,7 @@
}
bool FirmwareUtility::GenerateSignedImage(void) {
- uint32_t sign_key_pub_len;
+ uint32_t firmware_sign_key_pub_len;
uint8_t* header_checksum;
DigestContext ctx;
image_ = FirmwareImageNew();
@@ -161,30 +161,31 @@
Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE);
// Copy pre-processed public signing key.
- image_->sign_algorithm = (uint16_t) sign_algorithm_;
- image_->sign_key = BufferFromFile(sign_key_pub_file_.c_str(),
- &sign_key_pub_len);
- if (!image_->sign_key)
+ image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_;
+ image_->firmware_sign_key = BufferFromFile(
+ firmware_sign_key_pub_file_.c_str(),
+ &firmware_sign_key_pub_len);
+ if (!image_->firmware_sign_key)
return false;
- image_->key_version = key_version_;
+ image_->firmware_key_version = firmware_key_version_;
// Update header length.
image_->header_len = (sizeof(image_->header_len) +
- sizeof(image_->sign_algorithm) +
- sign_key_pub_len +
- sizeof(image_->key_version) +
+ sizeof(image_->firmware_sign_algorithm) +
+ firmware_sign_key_pub_len +
+ sizeof(image_->firmware_key_version) +
sizeof(image_->header_checksum));
// Calculate header checksum.
DigestInit(&ctx, SHA512_DIGEST_ALGORITHM);
DigestUpdate(&ctx, (uint8_t*) &image_->header_len,
sizeof(image_->header_len));
- DigestUpdate(&ctx, (uint8_t*) &image_->sign_algorithm,
- sizeof(image_->sign_algorithm));
- DigestUpdate(&ctx, image_->sign_key,
- RSAProcessedKeySize(image_->sign_algorithm));
- DigestUpdate(&ctx, (uint8_t*) &image_->key_version,
- sizeof(image_->key_version));
+ DigestUpdate(&ctx, (uint8_t*) &image_->firmware_sign_algorithm,
+ sizeof(image_->firmware_sign_algorithm));
+ DigestUpdate(&ctx, image_->firmware_sign_key,
+ RSAProcessedKeySize(image_->firmware_sign_algorithm));
+ DigestUpdate(&ctx, (uint8_t*) &image_->firmware_key_version,
+ sizeof(image_->firmware_key_version));
header_checksum = DigestFinal(&ctx);
Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE);
Free(header_checksum);
@@ -199,13 +200,12 @@
if (!image_)
return false;
// Generate and add the signatures.
- if(!AddFirmwareKeySignature(image_, root_key_file_.c_str())) {
+ if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) {
cerr << "Couldn't write key signature to verified boot image.\n";
return false;
}
- if(!AddFirmwareSignature(image_, sign_key_file_.c_str(),
- image_->sign_algorithm)) {
+ if (!AddFirmwareSignature(image_, firmware_sign_key_file_.c_str())) {
cerr << "Couldn't write firmware signature to verified boot image.\n";
return false;
}
@@ -257,19 +257,20 @@
cerr << "Invalid or no firmware version specified." << "\n";
return false;
}
- if (sign_key_file_.empty()) {
+ if (firmware_sign_key_file_.empty()) {
cerr << "No signing key file specified." << "\n";
return false;
}
- if (sign_key_pub_file_.empty()) {
+ if (firmware_sign_key_pub_file_.empty()) {
cerr << "No pre-processed public signing key file specified." << "\n";
return false;
}
- if (key_version_ <= 0 || key_version_ > UINT16_MAX) {
+ if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) {
cerr << "Invalid or no key version specified." << "\n";
return false;
}
- if (sign_algorithm_ < 0 || sign_algorithm_ >= kNumAlgorithms) {
+ if (firmware_sign_algorithm_ < 0 ||
+ firmware_sign_algorithm_ >= kNumAlgorithms) {
cerr << "Invalid or no signing key algorithm specified." << "\n";
return false;
}
diff --git a/utils/kernel_image.c b/utils/kernel_image.c
index b5f07c2..06b340b 100644
--- a/utils/kernel_image.c
+++ b/utils/kernel_image.c
@@ -17,6 +17,7 @@
#include "padding.h"
#include "rsa_utility.h"
#include "sha_utility.h"
+#include "signature_digest.h"
#include "utility.h"
/* Macro to determine the size of a field structure in the KernelImage
@@ -68,12 +69,12 @@
st.remaining_buf = kernel_buf;
/* Read and compare magic bytes. */
- if (!StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE))
- goto parse_failure;
+ StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE);
if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) {
fprintf(stderr, "Wrong Kernel Magic.\n");
- goto parse_failure;
+ Free(kernel_buf);
+ return NULL;
}
StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version));
StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
@@ -83,12 +84,16 @@
FIELD_LEN(kernel_sign_algorithm));
/* Valid Kernel Key signing algorithm. */
- if (image->firmware_sign_algorithm >= kNumAlgorithms)
- goto parse_failure;
+ if (image->firmware_sign_algorithm >= kNumAlgorithms) {
+ Free(kernel_buf);
+ return NULL;
+ }
/* Valid Kernel Signing Algorithm? */
- if (image->kernel_sign_algorithm >= kNumAlgorithms)
- goto parse_failure;
+ if (image->kernel_sign_algorithm >= kNumAlgorithms) {
+ Free(kernel_buf);
+ return NULL;
+ }
/* Compute size of pre-processed RSA public keys and signatures. */
firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm);
@@ -108,7 +113,8 @@
if (header_len != image->header_len) {
fprintf(stderr, "Header length mismatch. Got: %d, Expected: %d\n",
image->header_len, header_len);
- goto parse_failure;
+ Free(kernel_buf);
+ return NULL;
}
/* Read pre-processed public half of the kernel signing key. */
@@ -142,73 +148,150 @@
image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len);
StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len);
- if(st.remaining_len != 0) /* Overrun or underrun. */
- goto parse_failure;
-
- Free(kernel_buf);
- return image;
-
-parse_failure:
- Free(kernel_buf);
- return NULL;
-}
-
-void WriteKernelHeader(int fd, KernelImage* image) {
- int kernel_sign_key_len;
- write(fd, &image->header_version, FIELD_LEN(header_version));
- write(fd, &image->header_len, FIELD_LEN(header_len));
- write(fd, &image->firmware_sign_algorithm,
- FIELD_LEN(firmware_sign_algorithm));
- write(fd, &image->kernel_sign_algorithm,
- FIELD_LEN(kernel_sign_algorithm));
- write(fd, &image->kernel_key_version, FIELD_LEN(kernel_key_version));
- kernel_sign_key_len = (image->header_len -
- FIELD_LEN(header_version) -
- FIELD_LEN(header_len) -
- FIELD_LEN(firmware_sign_algorithm) -
- FIELD_LEN(kernel_sign_algorithm) -
- FIELD_LEN(kernel_key_version) -
- FIELD_LEN(header_checksum));
- write(fd, image->kernel_sign_key, kernel_sign_key_len);
- write(fd, &image->header_checksum, FIELD_LEN(header_checksum));
-}
-
-void WriteKernelConfig(int fd, KernelImage* image) {
- write(fd, &image->kernel_version, FIELD_LEN(kernel_version));
- write(fd, image->options.version, FIELD_LEN(options.version));
- write(fd, &image->options.kernel_len, FIELD_LEN(options.kernel_len));
- write(fd, &image->options.kernel_load_addr,
- FIELD_LEN(options.kernel_load_addr));
- write(fd, &image->options.kernel_entry_addr,
- FIELD_LEN(options.kernel_entry_addr));
-}
-
-KernelImage* WriteKernelImage(const char* input_file,
- KernelImage* image) {
- int fd;
- int kernel_key_signature_len;
- int kernel_signature_len;
- if (!image)
- return NULL;
- if (-1 == (fd = creat(input_file,
- S_IRUSR | S_IWUSR))) { /* Owner has R/W permissions. */
- fprintf(stderr, "Couldn't open file for writing.\n");
+ if(st.remaining_len != 0) { /* Overrun or underrun. */
+ Free(kernel_buf);
return NULL;
}
+ Free(kernel_buf);
+ return image;
+}
+int GetKernelHeaderLen(const KernelImage* image) {
+ return (FIELD_LEN(header_version) + FIELD_LEN(header_len) +
+ FIELD_LEN(firmware_sign_algorithm) +
+ FIELD_LEN(kernel_sign_algorithm) + FIELD_LEN(kernel_key_version) +
+ RSAProcessedKeySize(image->kernel_sign_algorithm) +
+ FIELD_LEN(header_checksum));
+}
+
+uint8_t* GetKernelHeaderBlob(const KernelImage* image) {
+ uint8_t* header_blob = NULL;
+ MemcpyState st;
+
+ header_blob = (uint8_t*) Malloc(GetKernelHeaderLen(image));
+ st.remaining_len = GetKernelHeaderLen(image);
+ st.remaining_buf = header_blob;
+
+ StatefulMemcpy_r(&st, &image->header_version, FIELD_LEN(header_version));
+ StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len));
+ StatefulMemcpy_r(&st, &image->firmware_sign_algorithm,
+ FIELD_LEN(firmware_sign_algorithm));
+ StatefulMemcpy_r(&st, &image->kernel_sign_algorithm,
+ FIELD_LEN(kernel_sign_algorithm));
+ StatefulMemcpy_r(&st, &image->kernel_key_version,
+ FIELD_LEN(kernel_key_version));
+ StatefulMemcpy_r(&st, image->kernel_sign_key,
+ RSAProcessedKeySize(image->kernel_sign_algorithm));
+ StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
+
+ if (st.remaining_len != 0) { /* Underrun or Overrun. */
+ Free(header_blob);
+ return NULL;
+ }
+ return header_blob;
+}
+
+int GetKernelConfigLen(const KernelImage* image) {
+ return (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));
+}
+
+uint8_t* GetKernelConfigBlob(const KernelImage* image) {
+ uint8_t* config_blob = NULL;
+ MemcpyState st;
+
+ config_blob = (uint8_t*) Malloc(GetKernelConfigLen(image));
+ st.remaining_len = GetKernelConfigLen(image);
+ st.remaining_buf = config_blob;
+
+ 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.kernel_len,
+ FIELD_LEN(options.kernel_len));
+ StatefulMemcpy_r(&st, &image->options.kernel_load_addr,
+ FIELD_LEN(options.kernel_load_addr));
+ StatefulMemcpy_r(&st, &image->options.kernel_entry_addr,
+ FIELD_LEN(options.kernel_entry_addr));
+ if (st.remaining_len != 0) { /* Overrun or Underrun. */
+ Free(config_blob);
+ return NULL;
+ }
+ return config_blob;
+}
+
+uint8_t* GetKernelBlob(const KernelImage* image, int* blob_len) {
+ int kernel_key_signature_len;
+ int kernel_signature_len;
+ uint8_t* kernel_blob = NULL;
+ uint8_t* header_blob = NULL;
+ uint8_t* config_blob = NULL;
+ MemcpyState st;
+
+ if (!image)
+ return NULL;
kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm];
kernel_signature_len = siglen_map[image->kernel_sign_algorithm];
+ *blob_len = (FIELD_LEN(magic) +
+ GetKernelHeaderLen(image) +
+ kernel_key_signature_len +
+ GetKernelConfigLen(image) +
+ 2 * kernel_signature_len +
+ image->options.kernel_len);
+ kernel_blob = (uint8_t*) Malloc(*blob_len);
+ st.remaining_len = *blob_len;
+ st.remaining_buf = kernel_blob;
- write(fd, image->magic, FIELD_LEN(magic));
- WriteKernelHeader(fd, image);
- write(fd, image->kernel_key_signature, kernel_key_signature_len);
- WriteKernelConfig(fd, image);
- write(fd, image->config_signature, kernel_signature_len);
- write(fd, image->kernel_signature, kernel_signature_len);
- write(fd, image->kernel_data, image->options.kernel_len);
+ header_blob = GetKernelHeaderBlob(image);
+ config_blob = GetKernelConfigBlob(image);
+ StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
+ StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image));
+ StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len);
+ StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen(image));
+ StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len);
+ StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
+ StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len);
+
+ Free(config_blob);
+ Free(header_blob);
+
+ if (st.remaining_len != 0) { /* Underrun or Overrun. */
+ Free(kernel_blob);
+ return NULL;
+ }
+ return kernel_blob;
+}
+
+int WriteKernelImage(const char* input_file,
+ const KernelImage* image) {
+ int fd;
+ uint8_t* kernel_blob;
+ int blob_len;
+
+ if (!image)
+ return 0;
+ if (-1 == (fd = creat(input_file, S_IRWXU))) {
+ fprintf(stderr, "Couldn't open file for writing kernel image: %s\n",
+ input_file);
+ return 0;
+ }
+ kernel_blob = GetKernelBlob(image, &blob_len);
+ if (!kernel_blob) {
+ fprintf(stderr, "Couldn't create kernel blob from KernelImage.\n");
+ return 0;
+ }
+ if (blob_len != write(fd, kernel_blob, blob_len)) {
+ fprintf(stderr, "Couldn't write Kernel Image to file: %s\n",
+ input_file);
+
+ Free(kernel_blob);
+ close(fd);
+ return 0;
+ }
+ Free(kernel_blob);
close(fd);
- return image;
+ return 1;
}
void PrintKernelImage(const KernelImage* image) {
@@ -478,7 +561,7 @@
DigestUpdate(&ctx, image->header_checksum,
FIELD_LEN(header_checksum));
header_digest = DigestFinal(&ctx);
- if (!RSA_verify(firmware_key, image->kernel_key_signature,
+ if (!RSAVerify(firmware_key, image->kernel_key_signature,
siglen_map[image->firmware_sign_algorithm],
image->firmware_sign_algorithm,
header_digest)) {
@@ -507,9 +590,9 @@
DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr,
FIELD_LEN(options.kernel_entry_addr));
config_digest = DigestFinal(&ctx);
- if (!RSA_verify(kernel_sign_key, image->config_signature,
- kernel_signature_size, image->kernel_sign_algorithm,
- config_digest)) {
+ if (!RSAVerify(kernel_sign_key, image->config_signature,
+ kernel_signature_size, image->kernel_sign_algorithm,
+ config_digest)) {
error_code = VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
goto verify_failure;
}
@@ -518,7 +601,7 @@
kernel_digest = DigestBuf(image->kernel_data,
image->options.kernel_len,
image->kernel_sign_algorithm);
- if(!RSA_verify(kernel_sign_key, image->kernel_signature,
+ if (!RSAVerify(kernel_sign_key, image->kernel_signature,
kernel_signature_size, image->kernel_sign_algorithm,
kernel_digest)) {
error_code = VERIFY_KERNEL_SIGNATURE_FAILED;
@@ -537,63 +620,53 @@
}
int AddKernelKeySignature(KernelImage* image, const char* firmware_key_file) {
- int tmp_hdr_fd;
- char* tmp_hdr_file = ".tmpKernelHdrFile";
+ uint8_t* header_blob = NULL;
uint8_t* signature;
int signature_len = siglen_map[image->firmware_sign_algorithm];
-
- if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "kernel header.\n");
+ if (!image || !firmware_key_file)
+ return 0;
+ header_blob = GetKernelHeaderBlob(image);
+ if (!header_blob)
+ return 0;
+ if (!(signature = SignatureBuf(header_blob,
+ GetKernelHeaderLen(image),
+ firmware_key_file,
+ image->firmware_sign_algorithm))) {
+ Free(header_blob);
return 0;
}
- WriteKernelHeader(tmp_hdr_fd, image);
- close(tmp_hdr_fd);
- if (!(signature = SignatureFile(tmp_hdr_file, firmware_key_file,
- image->firmware_sign_algorithm)))
- return 0;
image->kernel_key_signature = Malloc(signature_len);
Memcpy(image->kernel_key_signature, signature, signature_len);
+ Free(signature);
+ Free(header_blob);
return 1;
}
-int AddKernelSignature(KernelImage* image, const char* kernel_signing_key_file,
- int algorithm) {
- int tmp_config_fd;
- char* tmp_config_file = ".tmpConfigFile";
- int tmp_kernel_fd;
- char* tmp_kernel_file = ".tmpKernelFile";
+int AddKernelSignature(KernelImage* image,
+ const char* kernel_signing_key_file) {
+ uint8_t* config_blob;
uint8_t* config_signature;
uint8_t* kernel_signature;
- int signature_len = siglen_map[algorithm];
+ int signature_len = siglen_map[image->kernel_sign_algorithm];
- /* Write config to a file. */
- if(-1 == (tmp_config_fd = creat(tmp_config_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "kernel config.\n");
+ config_blob = GetKernelConfigBlob(image);
+ if (!(config_signature = SignatureBuf(config_blob,
+ GetKernelConfigLen(image),
+ kernel_signing_key_file,
+ image->kernel_sign_algorithm))) {
+ fprintf(stderr, "Could not compute signature on the kernel config.\n");
+ Free(config_blob);
return 0;
}
- WriteKernelConfig(tmp_config_fd, image);
- close(tmp_config_fd);
- if (!(config_signature = SignatureFile(tmp_config_file,
- kernel_signing_key_file,
- algorithm)))
- return 0;
+
image->config_signature = (uint8_t*) Malloc(signature_len);
Memcpy(image->config_signature, config_signature, signature_len);
Free(config_signature);
- if (-1 == (tmp_kernel_fd = creat(tmp_kernel_file, S_IRWXU))) {
- fprintf(stderr, "Could not open temporary file for writing "
- "kernel.\n");
- return 0;
- }
- write(tmp_kernel_fd, image->kernel_data, image->options.kernel_len);
- close(tmp_kernel_fd);
-
- if (!(kernel_signature = SignatureFile(tmp_kernel_file,
- kernel_signing_key_file,
- algorithm))) {
+ if (!(kernel_signature = SignatureBuf(image->kernel_data,
+ image->options.kernel_len,
+ kernel_signing_key_file,
+ image->kernel_sign_algorithm))) {
fprintf(stderr, "Could not compute signature on the kernel.\n");
return 0;
}
diff --git a/utils/signature_digest.c b/utils/signature_digest.c
index 100f7ec..96cc552 100644
--- a/utils/signature_digest.c
+++ b/utils/signature_digest.c
@@ -1,17 +1,13 @@
/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
- * Utility that outputs the message digest of the contents of a file in a
- * format that can be used as input to OpenSSL for an RSA signature.
- * Needed until the stable OpenSSL release supports SHA-256/512 digests for
- * RSA signatures.
- * Outputs DigestInfo || Digest where DigestInfo is the OID depending on the
- * choice of the hash algorithm (see padding.c).
- *
*/
#include "signature_digest.h"
+#define OPENSSL_NO_SHA
+#include <openssl/engine.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
#include <stdio.h>
#include <stdlib.h>
@@ -20,49 +16,59 @@
#include "padding.h"
#include "sha.h"
#include "sha_utility.h"
+#include "utility.h"
uint8_t* PrependDigestInfo(int algorithm, uint8_t* digest) {
const int digest_size = hash_size_map[algorithm];
const int digestinfo_size = digestinfo_size_map[algorithm];
const uint8_t* digestinfo = hash_digestinfo_map[algorithm];
- uint8_t* p = malloc(digestinfo_size + digest_size);
- memcpy(p, digestinfo, digestinfo_size);
- memcpy(p + digestinfo_size, digest, digest_size);
+ uint8_t* p = Malloc(digestinfo_size + digest_size);
+ Memcpy(p, digestinfo, digestinfo_size);
+ Memcpy(p + digestinfo_size, digest, digest_size);
return p;
}
-int main(int argc, char* argv[]) {
- int i, algorithm;
- uint8_t* digest = NULL;
- uint8_t* signature = NULL;
+uint8_t* SignatureDigest(const uint8_t* buf, int len, int algorithm) {
uint8_t* info_digest = NULL;
+ uint8_t* digest = NULL;
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <algorithm> <input file>\n\n",
- argv[0]);
- fprintf(stderr, "where <algorithm> is the signature algorithm to use:\n");
- for(i = 0; i<kNumAlgorithms; i++)
- fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]);
- return -1;
- }
-
- algorithm = atoi(argv[1]);
if (algorithm >= kNumAlgorithms) {
- fprintf(stderr, "Invalid Algorithm!\n");
- goto failure;
+ fprintf(stderr, "SignatureDigest() called with invalid algorithm!\n");
+ } else if ((digest = DigestBuf(buf, len, algorithm))) {
+ info_digest = PrependDigestInfo(algorithm, digest);
}
+ Free(digest);
+ return info_digest;
+}
- if (!(digest = DigestFile(argv[2], algorithm)))
- goto failure;
-
- info_digest = PrependDigestInfo(algorithm, digest);
- write(1, info_digest, hash_size_map[algorithm] +
- digestinfo_size_map[algorithm]);
-
-failure:
- free(digest);
- free(info_digest);
- free(signature);
-
- return 0;
+uint8_t* SignatureBuf(const uint8_t* buf, int len, const char* key_file,
+ int algorithm) {
+ FILE* key_fp = NULL;
+ RSA* key = NULL;
+ uint8_t* signature = NULL;
+ uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
+ int signature_digest_len = (hash_size_map[algorithm] +
+ digestinfo_size_map[algorithm]);
+ key_fp = fopen(key_file, "r");
+ if (!key_fp) {
+ fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n", key_file);
+ return NULL;
+ }
+ if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
+ signature = (uint8_t*) Malloc(siglen_map[algorithm]);
+ else
+ fprintf(stderr, "SignatureBuf(): Couldn't read private key from file: %s\n",
+ key_file);
+ if (signature) {
+ if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */
+ signature_digest, /* Input data. */
+ signature, /* Output signature. */
+ key, /* Key to use. */
+ RSA_PKCS1_PADDING)) /* Padding to use. */
+ fprintf(stderr, "SignatureBuf(): RSA_private_encrypt() failed.\n");
+ }
+ if (key)
+ RSA_free(key);
+ Free(signature_digest);
+ return signature;
}
diff --git a/utils/verify_data.c b/utils/verify_data.c
index 8a79d0f..4b0b785 100644
--- a/utils/verify_data.c
+++ b/utils/verify_data.c
@@ -74,23 +74,22 @@
return 0;
}
/* Length of the RSA Signature/RSA Key */
- sig_len = siglen_map[algorithm];
- if (!(key = RSAPublicKeyFromFile(argv[2])))
- goto failure;
- if (!(signature = read_signature(argv[3], sig_len)))
- goto failure;
- if (!(digest = DigestFile(argv[4], algorithm)))
- goto failure;
- if(RSA_verify(key, signature, sig_len, algorithm, digest)) {
- return_code = 0;
- fprintf(stderr, "Signature Verification "
- COL_GREEN "SUCCEEDED" COL_STOP "\n");
- } else {
- fprintf(stderr, "Signature Verification "
- COL_RED "FAILED" COL_STOP "\n");
+ sig_len = siglen_map[algorithm];
+ if ((key = RSAPublicKeyFromFile(argv[2])) &&
+ (signature = read_signature(argv[3], sig_len)) &&
+ (digest = DigestFile(argv[4], algorithm))) {
+ if (RSAVerify(key, signature, sig_len, algorithm, digest)) {
+ return_code = 0;
+ fprintf(stderr, "Signature Verification "
+ COL_GREEN "SUCCEEDED" COL_STOP "\n");
+ } else {
+ fprintf(stderr, "Signature Verification "
+ COL_RED "FAILED" COL_STOP "\n");
+ }
}
+ else
+ return_code = -1;
-failure:
free(key);
free(signature);
free(digest);