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

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

Issue 2327001: VerifyKernelHeader() fills a KernelImage* (Closed) Base URL: ssh://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 "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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698