Index: src/platform/vboot_reference/include/firmware_image.h |
diff --git a/src/platform/vboot_reference/include/firmware_image.h b/src/platform/vboot_reference/include/firmware_image.h |
index e2cbb5c0977d679d41a8a5d2a27f264d7b881072..1a9dc83ea3f29f140335758c11b0fa209d1046f1 100644 |
--- a/src/platform/vboot_reference/include/firmware_image.h |
+++ b/src/platform/vboot_reference/include/firmware_image.h |
@@ -17,7 +17,8 @@ |
#define FIRMWARE_MAGIC_SIZE 8 |
#define FIRMWARE_PREAMBLE_SIZE 8 |
-#define ROOT_SIGNATURE_ALGORITHM 11 /* RSA 8192 and SHA-512. */ |
+/* RSA 8192 and SHA-512. */ |
+#define ROOT_SIGNATURE_ALGORITHM 11 |
#define ROOT_SIGNATURE_ALGORITHM_STRING "11" |
typedef struct FirmwareImage { |
@@ -27,7 +28,7 @@ typedef struct FirmwareImage { |
uint16_t sign_algorithm; /* Signature algorithm used by the signing key. */ |
uint8_t* sign_key; /* Pre-processed public half of signing key. */ |
uint16_t key_version; /* Key Version# for preventing rollbacks. */ |
- uint8_t header_hash[SHA512_DIGEST_SIZE]; /* SHA-512 hash of the header.*/ |
+ uint8_t header_checksum[SHA512_DIGEST_SIZE]; /* SHA-512 hash of the header.*/ |
uint8_t key_signature[RSA8192NUMBYTES]; /* Signature of the header above. */ |
@@ -56,8 +57,8 @@ void FirmwareImageFree(FirmwareImage* fw); |
* |
* Returns a filled up FirmwareImage on success, NULL on error. |
*/ |
-FirmwareImage* ReadFirmware(const char* input_file, |
- FirmwareImage* image); |
+FirmwareImage* ReadFirmwareImage(const char* input_file, |
+ FirmwareImage* image); |
/* Write firmware header from [image] to an open file pointed by the |
* file descriptor [fd]. |
@@ -74,13 +75,79 @@ void WriteFirmwarePreamble(int fd, FirmwareImage* image); |
* |
* Return [image] on success, NULL on error. |
*/ |
-FirmwareImage* WriteFirmware(const char* input_file, |
- FirmwareImage* image); |
+FirmwareImage* WriteFirmwareImage(const char* input_file, |
+ FirmwareImage* image); |
/* Pretty print the contents of [image]. Only headers and metadata information |
* is printed. |
*/ |
-void PrintFirmware(const FirmwareImage* image); |
+void PrintFirmwareImage(const FirmwareImage* image); |
+ |
+/* Error Codes for VerifyFirmware* family of functions. */ |
+#define VERIFY_FIRMWARE_SUCCESS 0 |
+#define VERIFY_FIRMWARE_INVALID_IMAGE 1 |
+#define VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED 2 |
+#define VERIFY_FIRMWARE_INVALID_ALGORITHM 3 |
+#define VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED 4 |
+#define VERIFY_FIRMWARE_SIGNATURE_FAILED 5 |
+#define VERIFY_FIRMWARE_WRONG_MAGIC 6 |
+#define VERIFY_FIRMWARE_MAX 7 /* Generic catch-all. */ |
+ |
+char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX]; |
+ |
+/* Checks for the sanity of the firmware header pointed by [header_blob]. |
+ * If [dev_mode] is enabled, also checks the root key signature using the |
+ * pre-processed public root key [root_key_blob]. |
+ * |
+ * On success, put signature algorithm in [algorithm], header length |
+ * in [header_len], and return 0. |
+ * Else, return error code on failure. |
+ */ |
+int VerifyFirmwareHeader(const uint8_t* root_key_blob, |
+ const uint8_t* header_blob, |
+ const int dev_mode, |
+ int* algorithm, |
+ int* header_len); |
+ |
+/* Checks the preamble signature on firmware preamble pointed by |
+ * [preamble_blob] using the signing key [sign_key]. |
+ * |
+ * On success, put firmware length into [firmware_len], and return 0. |
+ * Else, return error code on failure. |
+ */ |
+int VerifyFirmwarePreamble(RSAPublicKey* sign_key, |
+ const uint8_t* preamble_blob, |
+ int algorithm, |
+ int* firmware_len); |
+ |
+/* Checks the signature on the firmware data at location [firmware_data_start]. |
+ * The length of the actual firmware data is firmware_len and it is assumed to |
+ * be prepended with the signature whose size depends on the signature_algorithm |
+ * [algorithm]. |
+ * |
+ * Return 0 on success, error code on failure. |
+ */ |
+int VerifyFirmwareData(RSAPublicKey* sign_key, |
+ const uint8_t* firmware_data_start, |
+ int firmware_len, |
+ int algorithm); |
+ |
+/* Performs a chained verify of the firmware blob [firmware_blob]. If |
+ * [dev_mode] is 0 [inactive], then the pre-processed public root key |
+ * [root_key_blob] is used the verify the signature of the signing key, |
+ * else the check is skipped. |
+ * |
+ * Returns 0 on success, error code on failure. |
+ * |
+ * NOTE: The length of the firmware blob is derived from reading the fields |
+ * in the first few bytes of the buffer. This might look risky but in firmware |
+ * land, the start address of the firmware_blob will always be fixed depending |
+ * on the memory map on the particular platform. In addition, the signature on |
+ * length itself is checked early in the verification process for extra safety. |
+ */ |
+int VerifyFirmware(const uint8_t* root_key_blob, |
+ const uint8_t* firmware_blob, |
+ const int dev_mode); |
/* Performs a chained verify of the firmware [image]. If [dev_mode] is |
* 0 (inactive), then the [root_key] is used to verify the signature of |
@@ -88,33 +155,13 @@ void PrintFirmware(const FirmwareImage* image); |
* |
* Returns 0 on success, error code on failure. |
*/ |
-int VerifyFirmware(const RSAPublicKey* root_key, |
- const FirmwareImage* image, |
- const int dev_mode); |
- |
-/* Error Codes for VerifyFirmware. */ |
-#define VERIFY_SUCCESS 0 |
-#define VERIFY_INVALID_IMAGE 1 |
-#define VERIFY_ROOT_SIGNATURE_FAILED 2 |
-#define VERIFY_INVALID_ALGORITHM 3 |
-#define VERIFY_PREAMBLE_SIGNATURE_FAILED 4 |
-#define VERIFY_FIRMWARE_SIGNATURE_FAILED 5 |
-#define VERIFY_MAX 6 /* Generic catch-all. */ |
- |
-char* kVerifyFirmwareErrors[VERIFY_MAX]; |
+int VerifyFirmwareImage(const RSAPublicKey* root_key, |
+ const FirmwareImage* image, |
+ const int dev_mode); |
/* Maps error codes from VerifyFirmware() to error description. */ |
char* VerifyErrorString(int error); |
- |
-/* Helper function to invoke external program to calculate signature on |
- * [input_file] using private key [key_file] and signature algorithm |
- * [algorithm]. |
- * |
- * Returns the signature. Caller owns the buffer and must Free() it. |
- */ |
-uint8_t* SignatureFile(char* input_fie, char* key_file, int algorithm); |
- |
/* Add a root key signature to the key header to a firmware image [image] |
* using the private root key in file [root_key_file]. |
* |