Chromium Code Reviews| 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 "utility.h" | 13 #include "utility.h" |
| 14 | 14 |
| 15 /* Macro to determine the size of a field structure in the KernelImage | 15 /* Macro to determine the size of a field structure in the KernelImage |
| 16 * structure. */ | 16 * structure. */ |
| 17 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) | 17 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) |
| 18 | 18 |
| 19 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { | 19 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { |
| 20 "Success.", | 20 "Success.", |
| 21 "Invalid Image.", | 21 "Invalid Image.", |
| 22 "Kernel Key Signature Failed.", | 22 "Kernel Key Signature Failed.", |
| 23 "Invalid Kernel Verification Algorithm.", | 23 "Invalid Kernel Verification Algorithm.", |
| 24 "Config Signature Failed.", | 24 "Preamble Signature Failed.", |
| 25 "Kernel Signature Failed.", | 25 "Kernel Signature Failed.", |
| 26 "Wrong Kernel Magic.", | 26 "Wrong Kernel Magic.", |
| 27 }; | 27 }; |
| 28 | 28 |
| 29 inline uint64_t GetKernelPreambleLen(void) { | |
| 30 return (FIELD_LEN(kernel_version) + | |
| 31 FIELD_LEN(kernel_len) + | |
| 32 FIELD_LEN(bootloader_offset) + | |
| 33 FIELD_LEN(bootloader_size) + | |
| 34 FIELD_LEN(padded_header_size)); | |
| 35 } | |
| 36 | |
| 29 uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) { | 37 uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) { |
| 30 uint64_t len = 0; | 38 uint64_t len = 0; |
| 31 uint16_t firmware_sign_algorithm; | 39 uint16_t firmware_sign_algorithm; |
| 32 uint16_t kernel_sign_algorithm; | 40 uint16_t kernel_sign_algorithm; |
| 33 int algorithms_offset = (FIELD_LEN(magic) + | 41 int algorithms_offset = (FIELD_LEN(magic) + |
| 34 FIELD_LEN(header_version) + | 42 FIELD_LEN(header_version) + |
| 35 FIELD_LEN(header_len)); | 43 FIELD_LEN(header_len)); |
| 36 if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { | 44 if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { |
| 37 debug("Not a valid verified boot kernel blob.\n"); | 45 debug("Not a valid verified boot kernel blob.\n"); |
| 38 return 0; | 46 return 0; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 51 debug("Invalid kernel signing algorithm.\n"); | 59 debug("Invalid kernel signing algorithm.\n"); |
| 52 return 0; | 60 return 0; |
| 53 } | 61 } |
| 54 len = algorithms_offset; /* magic, header length and version. */ | 62 len = algorithms_offset; /* magic, header length and version. */ |
| 55 len += (FIELD_LEN(firmware_sign_algorithm) + | 63 len += (FIELD_LEN(firmware_sign_algorithm) + |
| 56 FIELD_LEN(kernel_sign_algorithm) + | 64 FIELD_LEN(kernel_sign_algorithm) + |
| 57 FIELD_LEN(kernel_key_version) + | 65 FIELD_LEN(kernel_key_version) + |
| 58 RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */ | 66 RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */ |
| 59 FIELD_LEN(header_checksum) + | 67 FIELD_LEN(header_checksum) + |
| 60 siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */ | 68 siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */ |
| 61 FIELD_LEN(kernel_version) + | 69 GetKernelPreambleLen() + |
| 62 FIELD_LEN(kernel_len) + | 70 siglen_map[kernel_sign_algorithm] + /* preamble_signature */ |
| 63 siglen_map[kernel_sign_algorithm] + /* config_signature */ | |
| 64 siglen_map[kernel_sign_algorithm]); /* kernel_signature */ | 71 siglen_map[kernel_sign_algorithm]); /* kernel_signature */ |
| 65 return len; | 72 return len; |
| 66 } | 73 } |
| 67 | 74 |
| 68 int VerifyKernelHeader(const uint8_t* firmware_key_blob, | 75 int VerifyKernelKeyHeader(const uint8_t* firmware_key_blob, |
| 69 const uint8_t* header_blob, | 76 const uint8_t* header_blob, |
| 70 const int dev_mode, | 77 const int dev_mode, |
| 71 int* firmware_algorithm, | 78 int* firmware_algorithm, |
| 72 int* kernel_algorithm, | 79 int* kernel_algorithm, |
| 73 int* kernel_header_len) { | 80 int* kernel_header_len) { |
| 74 int kernel_sign_key_len; | 81 int kernel_sign_key_len; |
| 75 int firmware_sign_key_len; | 82 int firmware_sign_key_len; |
| 76 uint16_t header_version, header_len; | 83 uint16_t header_version, header_len; |
| 77 uint16_t firmware_sign_algorithm, kernel_sign_algorithm; | 84 uint16_t firmware_sign_algorithm, kernel_sign_algorithm; |
| 78 uint8_t* header_checksum = NULL; | 85 uint8_t* header_checksum = NULL; |
| 79 | 86 |
| 80 /* Base Offset for the header_checksum field. Actual offset is | 87 /* Base Offset for the header_checksum field. Actual offset is |
| 81 * this + kernel_sign_key_len. */ | 88 * this + kernel_sign_key_len. */ |
| 82 int base_header_checksum_offset = (FIELD_LEN(header_version) + | 89 int base_header_checksum_offset = (FIELD_LEN(header_version) + |
| 83 FIELD_LEN(header_len) + | 90 FIELD_LEN(header_len) + |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 108 *firmware_algorithm = (int) firmware_sign_algorithm; | 115 *firmware_algorithm = (int) firmware_sign_algorithm; |
| 109 *kernel_algorithm = (int) kernel_sign_algorithm; | 116 *kernel_algorithm = (int) kernel_sign_algorithm; |
| 110 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); | 117 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); |
| 111 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); | 118 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); |
| 112 | 119 |
| 113 | 120 |
| 114 /* Verify if header len is correct? */ | 121 /* Verify if header len is correct? */ |
| 115 if (header_len != (base_header_checksum_offset + | 122 if (header_len != (base_header_checksum_offset + |
| 116 kernel_sign_key_len + | 123 kernel_sign_key_len + |
| 117 FIELD_LEN(header_checksum))) { | 124 FIELD_LEN(header_checksum))) { |
| 118 debug("VerifyKernelHeader: Header length mismatch\n"); | 125 debug("VerifyKernelKeyHeader: Header length mismatch\n"); |
| 119 return VERIFY_KERNEL_INVALID_IMAGE; | 126 return VERIFY_KERNEL_INVALID_IMAGE; |
| 120 } | 127 } |
| 121 *kernel_header_len = (int) header_len; | 128 *kernel_header_len = (int) header_len; |
| 122 | 129 |
| 123 /* Verify if the hash of the header is correct. */ | 130 /* Verify if the hash of the header is correct. */ |
| 124 header_checksum = DigestBuf(header_blob, | 131 header_checksum = DigestBuf(header_blob, |
| 125 header_len - FIELD_LEN(header_checksum), | 132 header_len - FIELD_LEN(header_checksum), |
| 126 SHA512_DIGEST_ALGORITHM); | 133 SHA512_DIGEST_ALGORITHM); |
| 127 if (SafeMemcmp(header_checksum, | 134 if (SafeMemcmp(header_checksum, |
| 128 header_blob + (base_header_checksum_offset + | 135 header_blob + (base_header_checksum_offset + |
| 129 kernel_sign_key_len), | 136 kernel_sign_key_len), |
| 130 FIELD_LEN(header_checksum))) { | 137 FIELD_LEN(header_checksum))) { |
| 131 Free(header_checksum); | 138 Free(header_checksum); |
| 132 debug("VerifyKernelHeader: Invalid header hash\n"); | 139 debug("VerifyKernelKeyHeader: Invalid header hash\n"); |
| 133 return VERIFY_KERNEL_INVALID_IMAGE; | 140 return VERIFY_KERNEL_INVALID_IMAGE; |
| 134 } | 141 } |
| 135 Free(header_checksum); | 142 Free(header_checksum); |
| 136 | 143 |
| 137 /* Verify kernel key signature unless we are in dev mode. */ | 144 /* Verify kernel key signature unless we are in dev mode. */ |
| 138 if (!dev_mode) { | 145 if (!dev_mode) { |
| 139 if (!RSAVerifyBinary_f(firmware_key_blob, NULL, /* Key to use */ | 146 if (!RSAVerifyBinary_f(firmware_key_blob, NULL, /* Key to use */ |
| 140 header_blob, /* Data to verify */ | 147 header_blob, /* Data to verify */ |
| 141 header_len, /* Length of data */ | 148 header_len, /* Length of data */ |
| 142 header_blob + header_len, /* Expected Signature */ | 149 header_blob + header_len, /* Expected Signature */ |
| 143 firmware_sign_algorithm)) | 150 firmware_sign_algorithm)) |
| 144 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; | 151 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; |
| 145 } | 152 } |
| 146 return 0; | 153 return 0; |
| 147 } | 154 } |
| 148 | 155 |
| 149 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, | 156 int VerifyKernelPreamble(RSAPublicKey* kernel_sign_key, |
| 150 const uint8_t* config_blob, | 157 const uint8_t* preamble_blob, |
| 151 int algorithm, | 158 int algorithm, |
| 152 uint64_t* kernel_len) { | 159 uint64_t* kernel_len) { |
| 153 int signature_len = siglen_map[algorithm]; | 160 int preamble_len = GetKernelPreambleLen(); |
| 154 const uint8_t* config_signature = NULL; | 161 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ |
| 155 const uint8_t* kernel_config = NULL; | 162 preamble_blob, /* Data to verify */ |
| 156 uint8_t* digest = NULL; | 163 preamble_len, /* Length of data */ |
| 157 DigestContext ctx; | 164 preamble_blob + preamble_len, /* Expected Signature */ |
| 158 | 165 algorithm)) |
| 159 config_signature = config_blob + (FIELD_LEN(kernel_version) + | 166 return VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; |
| 160 FIELD_LEN(kernel_len)); | |
| 161 kernel_config = config_signature + 2 * signature_len; /* kernel and config | |
| 162 * signature. */ | |
| 163 /* Since the kernel config signature is computed over the kernel version, | |
| 164 * kernel length and config, which does not form a contiguous region memory, | |
| 165 * we calculate the message digest ourselves. */ | |
| 166 DigestInit(&ctx, algorithm); | |
| 167 DigestUpdate(&ctx, | |
| 168 config_blob, | |
| 169 FIELD_LEN(kernel_version) + FIELD_LEN(kernel_len)); | |
| 170 DigestUpdate(&ctx, | |
| 171 kernel_config, | |
| 172 FIELD_LEN(kernel_config)); | |
| 173 digest = DigestFinal(&ctx); | |
| 174 if (!RSAVerifyBinaryWithDigest_f( | |
| 175 NULL, kernel_sign_key, /* Key to use. */ | |
| 176 digest, /* Digest of the Data to verify. */ | |
| 177 config_signature, /* Expected signature. */ | |
| 178 algorithm)) { | |
| 179 Free(digest); | |
| 180 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; | |
| 181 } | |
| 182 Free(digest); | |
| 183 Memcpy(kernel_len, | 167 Memcpy(kernel_len, |
| 184 config_blob + FIELD_LEN(kernel_version), | 168 preamble_blob + FIELD_LEN(kernel_version), |
| 185 FIELD_LEN(kernel_len)); | 169 FIELD_LEN(kernel_len)); |
| 186 return 0; | 170 return 0; |
| 187 } | 171 } |
| 188 | 172 |
| 189 int VerifyKernelData(RSAPublicKey* kernel_sign_key, | 173 int VerifyKernelData(RSAPublicKey* kernel_sign_key, |
| 190 const uint8_t* config_blob, | 174 const uint8_t* preamble_blob, |
| 191 const uint8_t* kernel_data, | 175 const uint8_t* kernel_data, |
| 192 uint64_t kernel_len, | 176 uint64_t kernel_len, |
| 193 int algorithm) { | 177 int algorithm) { |
| 194 int signature_len = siglen_map[algorithm]; | 178 int signature_len = siglen_map[algorithm]; |
| 195 const uint8_t* kernel_signature = NULL; | 179 const uint8_t* kernel_signature = NULL; |
| 196 const uint8_t* kernel_config = NULL; | |
| 197 uint8_t* digest = NULL; | 180 uint8_t* digest = NULL; |
| 198 DigestContext ctx; | 181 DigestContext ctx; |
| 199 | 182 |
| 200 kernel_signature = config_blob + (FIELD_LEN(kernel_version) + | 183 kernel_signature = preamble_blob + (GetKernelPreambleLen() + |
| 201 FIELD_LEN(kernel_len) + | 184 signature_len); |
| 202 signature_len); | |
| 203 kernel_config = kernel_signature + signature_len; | |
| 204 | 185 |
| 205 /* Since the kernel signature is computed over the kernel version, length, | 186 /* Since the kernel signature is computed over the kernel preamble |
| 206 * config cmd line, and kernel image data, which does not form a contiguous | 187 * and kernel image data, which does not form a contiguous |
| 207 * region of memory, we calculate the message digest ourselves. */ | 188 * region of memory, we calculate the message digest ourselves. */ |
| 208 DigestInit(&ctx, algorithm); | 189 DigestInit(&ctx, algorithm); |
| 209 DigestUpdate(&ctx, | 190 DigestUpdate(&ctx, |
| 210 config_blob, | 191 preamble_blob, |
| 211 FIELD_LEN(kernel_version) + FIELD_LEN(kernel_len)); | 192 GetKernelPreambleLen()); |
| 212 DigestUpdate(&ctx, kernel_config, | |
| 213 FIELD_LEN(kernel_config)); | |
| 214 DigestUpdate(&ctx, kernel_data, kernel_len); | 193 DigestUpdate(&ctx, kernel_data, kernel_len); |
| 215 digest = DigestFinal(&ctx); | 194 digest = DigestFinal(&ctx); |
| 216 if (!RSAVerifyBinaryWithDigest_f( | 195 if (!RSAVerifyBinaryWithDigest_f( |
| 217 NULL, kernel_sign_key, /* Key to use. */ | 196 NULL, kernel_sign_key, /* Key to use. */ |
| 218 digest, /* Digest of the data to verify. */ | 197 digest, /* Digest of the data to verify. */ |
| 219 kernel_signature, /* Expected Signature */ | 198 kernel_signature, /* Expected Signature */ |
| 220 algorithm)) { | 199 algorithm)) { |
| 221 Free(digest); | 200 Free(digest); |
| 222 return VERIFY_KERNEL_SIGNATURE_FAILED; | 201 return VERIFY_KERNEL_SIGNATURE_FAILED; |
| 223 } | 202 } |
| 224 Free(digest); | 203 Free(digest); |
| 225 return 0; | 204 return 0; |
| 226 } | 205 } |
| 227 | 206 |
| 207 int VerifyKernelHeader(const uint8_t* firmware_key_blob, | |
| 208 const uint8_t* kernel_header_blob, | |
| 209 const int dev_mode, | |
| 210 const uint8_t** preamble_blob, | |
| 211 const uint8_t** expected_kernel_signature, | |
| 212 RSAPublicKey** kernel_sign_key, | |
| 213 int* kernel_sign_algorithm, | |
| 214 uint64_t* kernel_len) { | |
| 215 int error_code; | |
| 216 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | |
| 217 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, | |
| 218 header_len; | |
| 219 const uint8_t* header_ptr; /* Pointer to header. */ | |
| 220 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ | |
| 221 | |
| 222 /* Note: All the offset calculations are based on struct FirmwareImage which | |
|
Randall Spangler
2010/05/26 16:35:23
KernelImage
| |
| 223 * is defined in include/firmware_image.h. */ | |
| 224 | |
| 225 /* Compare magic bytes. */ | |
| 226 if (SafeMemcmp(kernel_header_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) | |
| 227 return VERIFY_KERNEL_WRONG_MAGIC; | |
| 228 header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; | |
| 229 | |
| 230 /* Only continue if header verification succeeds. */ | |
| 231 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, | |
| 232 dev_mode, | |
| 233 &firmware_sign_algorithm, | |
| 234 kernel_sign_algorithm, | |
| 235 &header_len))) { | |
| 236 debug("VerifyKernelHeader: Kernel Key Header verification failed.\n"); | |
| 237 return error_code; /* AKA jump to recovery. */ | |
| 238 } | |
| 239 /* Parse signing key into RSAPublicKey structure since it is required multiple | |
| 240 * times. */ | |
| 241 kernel_sign_key_len = RSAProcessedKeySize(*kernel_sign_algorithm); | |
| 242 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + | |
| 243 FIELD_LEN(header_len) + | |
| 244 FIELD_LEN(firmware_sign_algorithm) + | |
| 245 FIELD_LEN(kernel_sign_algorithm) + | |
| 246 FIELD_LEN(kernel_key_version)); | |
| 247 *kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, | |
| 248 kernel_sign_key_len); | |
| 249 kernel_signature_len = siglen_map[*kernel_sign_algorithm]; | |
| 250 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; | |
| 251 | |
| 252 /* Only continue if preamble verification succeeds. */ | |
| 253 *preamble_blob = (header_ptr + header_len + kernel_key_signature_len); | |
| 254 if ((error_code = VerifyKernelPreamble(*kernel_sign_key, *preamble_blob, | |
| 255 *kernel_sign_algorithm, | |
| 256 kernel_len))) { | |
| 257 RSAPublicKeyFree(*kernel_sign_key); | |
| 258 return error_code; /* AKA jump to recovery. */ | |
| 259 } | |
| 260 *expected_kernel_signature = (*preamble_blob + | |
| 261 GetKernelPreambleLen() + | |
| 262 kernel_signature_len); /* Skip preamble. */ | |
| 263 return 0; | |
| 264 } | |
| 265 | |
| 228 int VerifyKernel(const uint8_t* firmware_key_blob, | 266 int VerifyKernel(const uint8_t* firmware_key_blob, |
| 229 const uint8_t* kernel_blob, | 267 const uint8_t* kernel_blob, |
| 230 const int dev_mode) { | 268 const int dev_mode) { |
| 231 int error_code; | 269 int error_code; |
| 232 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | 270 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ |
| 233 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ | 271 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ |
| 234 RSAPublicKey* kernel_sign_key; | 272 RSAPublicKey* kernel_sign_key; |
| 235 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, | 273 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, |
| 236 header_len; | 274 header_len; |
| 237 uint64_t kernel_len; | 275 uint64_t kernel_len; |
| 238 const uint8_t* header_ptr; /* Pointer to header. */ | 276 const uint8_t* header_ptr; /* Pointer to header. */ |
| 239 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ | 277 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ |
| 240 const uint8_t* config_ptr; /* Pointer to kernel config block. */ | 278 const uint8_t* preamble_ptr; /* Pointer to kernel preamble block. */ |
| 241 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ | 279 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ |
| 242 | 280 |
| 243 /* Note: All the offset calculations are based on struct FirmwareImage which | 281 /* Note: All the offset calculations are based on struct FirmwareImage which |
| 244 * is defined in include/firmware_image.h. */ | 282 * is defined in include/firmware_image.h. */ |
| 245 | 283 |
| 246 /* Compare magic bytes. */ | 284 /* Compare magic bytes. */ |
| 247 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) | 285 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) |
| 248 return VERIFY_KERNEL_WRONG_MAGIC; | 286 return VERIFY_KERNEL_WRONG_MAGIC; |
| 249 header_ptr = kernel_blob + KERNEL_MAGIC_SIZE; | 287 header_ptr = kernel_blob + KERNEL_MAGIC_SIZE; |
| 250 | 288 |
| 251 /* Only continue if header verification succeeds. */ | 289 /* Only continue if header verification succeeds. */ |
| 252 if ((error_code = VerifyKernelHeader(firmware_key_blob, header_ptr, dev_mode, | 290 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, dev_mod e, |
| 253 &firmware_sign_algorithm, | 291 &firmware_sign_algorithm, |
| 254 &kernel_sign_algorithm, &header_len))) { | 292 &kernel_sign_algorithm, &header_len))) { |
| 255 debug("VerifyKernel: Kernel header verification failed.\n"); | 293 debug("VerifyKernel: Kernel header verification failed.\n"); |
| 256 return error_code; /* AKA jump to recovery. */ | 294 return error_code; /* AKA jump to recovery. */ |
| 257 } | 295 } |
| 258 /* Parse signing key into RSAPublicKey structure since it is required multiple | 296 /* Parse signing key into RSAPublicKey structure since it is required multiple |
| 259 * times. */ | 297 * times. */ |
| 260 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); | 298 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); |
| 261 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + | 299 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + |
| 262 FIELD_LEN(header_len) + | 300 FIELD_LEN(header_len) + |
| 263 FIELD_LEN(firmware_sign_algorithm) + | 301 FIELD_LEN(firmware_sign_algorithm) + |
| 264 FIELD_LEN(kernel_sign_algorithm) + | 302 FIELD_LEN(kernel_sign_algorithm) + |
| 265 FIELD_LEN(kernel_key_version)); | 303 FIELD_LEN(kernel_key_version)); |
| 266 kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, | 304 kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, |
| 267 kernel_sign_key_len); | 305 kernel_sign_key_len); |
| 268 kernel_signature_len = siglen_map[kernel_sign_algorithm]; | 306 kernel_signature_len = siglen_map[kernel_sign_algorithm]; |
| 269 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; | 307 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; |
| 270 | 308 |
| 271 /* Only continue if config verification succeeds. */ | 309 /* Only continue if preamble verification succeeds. */ |
| 272 config_ptr = (header_ptr + header_len + kernel_key_signature_len); | 310 preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); |
| 273 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr, | 311 if ((error_code = VerifyKernelPreamble(kernel_sign_key, preamble_ptr, |
| 274 kernel_sign_algorithm, | 312 kernel_sign_algorithm, |
| 275 &kernel_len))) { | 313 &kernel_len))) { |
| 276 RSAPublicKeyFree(kernel_sign_key); | 314 RSAPublicKeyFree(kernel_sign_key); |
| 277 return error_code; /* AKA jump to recovery. */ | 315 return error_code; /* AKA jump to recovery. */ |
| 278 } | 316 } |
| 279 /* Only continue if kernel data verification succeeds. */ | 317 /* Only continue if kernel data verification succeeds. */ |
| 280 kernel_ptr = (config_ptr + | 318 kernel_ptr = (preamble_ptr + |
| 281 FIELD_LEN(kernel_version) + | 319 GetKernelPreambleLen() + |
| 282 FIELD_LEN(kernel_len) + | 320 2 * kernel_signature_len); /* preamble and kernel signature. */ |
| 283 2 * kernel_signature_len + /* config and kernel signature. */ | |
| 284 FIELD_LEN(kernel_config)); | |
| 285 | 321 |
| 286 if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */ | 322 if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */ |
| 287 config_ptr, /* Start of config block */ | 323 preamble_ptr, /* Start of preamble */ |
| 288 kernel_ptr, /* Start of kernel image */ | 324 kernel_ptr, /* Start of kernel image */ |
| 289 kernel_len, /* Length of kernel image. */ | 325 kernel_len, /* Length of kernel image. */ |
| 290 kernel_sign_algorithm))) { | 326 kernel_sign_algorithm))) { |
| 291 RSAPublicKeyFree(kernel_sign_key); | 327 RSAPublicKeyFree(kernel_sign_key); |
| 292 return error_code; /* AKA jump to recovery. */ | 328 return error_code; /* AKA jump to recovery. */ |
| 293 } | 329 } |
| 294 RSAPublicKeyFree(kernel_sign_key); | 330 RSAPublicKeyFree(kernel_sign_key); |
| 295 return 0; /* Success! */ | 331 return 0; /* Success! */ |
| 296 } | 332 } |
| 297 | 333 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 /* Lock Kernel TPM rollback indices from further writes. | 462 /* Lock Kernel TPM rollback indices from further writes. |
| 427 * TODO(gauravsh): Figure out if these can be combined into one | 463 * TODO(gauravsh): Figure out if these can be combined into one |
| 428 * 32-bit location since we seem to always use them together. This can help | 464 * 32-bit location since we seem to always use them together. This can help |
| 429 * us minimize the number of NVRAM writes/locks (which are limited over flash | 465 * us minimize the number of NVRAM writes/locks (which are limited over flash |
| 430 * memory lifetimes. | 466 * memory lifetimes. |
| 431 */ | 467 */ |
| 432 LockStoredVersion(KERNEL_KEY_VERSION); | 468 LockStoredVersion(KERNEL_KEY_VERSION); |
| 433 LockStoredVersion(KERNEL_VERSION); | 469 LockStoredVersion(KERNEL_VERSION); |
| 434 return kernel_to_boot; | 470 return kernel_to_boot; |
| 435 } | 471 } |
| OLD | NEW |