| Index: src/platform/vboot_reference/utils/firmware_image.c
|
| diff --git a/src/platform/vboot_reference/utils/firmware_image.c b/src/platform/vboot_reference/utils/firmware_image.c
|
| index 07aa8bd46b09153824ad2337f8415b87e74874ca..714d5dd5a3a43c190f9a729c6b33f56e51c88de7 100644
|
| --- a/src/platform/vboot_reference/utils/firmware_image.c
|
| +++ b/src/platform/vboot_reference/utils/firmware_image.c
|
| @@ -25,54 +25,40 @@
|
| #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
|
|
|
| FirmwareImage* FirmwareImageNew(void) {
|
| - FirmwareImage* fw = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
|
| - return fw;
|
| + FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
|
| + if (image) {
|
| + image->sign_key = NULL;
|
| + image->preamble_signature = NULL;
|
| + image->firmware_signature = NULL;
|
| + image->firmware_data = NULL;
|
| + }
|
| + return image;
|
| }
|
|
|
| void FirmwareImageFree(FirmwareImage* image) {
|
| - Free(image->sign_key);
|
| - Free(image->key_signature);
|
| - Free(image->preamble_signature);
|
| - Free(image->firmware_signature);
|
| - Free(image->firmware_data);
|
| + if (image) {
|
| + Free(image->sign_key);
|
| + Free(image->preamble_signature);
|
| + Free(image->firmware_signature);
|
| + Free(image->firmware_data);
|
| + }
|
| }
|
|
|
| -FirmwareImage* ReadFirmwareImage(const char* input_file,
|
| - FirmwareImage* image) {
|
| - int fd;
|
| - struct stat fd_stat;
|
| -
|
| +FirmwareImage* ReadFirmwareImage(const char* input_file) {
|
| + uint32_t file_size;
|
| int image_len = 0; /* Total size of the firmware image. */
|
| int header_len = 0;
|
| int sign_key_len;
|
| int signature_len;
|
| uint8_t* firmware_buf;
|
| MemcpyState st;
|
| + FirmwareImage* image = FirmwareImageNew();
|
|
|
| if (!image)
|
| return NULL;
|
|
|
| - if (-1 == (fd = open(input_file, O_RDONLY))) {
|
| - fprintf(stderr, "Couldn't open file for reading.\n");
|
| - return NULL;
|
| - }
|
| -
|
| - if (-1 == fstat(fd, &fd_stat)) {
|
| - fprintf(stderr, "Couldn't stat file.\n");
|
| - close(fd);
|
| - return NULL;
|
| - }
|
| -
|
| - firmware_buf = (uint8_t*) Malloc(fd_stat.st_size);
|
| - image_len = fd_stat.st_size;
|
| -
|
| - /* Read entire file into a buffer. */
|
| - if (image_len != read(fd, firmware_buf, image_len)) {
|
| - fprintf(stderr, "Couldn't read file data.\n");
|
| - close(fd);
|
| - return NULL;
|
| - }
|
| - close(fd);
|
| + firmware_buf = BufferFromFile(input_file, &file_size);
|
| + image_len = file_size;
|
|
|
| st.remaining_len = image_len;
|
| st.remaining_buf = firmware_buf;
|
| @@ -86,41 +72,43 @@ FirmwareImage* ReadFirmwareImage(const char* input_file,
|
| goto parse_failure;
|
| }
|
|
|
| - StatefulMemcpy(&st, &image->header_len, sizeof(image->header_len));
|
| - StatefulMemcpy(&st, &image->sign_algorithm, sizeof(image->sign_algorithm));
|
| + StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
|
| + StatefulMemcpy(&st, &image->sign_algorithm, FIELD_LEN(sign_algorithm));
|
|
|
| /* Valid Algorithm? */
|
| - if (image->sign_algorithm > kNumAlgorithms)
|
| + if (image->sign_algorithm >= kNumAlgorithms)
|
| goto parse_failure;
|
|
|
| /* Compute size of pre-processed RSA public key and signature. */
|
| - sign_key_len = (2*siglen_map[image->sign_algorithm]*sizeof(uint32_t)
|
| - + sizeof(uint32_t) + sizeof(int));
|
| + sign_key_len = RSAProcessedKeySize(image->sign_algorithm);
|
| signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t);
|
|
|
|
|
| /* Check whether the header length is correct. */
|
| - header_len = (sizeof(image->header_len) + sizeof(image->sign_algorithm) +
|
| - sizeof(image->key_version) +
|
| - sizeof(image->header_checksum));
|
| + header_len = (FIELD_LEN(header_len) +
|
| + FIELD_LEN(sign_algorithm) +
|
| + sign_key_len +
|
| + FIELD_LEN(key_version) +
|
| + FIELD_LEN(header_checksum));
|
| if (header_len != image->header_len) {
|
| - fprintf(stderr, "Header length mismatch.");
|
| + fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n",
|
| + image->header_len, header_len);
|
| goto parse_failure;
|
| }
|
|
|
| /* 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, sizeof(image->key_version));
|
| - StatefulMemcpy(&st, image->header_checksum, sizeof(image->header_checksum));
|
| + StatefulMemcpy(&st, &image->key_version, FIELD_LEN(key_version));
|
| + StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
|
|
|
| /* Read key signature. */
|
| - StatefulMemcpy(&st, image->key_signature, sizeof(image->key_signature));
|
| + StatefulMemcpy(&st, image->key_signature, FIELD_LEN(key_signature));
|
|
|
| /* Read the firmware preamble. */
|
| - StatefulMemcpy(&st,&image->firmware_version, sizeof(image->firmware_version));
|
| - StatefulMemcpy(&st, &image->firmware_len, sizeof(image->firmware_len));
|
| - StatefulMemcpy(&st, image->preamble, sizeof(image->preamble));
|
| + StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version));
|
| + StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len));
|
| + StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble));
|
|
|
| /* Read firmware preamble signature. */
|
| image->preamble_signature = (uint8_t*) Malloc(signature_len);
|
| @@ -145,22 +133,22 @@ parse_failure:
|
|
|
| void WriteFirmwareHeader(int fd, FirmwareImage* image) {
|
| int sign_key_len;
|
| - write(fd, &image->header_len, sizeof(image->header_len));
|
| - write(fd, &image->sign_algorithm, sizeof(image->header_len));
|
| - sign_key_len = (image->header_len - sizeof(image->header_len) -
|
| - sizeof(image->sign_algorithm) -
|
| - sizeof(image->key_version) -
|
| - sizeof(image->header_checksum));
|
| + 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, sizeof(image->key_version));
|
| - write(fd, &image->header_checksum, sizeof(image->header_checksum));
|
| + 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,
|
| - sizeof(image->firmware_version));
|
| - write(fd, &image->firmware_len, sizeof(image->firmware_len));
|
| - write(fd, image->preamble, sizeof(image->preamble));
|
| + 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,
|
| @@ -175,9 +163,9 @@ FirmwareImage* WriteFirmwareImage(const char* input_file,
|
| return NULL;
|
| }
|
|
|
| - write(fd, image->magic, sizeof(image->magic));
|
| + write(fd, image->magic, FIELD_LEN(magic));
|
| WriteFirmwareHeader(fd, image);
|
| - write(fd, image->key_signature, sizeof(image->key_signature));
|
| + write(fd, image->key_signature, FIELD_LEN(key_signature));
|
| signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t);
|
| WriteFirmwarePreamble(fd, image);
|
| write(fd, image->preamble_signature, signature_len);
|
| @@ -188,7 +176,7 @@ FirmwareImage* WriteFirmwareImage(const char* input_file,
|
| return image;
|
| }
|
|
|
| -void PrintFirmware(const FirmwareImage* image) {
|
| +void PrintFirmwareImage(const FirmwareImage* image) {
|
| if (!image)
|
| return;
|
|
|
| @@ -395,18 +383,18 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key,
|
| if (!dev_mode) {
|
| DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
|
| DigestUpdate(&ctx, (uint8_t*) &image->header_len,
|
| - sizeof(image->header_len));
|
| + FIELD_LEN(header_len));
|
| DigestUpdate(&ctx, (uint8_t*) &image->sign_algorithm,
|
| - sizeof(image->sign_algorithm));
|
| + FIELD_LEN(sign_algorithm));
|
| DigestUpdate(&ctx, image->sign_key,
|
| RSAProcessedKeySize(image->sign_algorithm));
|
| DigestUpdate(&ctx, (uint8_t*) &image->key_version,
|
| - sizeof(image->key_version));
|
| + FIELD_LEN(key_version));
|
| DigestUpdate(&ctx, image->header_checksum,
|
| - sizeof(image->header_checksum));
|
| + FIELD_LEN(header_checksum));
|
| header_digest = DigestFinal(&ctx);
|
| if (!RSA_verify(root_key, image->key_signature,
|
| - sizeof(image->key_signature),
|
| + FIELD_LEN(key_signature),
|
| ROOT_SIGNATURE_ALGORITHM,
|
| header_digest)) {
|
| error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
|
| @@ -426,11 +414,11 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key,
|
| /* Verify firmware preamble signature. */
|
| DigestInit(&ctx, image->sign_algorithm);
|
| DigestUpdate(&ctx, (uint8_t*) &image->firmware_version,
|
| - sizeof(image->firmware_version));
|
| + FIELD_LEN(firmware_version));
|
| DigestUpdate(&ctx, (uint8_t*) &image->firmware_len,
|
| - sizeof(image->firmware_len));
|
| + FIELD_LEN(firmware_len));
|
| DigestUpdate(&ctx, (uint8_t*) &image->preamble,
|
| - sizeof(image->preamble));
|
| + FIELD_LEN(preamble));
|
| preamble_digest = DigestFinal(&ctx);
|
| if (!RSA_verify(sign_key, image->preamble_signature,
|
| signature_size, image->sign_algorithm,
|
| @@ -457,8 +445,11 @@ verify_failure:
|
| return error_code;
|
| }
|
|
|
| +const char* VerifyFirmwareErrorString(int error) {
|
| + return kVerifyFirmwareErrors[error];
|
| +}
|
|
|
| -int AddKeySignature(FirmwareImage* image, char* root_key_file) {
|
| +int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) {
|
| int tmp_hdr_fd;
|
| char* tmp_hdr_file = ".tmpHdrFile";
|
| uint8_t* signature;
|
| @@ -478,7 +469,7 @@ int AddKeySignature(FirmwareImage* image, char* root_key_file) {
|
| return 1;
|
| }
|
|
|
| -int AddFirmwareSignature(FirmwareImage* image, char* signing_key_file,
|
| +int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file,
|
| int algorithm) {
|
| int tmp_preamble_fd;
|
| char* tmp_preamble_file = ".tmpPreambleFile";
|
|
|