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

Side by Side Diff: firmware/lib/vboot_firmware.c

Issue 6626045: Pass VbSharedData between LoadFirmware() and LoadKernel() (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: Fixes from code review. Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « firmware/lib/vboot_common.c ('k') | firmware/lib/vboot_kernel.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010-2011 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2011 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 * High-level firmware API for loading and verifying rewritable firmware. 5 * High-level firmware API for loading and verifying rewritable firmware.
6 * (Firmware portion) 6 * (Firmware portion)
7 */ 7 */
8 8
9 #include "gbb_header.h"
9 #include "load_firmware_fw.h" 10 #include "load_firmware_fw.h"
10 #include "rollback_index.h" 11 #include "rollback_index.h"
11 #include "utility.h" 12 #include "utility.h"
12 #include "vboot_common.h" 13 #include "vboot_common.h"
13 #include "vboot_nvstorage.h" 14 #include "vboot_nvstorage.h"
14 15
15 /* Static variables for UpdateFirmwareBodyHash(). It's less than 16 /* Static variables for UpdateFirmwareBodyHash(). It's less than
16 * optimal to have static variables in a library, but in UEFI the 17 * optimal to have static variables in a library, but in UEFI the
17 * caller is deep inside a different firmware stack and doesn't have a 18 * caller is deep inside a different firmware stack and doesn't have a
18 * good way to pass the params struct back to us. */ 19 * good way to pass the params struct back to us. */
(...skipping 13 matching lines...) Expand all
32 } 33 }
33 34
34 35
35 int LoadFirmwareSetup(void) { 36 int LoadFirmwareSetup(void) {
36 /* TODO: start initializing the TPM */ 37 /* TODO: start initializing the TPM */
37 return LOAD_FIRMWARE_SUCCESS; 38 return LOAD_FIRMWARE_SUCCESS;
38 } 39 }
39 40
40 41
41 int LoadFirmware(LoadFirmwareParams* params) { 42 int LoadFirmware(LoadFirmwareParams* params) {
42 43 VbSharedDataHeader* shared = (VbSharedDataHeader*)params->shared_data_blob;
43 VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob; 44 GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)params->gbb_data;
45 VbPublicKey* root_key;
44 VbLoadFirmwareInternal* lfi; 46 VbLoadFirmwareInternal* lfi;
45 VbNvContext* vnc = params->nv_context; 47 VbNvContext* vnc = params->nv_context;
46 48
47 uint32_t try_b_count; 49 uint32_t try_b_count;
48 uint32_t tpm_version = 0; 50 uint32_t tpm_version = 0;
49 uint64_t lowest_version = 0xFFFFFFFF; 51 uint64_t lowest_version = 0xFFFFFFFF;
50 uint32_t status; 52 uint32_t status;
51 int good_index = -1; 53 int good_index = -1;
52 int is_dev; 54 int is_dev;
53 int index; 55 int index;
54 int i; 56 int i;
55 57
56 int retval = LOAD_FIRMWARE_RECOVERY; 58 int retval = LOAD_FIRMWARE_RECOVERY;
57 int recovery = VBNV_RECOVERY_RO_UNSPECIFIED; 59 int recovery = VBNV_RECOVERY_RO_UNSPECIFIED;
58 60
59 /* Clear output params in case we fail */ 61 /* Clear output params in case we fail */
60 params->firmware_index = 0; 62 params->firmware_index = 0;
61 63
62 VBDEBUG(("LoadFirmware started...\n")); 64 VBDEBUG(("LoadFirmware started...\n"));
63 65
64 /* Setup NV storage */ 66 /* Setup NV storage */
65 VbNvSetup(vnc); 67 VbNvSetup(vnc);
66 68
67 if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { 69 /* Initialize shared data structure. */
68 VBDEBUG(("Kernel sign key buffer too small\n")); 70 if (0 != VbSharedDataInit(shared, params->shared_data_size)) {
71 VBDEBUG(("Shared data init error\n"));
72 recovery = VBNV_RECOVERY_RO_SHARED_DATA;
69 goto LoadFirmwareExit; 73 goto LoadFirmwareExit;
70 } 74 }
71 75
72 /* Must have a root key */ 76 /* Must have a root key from the GBB */
73 if (!root_key) { 77 if (!gbb) {
74 VBDEBUG(("No root key\n")); 78 VBDEBUG(("No GBB\n"));
75 goto LoadFirmwareExit; 79 goto LoadFirmwareExit;
76 } 80 }
81 root_key = (VbPublicKey*)((uint8_t*)gbb + gbb->rootkey_offset);
77 82
78 /* Parse flags */ 83 /* Parse flags */
79 is_dev = (params->boot_flags & BOOT_FLAG_DEVELOPER ? 1 : 0); 84 is_dev = (params->boot_flags & BOOT_FLAG_DEVELOPER ? 1 : 0);
80 85
81 /* Initialize the TPM and read rollback indices. */ 86 /* Initialize the TPM and read rollback indices. */
82 VBPERFSTART("VB_TPMI"); 87 VBPERFSTART("VB_TPMI");
83 status = RollbackFirmwareSetup(is_dev, &tpm_version); 88 status = RollbackFirmwareSetup(is_dev, &tpm_version);
84 if (0 != status) { 89 if (0 != status) {
85 VBDEBUG(("Unable to setup TPM and read stored versions.\n")); 90 VBDEBUG(("Unable to setup TPM and read stored versions.\n"));
86 VBPERFEND("VB_TPMI"); 91 VBPERFEND("VB_TPMI");
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 233 }
229 VBPERFEND("VB_VFD"); 234 VBPERFEND("VB_VFD");
230 235
231 /* Done with the digest and data key, so can free them now */ 236 /* Done with the digest and data key, so can free them now */
232 RSAPublicKeyFree(data_key); 237 RSAPublicKeyFree(data_key);
233 Free(body_digest); 238 Free(body_digest);
234 239
235 /* If we're still here, the firmware is valid. */ 240 /* If we're still here, the firmware is valid. */
236 VBDEBUG(("Firmware %d is valid.\n", index)); 241 VBDEBUG(("Firmware %d is valid.\n", index));
237 if (-1 == good_index) { 242 if (-1 == good_index) {
238 VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; 243 /* Save the key we actually used */
239 244 if (0 != VbSharedDataSetKernelKey(shared, &preamble->kernel_subkey)) {
240 /* Copy the kernel sign key blob into the destination buffer */ 245 VBDEBUG(("Unable to save kernel subkey to shared data.\n"));
241 PublicKeyInit(kdest, (uint8_t*)(kdest + 1),
242 (params->kernel_sign_key_size - sizeof(VbPublicKey)));
243
244 if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) {
245 VBDEBUG(("Kernel subkey too big for buffer.\n"));
246 continue; /* The firmware signature was good, but the public 246 continue; /* The firmware signature was good, but the public
247 * key was bigger that the caller can handle. */ 247 * key was bigger that the caller can handle. */
248 } 248 }
249 249
250 /* Save the key size we actually used */
251 params->kernel_sign_key_size = kdest->key_offset + kdest->key_size;
252
253 /* Save the good index, now that we're sure we can actually use 250 /* Save the good index, now that we're sure we can actually use
254 * this firmware. That's the one we'll boot. */ 251 * this firmware. That's the one we'll boot. */
255 good_index = index; 252 good_index = index;
256 params->firmware_index = index; 253 params->firmware_index = index;
257 254
258 /* If the good firmware's key version is the same as the tpm, 255 /* If the good firmware's key version is the same as the tpm,
259 * then the TPM doesn't need updating; we can stop now. 256 * then the TPM doesn't need updating; we can stop now.
260 * Otherwise, we'll check all the other headers to see if they 257 * Otherwise, we'll check all the other headers to see if they
261 * contain a newer key. */ 258 * contain a newer key. */
262 if (combined_version == tpm_version) 259 if (combined_version == tpm_version)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 VBDEBUG(("Alas, no good firmware.\n")); 304 VBDEBUG(("Alas, no good firmware.\n"));
308 recovery = VBNV_RECOVERY_RO_INVALID_RW; 305 recovery = VBNV_RECOVERY_RO_INVALID_RW;
309 } 306 }
310 307
311 LoadFirmwareExit: 308 LoadFirmwareExit:
312 /* Store recovery request, if any, then tear down non-volatile storage */ 309 /* Store recovery request, if any, then tear down non-volatile storage */
313 VbNvSet(vnc, VBNV_RECOVERY_REQUEST, LOAD_FIRMWARE_RECOVERY == retval ? 310 VbNvSet(vnc, VBNV_RECOVERY_REQUEST, LOAD_FIRMWARE_RECOVERY == retval ?
314 recovery : VBNV_RECOVERY_NOT_REQUESTED); 311 recovery : VBNV_RECOVERY_NOT_REQUESTED);
315 VbNvTeardown(vnc); 312 VbNvTeardown(vnc);
316 313
314 /* Note that we don't reduce params->shared_data_size to shared->data_used,
315 * since we want to leave space for LoadKernel() to add to the shared data
316 * buffer. */
317
317 return retval; 318 return retval;
318 } 319 }
319 320
320 321
321 int S3Resume(void) { 322 int S3Resume(void) {
322 /* Resume the TPM */ 323 /* Resume the TPM */
323 uint32_t status = RollbackS3Resume(); 324 uint32_t status = RollbackS3Resume();
324 325
325 /* If we can't resume, just do a full reboot. No need to go to recovery 326 /* If we can't resume, just do a full reboot. No need to go to recovery
326 * mode here, since if the TPM is really broken we'll catch it on the 327 * mode here, since if the TPM is really broken we'll catch it on the
327 * next boot. */ 328 * next boot. */
328 if (status == TPM_SUCCESS) 329 if (status == TPM_SUCCESS)
329 return LOAD_FIRMWARE_SUCCESS; 330 return LOAD_FIRMWARE_SUCCESS;
330 else 331 else
331 return LOAD_FIRMWARE_REBOOT; 332 return LOAD_FIRMWARE_REBOOT;
332 } 333 }
OLDNEW
« no previous file with comments | « firmware/lib/vboot_common.c ('k') | firmware/lib/vboot_kernel.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698