| 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 kernel image. | 5 * Functions for verifying a verified boot kernel image. |
| 6 * (Firmware portion) | 6 * (Firmware portion) |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "kernel_image_fw.h" | 9 #include "kernel_image_fw.h" |
| 10 | 10 |
| 11 #include "cryptolib.h" | 11 #include "cryptolib.h" |
| 12 #include "rollback_index.h" | 12 #include "rollback_index.h" |
| 13 #include "stateful_util.h" |
| 13 #include "utility.h" | 14 #include "utility.h" |
| 14 | 15 |
| 15 /* Macro to determine the size of a field structure in the KernelImage | 16 /* Macro to determine the size of a field structure in the KernelImage |
| 16 * structure. */ | 17 * structure. */ |
| 17 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) | 18 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) |
| 18 | 19 |
| 19 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { | 20 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { |
| 20 "Success.", | 21 "Success.", |
| 21 "Invalid Image.", | 22 "Invalid Image.", |
| 22 "Kernel Key Signature Failed.", | 23 "Kernel Key Signature Failed.", |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 kernel_data, /* Data to verify */ | 181 kernel_data, /* Data to verify */ |
| 181 kernel_len, /* Length of data */ | 182 kernel_len, /* Length of data */ |
| 182 kernel_signature, /* Expected Signature */ | 183 kernel_signature, /* Expected Signature */ |
| 183 algorithm)) | 184 algorithm)) |
| 184 return VERIFY_KERNEL_SIGNATURE_FAILED; | 185 return VERIFY_KERNEL_SIGNATURE_FAILED; |
| 185 return 0; | 186 return 0; |
| 186 } | 187 } |
| 187 | 188 |
| 188 int VerifyKernelHeader(const uint8_t* firmware_key_blob, | 189 int VerifyKernelHeader(const uint8_t* firmware_key_blob, |
| 189 const uint8_t* kernel_header_blob, | 190 const uint8_t* kernel_header_blob, |
| 191 uint64_t kernel_header_blob_len, |
| 190 const int dev_mode, | 192 const int dev_mode, |
| 191 const uint8_t** expected_kernel_signature, | 193 KernelImage *image, |
| 192 RSAPublicKey** kernel_sign_key, | 194 RSAPublicKey** kernel_sign_key) { |
| 193 int* kernel_sign_algorithm, | |
| 194 uint64_t* kernel_len) { | |
| 195 int error_code; | 195 int error_code; |
| 196 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | 196 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ |
| 197 int kernel_sign_algorithm; /* Kernel signing key algorithm. */ |
| 197 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, | 198 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, |
| 198 header_len; | 199 header_len; |
| 200 uint64_t kernel_len; |
| 199 const uint8_t* header_ptr = NULL; /* Pointer to key header. */ | 201 const uint8_t* header_ptr = NULL; /* Pointer to key header. */ |
| 200 const uint8_t* preamble_ptr = NULL; /* Pointer to start of preamble. */ | 202 const uint8_t* preamble_ptr = NULL; /* Pointer to start of preamble. */ |
| 201 const uint8_t* kernel_sign_key_ptr = NULL; /* Pointer to signing key. */ | 203 MemcpyState st; |
| 202 | 204 |
| 203 /* Note: All the offset calculations are based on struct FirmwareImage which | 205 /* Note: All the offset calculations are based on struct KernelImage which |
| 204 * is defined in include/firmware_image.h. */ | 206 * is defined in include/kernel_image_fw.h. */ |
| 207 st.remaining_buf = (void *)kernel_header_blob; |
| 208 st.remaining_len = kernel_header_blob_len; |
| 209 st.overrun = 0; |
| 205 | 210 |
| 206 /* Compare magic bytes. */ | 211 /* Clear destination image struct */ |
| 207 if (SafeMemcmp(kernel_header_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) | 212 Memset(image, 0, sizeof(KernelImage)); |
| 213 |
| 214 /* Read and compare magic bytes. */ |
| 215 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); |
| 216 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { |
| 208 return VERIFY_KERNEL_WRONG_MAGIC; | 217 return VERIFY_KERNEL_WRONG_MAGIC; |
| 218 } |
| 219 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); |
| 220 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); |
| 221 StatefulMemcpy(&st, &image->firmware_sign_algorithm, |
| 222 FIELD_LEN(firmware_sign_algorithm)); |
| 223 StatefulMemcpy(&st, &image->kernel_sign_algorithm, |
| 224 FIELD_LEN(kernel_sign_algorithm)); |
| 225 |
| 209 header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; | 226 header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; |
| 210 | 227 |
| 211 /* Only continue if header verification succeeds. */ | 228 /* Only continue if header verification succeeds. */ |
| 212 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, | 229 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, |
| 213 dev_mode, | 230 dev_mode, |
| 214 &firmware_sign_algorithm, | 231 &firmware_sign_algorithm, |
| 215 kernel_sign_algorithm, | 232 &kernel_sign_algorithm, |
| 216 &header_len))) { | 233 &header_len))) { |
| 217 debug("VerifyKernelHeader: Kernel Key Header verification failed.\n"); | 234 debug("VerifyKernelHeader: Kernel Key Header verification failed.\n"); |
| 218 return error_code; /* AKA jump to recovery. */ | 235 return error_code; /* AKA jump to recovery. */ |
| 219 } | 236 } |
| 220 /* Parse signing key into RSAPublicKey structure since it is required multiple | 237 |
| 221 * times. */ | 238 /* Read pre-processed public half of the kernel signing key. */ |
| 222 kernel_sign_key_len = RSAProcessedKeySize(*kernel_sign_algorithm); | 239 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); |
| 223 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + | 240 StatefulMemcpy(&st, &image->kernel_key_version, |
| 224 FIELD_LEN(header_len) + | 241 FIELD_LEN(kernel_key_version)); |
| 225 FIELD_LEN(firmware_sign_algorithm) + | 242 image->kernel_sign_key = (uint8_t*)st.remaining_buf; |
| 226 FIELD_LEN(kernel_sign_algorithm) + | 243 StatefulSkip(&st, kernel_sign_key_len); |
| 227 FIELD_LEN(kernel_key_version)); | 244 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); |
| 228 *kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, | 245 |
| 246 /* Parse signing key into RSAPublicKey structure since it is |
| 247 * required multiple times. */ |
| 248 *kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, |
| 229 kernel_sign_key_len); | 249 kernel_sign_key_len); |
| 230 kernel_signature_len = siglen_map[*kernel_sign_algorithm]; | 250 kernel_signature_len = siglen_map[kernel_sign_algorithm]; |
| 231 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; | 251 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; |
| 252 image->kernel_key_signature = (uint8_t*)st.remaining_buf; |
| 253 StatefulSkip(&st, kernel_signature_len); |
| 232 | 254 |
| 233 /* Only continue if preamble verification succeeds. */ | 255 /* Only continue if preamble verification succeeds. */ |
| 234 preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); | 256 /* TODO: should pass the remaining len into VerifyKernelPreamble() */ |
| 257 preamble_ptr = (const uint8_t*)st.remaining_buf; |
| 235 if ((error_code = VerifyKernelPreamble(*kernel_sign_key, preamble_ptr, | 258 if ((error_code = VerifyKernelPreamble(*kernel_sign_key, preamble_ptr, |
| 236 *kernel_sign_algorithm, | 259 kernel_sign_algorithm, |
| 237 kernel_len))) { | 260 &kernel_len))) { |
| 238 RSAPublicKeyFree(*kernel_sign_key); | 261 RSAPublicKeyFree(*kernel_sign_key); |
| 239 return error_code; /* AKA jump to recovery. */ | 262 return error_code; /* AKA jump to recovery. */ |
| 240 } | 263 } |
| 241 *expected_kernel_signature = (preamble_ptr + | 264 |
| 242 GetKernelPreambleLen(*kernel_sign_algorithm) - | 265 /* Copy preamble fields */ |
| 243 kernel_signature_len); /* Skip beginning of | 266 StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version)); |
| 244 * preamble. */ | 267 StatefulMemcpy(&st, &image->kernel_len, FIELD_LEN(kernel_len)); |
| 268 StatefulMemcpy(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)); |
| 269 StatefulMemcpy(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); |
| 270 StatefulMemcpy(&st, &image->padded_header_size, |
| 271 FIELD_LEN(padded_header_size)); |
| 272 image->kernel_signature = (uint8_t*)st.remaining_buf; |
| 273 StatefulSkip(&st, kernel_signature_len); |
| 274 image->preamble_signature = (uint8_t*)st.remaining_buf; |
| 275 |
| 245 return 0; | 276 return 0; |
| 246 } | 277 } |
| 247 | 278 |
| 248 int VerifyKernel(const uint8_t* firmware_key_blob, | 279 int VerifyKernel(const uint8_t* firmware_key_blob, |
| 249 const uint8_t* kernel_blob, | 280 const uint8_t* kernel_blob, |
| 250 const int dev_mode) { | 281 const int dev_mode) { |
| 251 int error_code; | 282 int error_code; |
| 252 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | 283 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ |
| 253 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ | 284 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ |
| 254 RSAPublicKey* kernel_sign_key; | 285 RSAPublicKey* kernel_sign_key; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 /* Lock Kernel TPM rollback indices from further writes. | 481 /* Lock Kernel TPM rollback indices from further writes. |
| 451 * TODO(gauravsh): Figure out if these can be combined into one | 482 * TODO(gauravsh): Figure out if these can be combined into one |
| 452 * 32-bit location since we seem to always use them together. This can help | 483 * 32-bit location since we seem to always use them together. This can help |
| 453 * us minimize the number of NVRAM writes/locks (which are limited over flash | 484 * us minimize the number of NVRAM writes/locks (which are limited over flash |
| 454 * memory lifetimes. | 485 * memory lifetimes. |
| 455 */ | 486 */ |
| 456 LockStoredVersion(KERNEL_KEY_VERSION); | 487 LockStoredVersion(KERNEL_KEY_VERSION); |
| 457 LockStoredVersion(KERNEL_VERSION); | 488 LockStoredVersion(KERNEL_VERSION); |
| 458 return kernel_to_boot; | 489 return kernel_to_boot; |
| 459 } | 490 } |
| OLD | NEW |