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 "Preamble 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) { | 29 inline uint64_t GetKernelPreambleLen(int algorithm) { |
30 return (FIELD_LEN(kernel_version) + | 30 return (FIELD_LEN(kernel_version) + |
31 FIELD_LEN(kernel_len) + | 31 FIELD_LEN(kernel_len) + |
32 FIELD_LEN(bootloader_offset) + | 32 FIELD_LEN(bootloader_offset) + |
33 FIELD_LEN(bootloader_size) + | 33 FIELD_LEN(bootloader_size) + |
34 FIELD_LEN(padded_header_size)); | 34 FIELD_LEN(padded_header_size) + |
| 35 siglen_map[algorithm]); |
35 } | 36 } |
36 | 37 |
37 uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) { | 38 uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) { |
38 uint64_t len = 0; | 39 uint64_t len = 0; |
39 uint16_t firmware_sign_algorithm; | 40 uint16_t firmware_sign_algorithm; |
40 uint16_t kernel_sign_algorithm; | 41 uint16_t kernel_sign_algorithm; |
41 int algorithms_offset = (FIELD_LEN(magic) + | 42 int algorithms_offset = (FIELD_LEN(magic) + |
42 FIELD_LEN(header_version) + | 43 FIELD_LEN(header_version) + |
43 FIELD_LEN(header_len)); | 44 FIELD_LEN(header_len)); |
44 if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { | 45 if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { |
(...skipping 14 matching lines...) Expand all Loading... |
59 debug("Invalid kernel signing algorithm.\n"); | 60 debug("Invalid kernel signing algorithm.\n"); |
60 return 0; | 61 return 0; |
61 } | 62 } |
62 len = algorithms_offset; /* magic, header length and version. */ | 63 len = algorithms_offset; /* magic, header length and version. */ |
63 len += (FIELD_LEN(firmware_sign_algorithm) + | 64 len += (FIELD_LEN(firmware_sign_algorithm) + |
64 FIELD_LEN(kernel_sign_algorithm) + | 65 FIELD_LEN(kernel_sign_algorithm) + |
65 FIELD_LEN(kernel_key_version) + | 66 FIELD_LEN(kernel_key_version) + |
66 RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */ | 67 RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */ |
67 FIELD_LEN(header_checksum) + | 68 FIELD_LEN(header_checksum) + |
68 siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */ | 69 siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */ |
69 GetKernelPreambleLen() + | 70 GetKernelPreambleLen(kernel_sign_algorithm) + |
70 siglen_map[kernel_sign_algorithm] + /* preamble_signature */ | 71 siglen_map[kernel_sign_algorithm]); /* preamble_signature */ |
71 siglen_map[kernel_sign_algorithm]); /* kernel_signature */ | |
72 return len; | 72 return len; |
73 } | 73 } |
74 | 74 |
75 int VerifyKernelKeyHeader(const uint8_t* firmware_key_blob, | 75 int VerifyKernelKeyHeader(const uint8_t* firmware_key_blob, |
76 const uint8_t* header_blob, | 76 const uint8_t* header_blob, |
77 const int dev_mode, | 77 const int dev_mode, |
78 int* firmware_algorithm, | 78 int* firmware_algorithm, |
79 int* kernel_algorithm, | 79 int* kernel_algorithm, |
80 int* kernel_header_len) { | 80 int* kernel_header_len) { |
81 int kernel_sign_key_len; | 81 int kernel_sign_key_len; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 firmware_sign_algorithm)) | 150 firmware_sign_algorithm)) |
151 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; | 151 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; |
152 } | 152 } |
153 return 0; | 153 return 0; |
154 } | 154 } |
155 | 155 |
156 int VerifyKernelPreamble(RSAPublicKey* kernel_sign_key, | 156 int VerifyKernelPreamble(RSAPublicKey* kernel_sign_key, |
157 const uint8_t* preamble_blob, | 157 const uint8_t* preamble_blob, |
158 int algorithm, | 158 int algorithm, |
159 uint64_t* kernel_len) { | 159 uint64_t* kernel_len) { |
160 int preamble_len = GetKernelPreambleLen(); | 160 int preamble_len = GetKernelPreambleLen(algorithm); |
161 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ | 161 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ |
162 preamble_blob, /* Data to verify */ | 162 preamble_blob, /* Data to verify */ |
163 preamble_len, /* Length of data */ | 163 preamble_len, /* Length of data */ |
164 preamble_blob + preamble_len, /* Expected Signature */ | 164 preamble_blob + preamble_len, /* Expected Signature */ |
165 algorithm)) | 165 algorithm)) |
166 return VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; | 166 return VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; |
167 Memcpy(kernel_len, | 167 Memcpy(kernel_len, |
168 preamble_blob + FIELD_LEN(kernel_version), | 168 preamble_blob + FIELD_LEN(kernel_version), |
169 FIELD_LEN(kernel_len)); | 169 FIELD_LEN(kernel_len)); |
170 return 0; | 170 return 0; |
171 } | 171 } |
172 | 172 |
173 int VerifyKernelData(RSAPublicKey* kernel_sign_key, | 173 int VerifyKernelData(RSAPublicKey* kernel_sign_key, |
174 const uint8_t* preamble_blob, | 174 const uint8_t* kernel_signature, |
175 const uint8_t* kernel_data, | 175 const uint8_t* kernel_data, |
176 uint64_t kernel_len, | 176 uint64_t kernel_len, |
177 int algorithm) { | 177 int algorithm) { |
178 int signature_len = siglen_map[algorithm]; | |
179 const uint8_t* kernel_signature = NULL; | |
180 uint8_t* digest = NULL; | |
181 DigestContext ctx; | |
182 | 178 |
183 kernel_signature = preamble_blob + (GetKernelPreambleLen() + | 179 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ |
184 signature_len); | 180 kernel_data, /* Data to verify */ |
185 | 181 kernel_len, /* Length of data */ |
186 /* Since the kernel signature is computed over the kernel preamble | 182 kernel_signature, /* Expected Signature */ |
187 * and kernel image data, which does not form a contiguous | 183 algorithm)) |
188 * region of memory, we calculate the message digest ourselves. */ | |
189 DigestInit(&ctx, algorithm); | |
190 DigestUpdate(&ctx, | |
191 preamble_blob, | |
192 GetKernelPreambleLen()); | |
193 DigestUpdate(&ctx, kernel_data, kernel_len); | |
194 digest = DigestFinal(&ctx); | |
195 if (!RSAVerifyBinaryWithDigest_f( | |
196 NULL, kernel_sign_key, /* Key to use. */ | |
197 digest, /* Digest of the data to verify. */ | |
198 kernel_signature, /* Expected Signature */ | |
199 algorithm)) { | |
200 Free(digest); | |
201 return VERIFY_KERNEL_SIGNATURE_FAILED; | 184 return VERIFY_KERNEL_SIGNATURE_FAILED; |
202 } | |
203 Free(digest); | |
204 return 0; | 185 return 0; |
205 } | 186 } |
206 | 187 |
207 int VerifyKernelHeader(const uint8_t* firmware_key_blob, | 188 int VerifyKernelHeader(const uint8_t* firmware_key_blob, |
208 const uint8_t* kernel_header_blob, | 189 const uint8_t* kernel_header_blob, |
209 const int dev_mode, | 190 const int dev_mode, |
210 const uint8_t** preamble_blob, | |
211 const uint8_t** expected_kernel_signature, | 191 const uint8_t** expected_kernel_signature, |
212 RSAPublicKey** kernel_sign_key, | 192 RSAPublicKey** kernel_sign_key, |
213 int* kernel_sign_algorithm, | 193 int* kernel_sign_algorithm, |
214 uint64_t* kernel_len) { | 194 uint64_t* kernel_len) { |
215 int error_code; | 195 int error_code; |
216 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | 196 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ |
217 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, | 197 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, |
218 header_len; | 198 header_len; |
219 const uint8_t* header_ptr; /* Pointer to header. */ | 199 const uint8_t* header_ptr = NULL; /* Pointer to key header. */ |
220 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ | 200 const uint8_t* preamble_ptr = NULL; /* Pointer to start of preamble. */ |
| 201 const uint8_t* kernel_sign_key_ptr = NULL; /* Pointer to signing key. */ |
221 | 202 |
222 /* Note: All the offset calculations are based on struct FirmwareImage which | 203 /* Note: All the offset calculations are based on struct FirmwareImage which |
223 * is defined in include/firmware_image.h. */ | 204 * is defined in include/firmware_image.h. */ |
224 | 205 |
225 /* Compare magic bytes. */ | 206 /* Compare magic bytes. */ |
226 if (SafeMemcmp(kernel_header_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) | 207 if (SafeMemcmp(kernel_header_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) |
227 return VERIFY_KERNEL_WRONG_MAGIC; | 208 return VERIFY_KERNEL_WRONG_MAGIC; |
228 header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; | 209 header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; |
229 | 210 |
230 /* Only continue if header verification succeeds. */ | 211 /* Only continue if header verification succeeds. */ |
(...skipping 12 matching lines...) Expand all Loading... |
243 FIELD_LEN(header_len) + | 224 FIELD_LEN(header_len) + |
244 FIELD_LEN(firmware_sign_algorithm) + | 225 FIELD_LEN(firmware_sign_algorithm) + |
245 FIELD_LEN(kernel_sign_algorithm) + | 226 FIELD_LEN(kernel_sign_algorithm) + |
246 FIELD_LEN(kernel_key_version)); | 227 FIELD_LEN(kernel_key_version)); |
247 *kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, | 228 *kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, |
248 kernel_sign_key_len); | 229 kernel_sign_key_len); |
249 kernel_signature_len = siglen_map[*kernel_sign_algorithm]; | 230 kernel_signature_len = siglen_map[*kernel_sign_algorithm]; |
250 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; | 231 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; |
251 | 232 |
252 /* Only continue if preamble verification succeeds. */ | 233 /* Only continue if preamble verification succeeds. */ |
253 *preamble_blob = (header_ptr + header_len + kernel_key_signature_len); | 234 preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); |
254 if ((error_code = VerifyKernelPreamble(*kernel_sign_key, *preamble_blob, | 235 if ((error_code = VerifyKernelPreamble(*kernel_sign_key, preamble_ptr, |
255 *kernel_sign_algorithm, | 236 *kernel_sign_algorithm, |
256 kernel_len))) { | 237 kernel_len))) { |
257 RSAPublicKeyFree(*kernel_sign_key); | 238 RSAPublicKeyFree(*kernel_sign_key); |
258 return error_code; /* AKA jump to recovery. */ | 239 return error_code; /* AKA jump to recovery. */ |
259 } | 240 } |
260 *expected_kernel_signature = (*preamble_blob + | 241 *expected_kernel_signature = (preamble_ptr + |
261 GetKernelPreambleLen() + | 242 GetKernelPreambleLen(*kernel_sign_algorithm) - |
262 kernel_signature_len); /* Skip preamble. */ | 243 kernel_signature_len); /* Skip beginning of |
| 244 * preamble. */ |
263 return 0; | 245 return 0; |
264 } | 246 } |
265 | 247 |
266 int VerifyKernel(const uint8_t* firmware_key_blob, | 248 int VerifyKernel(const uint8_t* firmware_key_blob, |
267 const uint8_t* kernel_blob, | 249 const uint8_t* kernel_blob, |
268 const int dev_mode) { | 250 const int dev_mode) { |
269 int error_code; | 251 int error_code; |
270 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ | 252 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ |
271 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ | 253 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ |
272 RSAPublicKey* kernel_sign_key; | 254 RSAPublicKey* kernel_sign_key; |
273 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, | 255 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, |
274 header_len; | 256 header_len; |
275 uint64_t kernel_len; | 257 uint64_t kernel_len; |
276 const uint8_t* header_ptr; /* Pointer to header. */ | 258 const uint8_t* header_ptr; /* Pointer to header. */ |
277 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ | 259 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ |
278 const uint8_t* preamble_ptr; /* Pointer to kernel preamble block. */ | 260 const uint8_t* preamble_ptr; /* Pointer to kernel preamble block. */ |
279 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ | 261 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ |
| 262 const uint8_t* kernel_signature; |
280 | 263 |
281 /* Note: All the offset calculations are based on struct FirmwareImage which | 264 /* Note: All the offset calculations are based on struct FirmwareImage which |
282 * is defined in include/firmware_image.h. */ | 265 * is defined in include/firmware_image.h. */ |
283 | 266 |
284 /* Compare magic bytes. */ | 267 /* Compare magic bytes. */ |
285 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) | 268 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { |
| 269 debug("VerifyKernel: Kernel magic bytes not found.\n"); |
286 return VERIFY_KERNEL_WRONG_MAGIC; | 270 return VERIFY_KERNEL_WRONG_MAGIC; |
| 271 } |
287 header_ptr = kernel_blob + KERNEL_MAGIC_SIZE; | 272 header_ptr = kernel_blob + KERNEL_MAGIC_SIZE; |
288 | 273 |
289 /* Only continue if header verification succeeds. */ | 274 /* Only continue if header verification succeeds. */ |
290 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, dev_mod
e, | 275 if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, dev_mod
e, |
291 &firmware_sign_algorithm, | 276 &firmware_sign_algorithm, |
292 &kernel_sign_algorithm, &header_len)))
{ | 277 &kernel_sign_algorithm, &header_len)))
{ |
293 debug("VerifyKernel: Kernel header verification failed.\n"); | 278 debug("VerifyKernel: Kernel header verification failed.\n"); |
294 return error_code; /* AKA jump to recovery. */ | 279 return error_code; /* AKA jump to recovery. */ |
295 } | 280 } |
296 /* Parse signing key into RSAPublicKey structure since it is required multiple | 281 /* Parse signing key into RSAPublicKey structure since it is required multiple |
297 * times. */ | 282 * times. */ |
298 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); | 283 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); |
299 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + | 284 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + |
300 FIELD_LEN(header_len) + | 285 FIELD_LEN(header_len) + |
301 FIELD_LEN(firmware_sign_algorithm) + | 286 FIELD_LEN(firmware_sign_algorithm) + |
302 FIELD_LEN(kernel_sign_algorithm) + | 287 FIELD_LEN(kernel_sign_algorithm) + |
303 FIELD_LEN(kernel_key_version)); | 288 FIELD_LEN(kernel_key_version)); |
304 kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, | 289 kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, |
305 kernel_sign_key_len); | 290 kernel_sign_key_len); |
306 kernel_signature_len = siglen_map[kernel_sign_algorithm]; | 291 kernel_signature_len = siglen_map[kernel_sign_algorithm]; |
307 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; | 292 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; |
308 | 293 |
309 /* Only continue if preamble verification succeeds. */ | 294 /* Only continue if preamble verification succeeds. */ |
310 preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); | 295 preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); |
311 if ((error_code = VerifyKernelPreamble(kernel_sign_key, preamble_ptr, | 296 if ((error_code = VerifyKernelPreamble(kernel_sign_key, preamble_ptr, |
312 kernel_sign_algorithm, | 297 kernel_sign_algorithm, |
313 &kernel_len))) { | 298 &kernel_len))) { |
| 299 debug("VerifyKernel: Kernel preamble verification failed.\n"); |
314 RSAPublicKeyFree(kernel_sign_key); | 300 RSAPublicKeyFree(kernel_sign_key); |
315 return error_code; /* AKA jump to recovery. */ | 301 return error_code; /* AKA jump to recovery. */ |
316 } | 302 } |
317 /* Only continue if kernel data verification succeeds. */ | 303 /* Only continue if kernel data verification succeeds. */ |
318 kernel_ptr = (preamble_ptr + | 304 kernel_ptr = (preamble_ptr + |
319 GetKernelPreambleLen() + | 305 GetKernelPreambleLen(kernel_sign_algorithm) + |
320 2 * kernel_signature_len); /* preamble and kernel signature. */ | 306 kernel_signature_len); /* preamble signature. */ |
| 307 kernel_signature = kernel_ptr - 2 * kernel_signature_len; /* end of kernel |
| 308 * preamble. */ |
321 | 309 |
322 if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */ | 310 if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */ |
323 preamble_ptr, /* Start of preamble */ | 311 kernel_signature, /* kernel signature */ |
324 kernel_ptr, /* Start of kernel image */ | 312 kernel_ptr, /* Start of kernel data */ |
325 kernel_len, /* Length of kernel image. */ | 313 kernel_len, /* Length of kernel data. */ |
326 kernel_sign_algorithm))) { | 314 kernel_sign_algorithm))) { |
327 RSAPublicKeyFree(kernel_sign_key); | 315 RSAPublicKeyFree(kernel_sign_key); |
328 return error_code; /* AKA jump to recovery. */ | 316 return error_code; /* AKA jump to recovery. */ |
329 } | 317 } |
330 RSAPublicKeyFree(kernel_sign_key); | 318 RSAPublicKeyFree(kernel_sign_key); |
331 return 0; /* Success! */ | 319 return 0; /* Success! */ |
332 } | 320 } |
333 | 321 |
334 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { | 322 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { |
335 uint8_t* kernel_ptr; | 323 uint8_t* kernel_ptr; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 /* Lock Kernel TPM rollback indices from further writes. | 450 /* Lock Kernel TPM rollback indices from further writes. |
463 * TODO(gauravsh): Figure out if these can be combined into one | 451 * TODO(gauravsh): Figure out if these can be combined into one |
464 * 32-bit location since we seem to always use them together. This can help | 452 * 32-bit location since we seem to always use them together. This can help |
465 * us minimize the number of NVRAM writes/locks (which are limited over flash | 453 * us minimize the number of NVRAM writes/locks (which are limited over flash |
466 * memory lifetimes. | 454 * memory lifetimes. |
467 */ | 455 */ |
468 LockStoredVersion(KERNEL_KEY_VERSION); | 456 LockStoredVersion(KERNEL_KEY_VERSION); |
469 LockStoredVersion(KERNEL_VERSION); | 457 LockStoredVersion(KERNEL_VERSION); |
470 return kernel_to_boot; | 458 return kernel_to_boot; |
471 } | 459 } |
OLD | NEW |