Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: src/platform/vboot_reference/vboot_firmware/lib/kernel_image_fw.c

Issue 2292001: Make kernel signature a part of the kernel preamble. (Closed) Base URL: ssh://git@gitrw.chromium.org/chromiumos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698