| OLD | NEW |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 * | 4 * |
| 5 * Functions for verifying a verified boot firmware image. | 5 * Functions for verifying a verified boot firmware image. |
| 6 * (Firmware Portion) | 6 * (Firmware Portion) |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "firmware_image_fw.h" | 9 #include "firmware_image_fw.h" |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 "Root Key Signature Failed.", | 22 "Root Key Signature Failed.", |
| 23 "Invalid Verification Algorithm.", | 23 "Invalid Verification Algorithm.", |
| 24 "Preamble Signature Failed.", | 24 "Preamble Signature Failed.", |
| 25 "Firmware Signature Failed.", | 25 "Firmware Signature Failed.", |
| 26 "Wrong Firmware Magic.", | 26 "Wrong Firmware Magic.", |
| 27 "Invalid Firmware Header Checksum.", | 27 "Invalid Firmware Header Checksum.", |
| 28 "Firmware Signing Key Rollback.", | 28 "Firmware Signing Key Rollback.", |
| 29 "Firmware Version Rollback." | 29 "Firmware Version Rollback." |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 uint64_t GetFirmwarePreambleLen(int algorithm) { |
| 33 return (FIELD_LEN(firmware_version) + |
| 34 FIELD_LEN(firmware_len) + |
| 35 FIELD_LEN(kernel_subkey_sign_algorithm) + |
| 36 RSAProcessedKeySize(algorithm) + |
| 37 FIELD_LEN(preamble)); |
| 38 } |
| 39 |
| 40 |
| 32 int VerifyFirmwareHeader(const uint8_t* root_key_blob, | 41 int VerifyFirmwareHeader(const uint8_t* root_key_blob, |
| 33 const uint8_t* header_blob, | 42 const uint8_t* header_blob, |
| 34 int* algorithm, | 43 int* algorithm, |
| 35 int* header_len) { | 44 int* header_len) { |
| 36 int firmware_sign_key_len; | 45 int firmware_sign_key_len; |
| 37 int root_key_len; | 46 int root_key_len; |
| 38 uint16_t hlen, algo; | 47 uint16_t hlen, algo; |
| 39 uint8_t* header_checksum = NULL; | 48 uint8_t* header_checksum = NULL; |
| 40 | 49 |
| 41 /* Base Offset for the header_checksum field. Actual offset is | 50 /* Base Offset for the header_checksum field. Actual offset is |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 header_blob, /* Data to verify */ | 91 header_blob, /* Data to verify */ |
| 83 *header_len, /* Length of data */ | 92 *header_len, /* Length of data */ |
| 84 header_blob + *header_len, /* Expected Signature */ | 93 header_blob + *header_len, /* Expected Signature */ |
| 85 ROOT_SIGNATURE_ALGORITHM)) | 94 ROOT_SIGNATURE_ALGORITHM)) |
| 86 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | 95 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
| 87 return 0; | 96 return 0; |
| 88 } | 97 } |
| 89 | 98 |
| 90 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, | 99 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, |
| 91 const uint8_t* preamble_blob, | 100 const uint8_t* preamble_blob, |
| 92 int algorithm, | 101 int firmware_sign_algorithm, |
| 93 uint64_t* firmware_len) { | 102 uint64_t* firmware_len) { |
| 94 uint64_t len; | 103 uint64_t len; |
| 95 int preamble_len; | 104 int preamble_len; |
| 96 uint16_t firmware_version; | 105 uint16_t firmware_version; |
| 106 uint16_t kernel_subkey_sign_algorithm; |
| 97 | 107 |
| 98 Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version)); | 108 Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version)); |
| 99 | 109 Memcpy(&kernel_subkey_sign_algorithm, |
| 100 preamble_len = (FIELD_LEN(firmware_version) + | 110 preamble_blob + (FIELD_LEN(firmware_version) + |
| 101 FIELD_LEN(firmware_len) + | 111 FIELD_LEN(firmware_len)), |
| 102 FIELD_LEN(preamble)); | 112 FIELD_LEN(kernel_subkey_sign_algorithm)); |
| 113 preamble_len = GetFirmwarePreambleLen(kernel_subkey_sign_algorithm); |
| 103 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ | 114 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ |
| 104 preamble_blob, /* Data to verify */ | 115 preamble_blob, /* Data to verify */ |
| 105 preamble_len, /* Length of data */ | 116 preamble_len, /* Length of data */ |
| 106 preamble_blob + preamble_len, /* Expected Signature */ | 117 preamble_blob + preamble_len, /* Expected Signature */ |
| 107 algorithm)) | 118 firmware_sign_algorithm)) |
| 108 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; | 119 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; |
| 109 | 120 |
| 110 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), | 121 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), |
| 111 sizeof(len)); | 122 sizeof(len)); |
| 112 *firmware_len = len; | 123 *firmware_len = len; |
| 113 return 0; | 124 return 0; |
| 114 } | 125 } |
| 115 | 126 |
| 116 int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, | 127 int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, |
| 117 const uint8_t* preamble_start, | 128 const uint8_t* preamble_start, |
| 118 const uint8_t* firmware_data, | 129 const uint8_t* firmware_data, |
| 119 uint64_t firmware_len, | 130 uint64_t firmware_len, |
| 120 int algorithm) { | 131 int firmware_sign_algorithm) { |
| 121 int signature_len = siglen_map[algorithm]; | 132 int signature_len = siglen_map[firmware_sign_algorithm]; |
| 122 int preamble_len = (FIELD_LEN(firmware_version) + | 133 int preamble_len; |
| 123 FIELD_LEN(firmware_len) + | 134 uint16_t kernel_subkey_sign_algorithm; |
| 124 FIELD_LEN(preamble));; | |
| 125 uint8_t* digest = NULL; | 135 uint8_t* digest = NULL; |
| 126 const uint8_t* firmware_signature = NULL; | 136 const uint8_t* firmware_signature = NULL; |
| 127 DigestContext ctx; | 137 DigestContext ctx; |
| 138 Memcpy(&kernel_subkey_sign_algorithm, |
| 139 preamble_start + (FIELD_LEN(firmware_version) + |
| 140 FIELD_LEN(firmware_len)), |
| 141 FIELD_LEN(kernel_subkey_sign_algorithm)); |
| 142 preamble_len = GetFirmwarePreambleLen(kernel_subkey_sign_algorithm); |
| 143 |
| 128 | 144 |
| 129 /* Since the firmware signature is over the preamble and the firmware data, | 145 /* Since the firmware signature is over the preamble and the firmware data, |
| 130 * which does not form a contiguous region of memory, we calculate the | 146 * which does not form a contiguous region of memory, we calculate the |
| 131 * message digest ourselves. */ | 147 * message digest ourselves. */ |
| 132 DigestInit(&ctx, algorithm); | 148 DigestInit(&ctx, firmware_sign_algorithm); |
| 133 DigestUpdate(&ctx, preamble_start, preamble_len); | 149 DigestUpdate(&ctx, preamble_start, preamble_len); |
| 134 DigestUpdate(&ctx, firmware_data, firmware_len); | 150 DigestUpdate(&ctx, firmware_data, firmware_len); |
| 135 digest = DigestFinal(&ctx); | 151 digest = DigestFinal(&ctx); |
| 136 /* Firmware signature is at the end of preamble and preamble signature. */ | 152 /* Firmware signature is at the end of preamble and preamble signature. */ |
| 137 firmware_signature = preamble_start + preamble_len + signature_len; | 153 firmware_signature = preamble_start + preamble_len + signature_len; |
| 138 if (!RSAVerifyBinaryWithDigest_f( | 154 if (!RSAVerifyBinaryWithDigest_f( |
| 139 NULL, firmware_sign_key, /* Key to use. */ | 155 NULL, firmware_sign_key, /* Key to use. */ |
| 140 digest, /* Digest of the data to verify. */ | 156 digest, /* Digest of the data to verify. */ |
| 141 firmware_signature, /* Expected Signature */ | 157 firmware_signature, /* Expected Signature */ |
| 142 algorithm)) { | 158 firmware_sign_algorithm)) { |
| 143 Free(digest); | 159 Free(digest); |
| 144 return VERIFY_FIRMWARE_SIGNATURE_FAILED; | 160 return VERIFY_FIRMWARE_SIGNATURE_FAILED; |
| 145 } | 161 } |
| 146 Free(digest); | 162 Free(digest); |
| 147 return 0; | 163 return 0; |
| 148 } | 164 } |
| 149 | 165 |
| 150 int VerifyFirmware(const uint8_t* root_key_blob, | 166 int VerifyFirmware(const uint8_t* root_key_blob, |
| 151 const uint8_t* verification_header_blob, | 167 const uint8_t* verification_header_blob, |
| 152 const uint8_t* firmware_blob) { | 168 const uint8_t* firmware_blob) { |
| 153 int error_code = 0; | 169 int error_code = 0; |
| 154 int algorithm; /* Signing key algorithm. */ | 170 int firmware_sign_algorithm; /* Signing key algorithm. */ |
| 155 RSAPublicKey* firmware_sign_key = NULL; | 171 RSAPublicKey* firmware_sign_key = NULL; |
| 156 int firmware_sign_key_len, signature_len, header_len; | 172 int firmware_sign_key_len, signature_len, header_len; |
| 157 uint64_t firmware_len; | 173 uint64_t firmware_len; |
| 158 const uint8_t* header_ptr = NULL; /* Pointer to header. */ | 174 const uint8_t* header_ptr = NULL; /* Pointer to header. */ |
| 159 const uint8_t* firmware_sign_key_ptr = NULL; /* Pointer to signing key. */ | 175 const uint8_t* firmware_sign_key_ptr = NULL; /* Pointer to signing key. */ |
| 160 const uint8_t* preamble_ptr = NULL; /* Pointer to preamble block. */ | 176 const uint8_t* preamble_ptr = NULL; /* Pointer to preamble block. */ |
| 161 | 177 |
| 162 /* Note: All the offset calculations are based on struct FirmwareImage which | 178 /* Note: All the offset calculations are based on struct FirmwareImage which |
| 163 * is defined in include/firmware_image_fw.h. */ | 179 * is defined in include/firmware_image_fw.h. */ |
| 164 | 180 |
| 165 /* Compare magic bytes. */ | 181 /* Compare magic bytes. */ |
| 166 if (SafeMemcmp(verification_header_blob, FIRMWARE_MAGIC, | 182 if (SafeMemcmp(verification_header_blob, FIRMWARE_MAGIC, |
| 167 FIRMWARE_MAGIC_SIZE)) { | 183 FIRMWARE_MAGIC_SIZE)) { |
| 168 debug("Wrong Firmware Magic.\n"); | 184 debug("Wrong Firmware Magic.\n"); |
| 169 return VERIFY_FIRMWARE_WRONG_MAGIC; | 185 return VERIFY_FIRMWARE_WRONG_MAGIC; |
| 170 } | 186 } |
| 171 header_ptr = verification_header_blob + FIRMWARE_MAGIC_SIZE; | 187 header_ptr = verification_header_blob + FIRMWARE_MAGIC_SIZE; |
| 172 | 188 |
| 173 /* Only continue if header verification succeeds. */ | 189 /* Only continue if header verification succeeds. */ |
| 174 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, | 190 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, |
| 175 &algorithm, &header_len))) { | 191 &firmware_sign_algorithm, |
| 192 &header_len))) { |
| 176 debug("Couldn't verify Firmware header.\n"); | 193 debug("Couldn't verify Firmware header.\n"); |
| 177 return error_code; /* AKA jump to revovery. */ | 194 return error_code; /* AKA jump to revovery. */ |
| 178 } | 195 } |
| 179 /* Parse signing key into RSAPublicKey structure since it is required multiple | 196 /* Parse signing key into RSAPublicKey structure since it is required multiple |
| 180 * times. */ | 197 * times. */ |
| 181 firmware_sign_key_len = RSAProcessedKeySize(algorithm); | 198 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); |
| 182 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + | 199 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + |
| 183 FIELD_LEN(firmware_sign_algorithm) + | 200 FIELD_LEN(firmware_sign_algorithm) + |
| 184 FIELD_LEN(firmware_key_version)); | 201 FIELD_LEN(firmware_key_version)); |
| 185 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, | 202 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, |
| 186 firmware_sign_key_len); | 203 firmware_sign_key_len); |
| 187 signature_len = siglen_map[algorithm]; | 204 signature_len = siglen_map[firmware_sign_algorithm]; |
| 188 | 205 |
| 189 /* Only continue if preamble verification succeeds. */ | 206 /* Only continue if preamble verification succeeds. */ |
| 190 preamble_ptr = (header_ptr + header_len + | 207 preamble_ptr = (header_ptr + header_len + |
| 191 FIELD_LEN(firmware_key_signature)); | 208 FIELD_LEN(firmware_key_signature)); |
| 192 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, | 209 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, |
| 193 algorithm, | 210 firmware_sign_algorithm, |
| 194 &firmware_len))) { | 211 &firmware_len))) { |
| 195 RSAPublicKeyFree(firmware_sign_key); | 212 RSAPublicKeyFree(firmware_sign_key); |
| 196 debug("Couldn't verify Firmware preamble.\n"); | 213 debug("Couldn't verify Firmware preamble.\n"); |
| 197 return error_code; /* AKA jump to recovery. */ | 214 return error_code; /* AKA jump to recovery. */ |
| 198 } | 215 } |
| 199 | 216 |
| 200 if ((error_code = VerifyFirmwareData(firmware_sign_key, preamble_ptr, | 217 if ((error_code = VerifyFirmwareData(firmware_sign_key, preamble_ptr, |
| 201 firmware_blob, | 218 firmware_blob, |
| 202 firmware_len, | 219 firmware_len, |
| 203 algorithm))) { | 220 firmware_sign_algorithm))) { |
| 204 RSAPublicKeyFree(firmware_sign_key); | 221 RSAPublicKeyFree(firmware_sign_key); |
| 205 debug("Couldn't verify Firmware data.\n"); | 222 debug("Couldn't verify Firmware data.\n"); |
| 206 return error_code; /* AKA jump to recovery. */ | 223 return error_code; /* AKA jump to recovery. */ |
| 207 } | 224 } |
| 208 | 225 |
| 209 RSAPublicKeyFree(firmware_sign_key); | 226 RSAPublicKeyFree(firmware_sign_key); |
| 210 return VERIFY_FIRMWARE_SUCCESS; /* Success! */ | 227 return VERIFY_FIRMWARE_SUCCESS; /* Success! */ |
| 211 } | 228 } |
| 212 | 229 |
| 213 uint32_t GetLogicalFirmwareVersion(uint8_t* verification_header_blob) { | 230 uint32_t GetLogicalFirmwareVersion(uint8_t* verification_header_blob) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 */ | 336 */ |
| 320 if (stored_lversion <= firmwareB_lversion && | 337 if (stored_lversion <= firmwareB_lversion && |
| 321 (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, | 338 (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, |
| 322 verification_headerB, | 339 verification_headerB, |
| 323 firmwareB))) | 340 firmwareB))) |
| 324 return BOOT_FIRMWARE_B_CONTINUE; | 341 return BOOT_FIRMWARE_B_CONTINUE; |
| 325 } | 342 } |
| 326 /* D'oh: No bootable firmware. */ | 343 /* D'oh: No bootable firmware. */ |
| 327 return BOOT_FIRMWARE_RECOVERY_CONTINUE; | 344 return BOOT_FIRMWARE_RECOVERY_CONTINUE; |
| 328 } | 345 } |
| OLD | NEW |