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

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

Issue 2802002: Implemented pipelined hash calculation in LoadFirmware() (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Add comment Created 10 years, 6 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
« no previous file with comments | « vboot_firmware/lib/vboot_common.c ('k') | vboot_firmware/linktest/main.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 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 * 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 "vboot_firmware.h" 9 #include "vboot_firmware.h"
10 10
11 #include "load_firmware_fw.h" 11 #include "load_firmware_fw.h"
12 #include "rollback_index.h" 12 #include "rollback_index.h"
13 #include "utility.h" 13 #include "utility.h"
14 #include "vboot_common.h" 14 #include "vboot_common.h"
15 15
16 /* Static variables for UpdateFirmwareBodyHash(). It's less than
17 * optimal to have static variables in a library, but in UEFI the
18 * caller is deep inside a different firmware stack and doesn't have a
19 * good way to pass the params struct back to us. */
20 static DigestContext ctx;
21 static uint64_t body_size_accum = 0;
22 static int inside_load_firmware = 0;
16 23
17 void UpdateFirmwareBodyHash2(uint8_t* data, uint64_t size) { 24 void UpdateFirmwareBodyHash2(uint8_t* data, uint64_t size) {
18 /* TODO: actually update the hash. */ 25
26 if (!inside_load_firmware) {
27 debug("UpdateFirmwareBodyHash() called outside LoadFirmware()\n");
28 return;
29 }
30
31 DigestUpdate(&ctx, data, size);
32 body_size_accum += size;
19 } 33 }
20 34
21 35
22 int LoadFirmware2(LoadFirmwareParams* params) { 36 int LoadFirmware2(LoadFirmwareParams* params) {
23 37
24 VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob; 38 VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob;
25 39
26 uint16_t tpm_key_version = 0; 40 uint16_t tpm_key_version = 0;
27 uint16_t tpm_fw_version = 0; 41 uint16_t tpm_fw_version = 0;
28 uint64_t lowest_key_version = 0xFFFF; 42 uint64_t lowest_key_version = 0xFFFF;
(...skipping 20 matching lines...) Expand all
49 63
50 /* Loop over indices */ 64 /* Loop over indices */
51 for (index = 0; index < 2; index++) { 65 for (index = 0; index < 2; index++) {
52 VbKeyBlockHeader* key_block; 66 VbKeyBlockHeader* key_block;
53 uint64_t vblock_size; 67 uint64_t vblock_size;
54 VbFirmwarePreambleHeader* preamble; 68 VbFirmwarePreambleHeader* preamble;
55 RSAPublicKey* data_key; 69 RSAPublicKey* data_key;
56 uint64_t key_version; 70 uint64_t key_version;
57 uint8_t* body_data; 71 uint8_t* body_data;
58 uint64_t body_size; 72 uint64_t body_size;
73 uint8_t* body_digest;
59 74
60 /* Verify the key block */ 75 /* Verify the key block */
61 if (0 == index) { 76 if (0 == index) {
62 key_block = (VbKeyBlockHeader*)params->verification_block_0; 77 key_block = (VbKeyBlockHeader*)params->verification_block_0;
63 vblock_size = params->verification_size_0; 78 vblock_size = params->verification_size_0;
64 } else { 79 } else {
65 key_block = (VbKeyBlockHeader*)params->verification_block_1; 80 key_block = (VbKeyBlockHeader*)params->verification_block_1;
66 vblock_size = params->verification_size_1; 81 vblock_size = params->verification_size_1;
67 } 82 }
68 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) 83 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key)))
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 lowest_fw_version = preamble->firmware_version; 120 lowest_fw_version = preamble->firmware_version;
106 } 121 }
107 122
108 /* If we already have good firmware, no need to read another one; 123 /* If we already have good firmware, no need to read another one;
109 * we only needed to look at the versions to check for 124 * we only needed to look at the versions to check for
110 * rollback. */ 125 * rollback. */
111 if (-1 != good_index) 126 if (-1 != good_index)
112 continue; 127 continue;
113 128
114 /* Read the firmware data */ 129 /* Read the firmware data */
115 /* TODO: should set up hash for UpdateFirmwareBodyHash(). */ 130 DigestInit(&ctx, data_key->algorithm);
131 body_size_accum = 0;
132 inside_load_firmware = 1;
116 body_data = GetFirmwareBody(index, &body_size); 133 body_data = GetFirmwareBody(index, &body_size);
117 if (!body_data || (body_size != preamble->body_signature.data_size)) { 134 inside_load_firmware = 0;
135 body_digest = DigestFinal(&ctx);
136 if (!body_data || (body_size != preamble->body_signature.data_size) ||
137 (body_size_accum != body_size)) {
118 RSAPublicKeyFree(data_key); 138 RSAPublicKeyFree(data_key);
139 Free(body_digest);
119 continue; 140 continue;
120 } 141 }
121 142
122 /* Verify firmware data */ 143 /* Verify firmware data */
123 /* TODO: should use hash from UpdateFirmwareBodyHash() rather than 144 if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) {
124 * recalculating it in VerifyData(). */
125 if (0 != VerifyData(body_data, &preamble->body_signature, data_key)) {
126 RSAPublicKeyFree(data_key); 145 RSAPublicKeyFree(data_key);
146 Free(body_digest);
127 continue; 147 continue;
128 } 148 }
129 149
130 /* Done with the data key, so can free it now */ 150 /* Done with the digest and data key, so can free them now */
131 RSAPublicKeyFree(data_key); 151 RSAPublicKeyFree(data_key);
152 Free(body_digest);
132 153
133 /* If we're still here, the firmware is valid. */ 154 /* If we're still here, the firmware is valid. */
134 /* Save the first good firmware we find; that's the one we'll boot */ 155 /* Save the first good firmware we find; that's the one we'll boot */
135 if (-1 == good_index) { 156 if (-1 == good_index) {
136 good_index = index; 157 good_index = index;
137 params->firmware_index = index; 158 params->firmware_index = index;
138 params->kernel_sign_key_blob = &preamble->kernel_subkey; 159 params->kernel_sign_key_blob = &preamble->kernel_subkey;
139 params->kernel_sign_key_size = (preamble->kernel_subkey.key_offset + 160 params->kernel_sign_key_size = (preamble->kernel_subkey.key_offset +
140 preamble->kernel_subkey.key_size); 161 preamble->kernel_subkey.key_size);
141 162
(...skipping 23 matching lines...) Expand all
165 /* Lock Firmware TPM rollback indices from further writes. In 186 /* Lock Firmware TPM rollback indices from further writes. In
166 * this design, this is done by setting the globalLock bit, which 187 * this design, this is done by setting the globalLock bit, which
167 * is cleared only by TPM_Init at reboot. */ 188 * is cleared only by TPM_Init at reboot. */
168 if (0 != LockFirmwareVersions()) 189 if (0 != LockFirmwareVersions())
169 return LOAD_FIRMWARE_RECOVERY; 190 return LOAD_FIRMWARE_RECOVERY;
170 } 191 }
171 192
172 /* If we're still here, no good firmware, so go to recovery mode. */ 193 /* If we're still here, no good firmware, so go to recovery mode. */
173 return LOAD_FIRMWARE_RECOVERY; 194 return LOAD_FIRMWARE_RECOVERY;
174 } 195 }
OLDNEW
« no previous file with comments | « vboot_firmware/lib/vboot_common.c ('k') | vboot_firmware/linktest/main.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698