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

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

Issue 2810026: Add VBDEBUG macro for debug output. (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: 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 | « 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 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 "load_firmware_fw.h" 9 #include "load_firmware_fw.h"
10 #include "rollback_index.h" 10 #include "rollback_index.h"
(...skipping 28 matching lines...) Expand all
39 uint16_t tpm_key_version = 0; 39 uint16_t tpm_key_version = 0;
40 uint16_t tpm_fw_version = 0; 40 uint16_t tpm_fw_version = 0;
41 uint64_t lowest_key_version = 0xFFFF; 41 uint64_t lowest_key_version = 0xFFFF;
42 uint64_t lowest_fw_version = 0xFFFF; 42 uint64_t lowest_fw_version = 0xFFFF;
43 int good_index = -1; 43 int good_index = -1;
44 int index; 44 int index;
45 45
46 /* Clear output params in case we fail */ 46 /* Clear output params in case we fail */
47 params->firmware_index = 0; 47 params->firmware_index = 0;
48 48
49 debug("LoadFirmware started...\n"); 49 VBDEBUG(("LoadFirmware started...\n"));
50 50
51 if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { 51 if (params->kernel_sign_key_size < sizeof(VbPublicKey)) {
52 debug("Kernel sign key buffer too small\n"); 52 VBDEBUG(("Kernel sign key buffer too small\n"));
53 return LOAD_FIRMWARE_RECOVERY; 53 return LOAD_FIRMWARE_RECOVERY;
54 } 54 }
55 55
56 /* Must have a root key */ 56 /* Must have a root key */
57 if (!root_key) { 57 if (!root_key) {
58 debug("No root key\n"); 58 VBDEBUG(("No root key\n"));
59 return LOAD_FIRMWARE_RECOVERY; 59 return LOAD_FIRMWARE_RECOVERY;
60 } 60 }
61 61
62 /* Initialize the TPM and read rollback indices. */ 62 /* Initialize the TPM and read rollback indices. */
63 /* TODO: fix SetupTPM parameter for developer mode */ 63 /* TODO: fix SetupTPM parameter for developer mode */
64 if (0 != RollbackFirmwareSetup(0, &tpm_key_version, &tpm_fw_version)) { 64 if (0 != RollbackFirmwareSetup(0, &tpm_key_version, &tpm_fw_version)) {
65 debug("Unable to get stored versions.\n"); 65 VBDEBUG(("Unable to get stored versions.\n"));
66 return LOAD_FIRMWARE_RECOVERY; 66 return LOAD_FIRMWARE_RECOVERY;
67 } 67 }
68 68
69 /* Allocate our internal data */ 69 /* Allocate our internal data */
70 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); 70 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal));
71 if (!lfi) 71 if (!lfi)
72 return LOAD_FIRMWARE_RECOVERY; 72 return LOAD_FIRMWARE_RECOVERY;
73 params->load_firmware_internal = (uint8_t*)lfi; 73 params->load_firmware_internal = (uint8_t*)lfi;
74 74
75 /* Loop over indices */ 75 /* Loop over indices */
76 for (index = 0; index < 2; index++) { 76 for (index = 0; index < 2; index++) {
77 VbKeyBlockHeader* key_block; 77 VbKeyBlockHeader* key_block;
78 uint64_t vblock_size; 78 uint64_t vblock_size;
79 VbFirmwarePreambleHeader* preamble; 79 VbFirmwarePreambleHeader* preamble;
80 RSAPublicKey* data_key; 80 RSAPublicKey* data_key;
81 uint64_t key_version; 81 uint64_t key_version;
82 uint8_t* body_digest; 82 uint8_t* body_digest;
83 83
84 /* Verify the key block */ 84 /* Verify the key block */
85 if (0 == index) { 85 if (0 == index) {
86 key_block = (VbKeyBlockHeader*)params->verification_block_0; 86 key_block = (VbKeyBlockHeader*)params->verification_block_0;
87 vblock_size = params->verification_size_0; 87 vblock_size = params->verification_size_0;
88 } else { 88 } else {
89 key_block = (VbKeyBlockHeader*)params->verification_block_1; 89 key_block = (VbKeyBlockHeader*)params->verification_block_1;
90 vblock_size = params->verification_size_1; 90 vblock_size = params->verification_size_1;
91 } 91 }
92 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) { 92 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) {
93 debug("Key block verification failed.\n"); 93 VBDEBUG(("Key block verification failed.\n"));
94 continue; 94 continue;
95 } 95 }
96 96
97 /* Check for rollback of key version. */ 97 /* Check for rollback of key version. */
98 key_version = key_block->data_key.key_version; 98 key_version = key_block->data_key.key_version;
99 if (key_version < tpm_key_version) { 99 if (key_version < tpm_key_version) {
100 debug("Key rollback detected.\n"); 100 VBDEBUG(("Key rollback detected.\n"));
101 continue; 101 continue;
102 } 102 }
103 103
104 /* Get the key for preamble/data verification from the key block. */ 104 /* Get the key for preamble/data verification from the key block. */
105 data_key = PublicKeyToRSA(&key_block->data_key); 105 data_key = PublicKeyToRSA(&key_block->data_key);
106 if (!data_key) { 106 if (!data_key) {
107 debug("Unable to parse data key.\n"); 107 VBDEBUG(("Unable to parse data key.\n"));
108 continue; 108 continue;
109 } 109 }
110 110
111 /* Verify the preamble, which follows the key block. */ 111 /* Verify the preamble, which follows the key block. */
112 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + 112 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block +
113 key_block->key_block_size); 113 key_block->key_block_size);
114 if ((0 != VerifyFirmwarePreamble2(preamble, 114 if ((0 != VerifyFirmwarePreamble2(preamble,
115 vblock_size - key_block->key_block_size, 115 vblock_size - key_block->key_block_size,
116 data_key))) { 116 data_key))) {
117 debug("Preamble verfication failed.\n"); 117 VBDEBUG(("Preamble verfication failed.\n"));
118 RSAPublicKeyFree(data_key); 118 RSAPublicKeyFree(data_key);
119 continue; 119 continue;
120 } 120 }
121 121
122 /* Check for rollback of firmware version. */ 122 /* Check for rollback of firmware version. */
123 if (key_version == tpm_key_version && 123 if (key_version == tpm_key_version &&
124 preamble->firmware_version < tpm_fw_version) { 124 preamble->firmware_version < tpm_fw_version) {
125 debug("Firmware version rollback detected.\n"); 125 VBDEBUG(("Firmware version rollback detected.\n"));
126 RSAPublicKeyFree(data_key); 126 RSAPublicKeyFree(data_key);
127 continue; 127 continue;
128 } 128 }
129 129
130 /* Check for lowest key version from a valid header. */ 130 /* Check for lowest key version from a valid header. */
131 if (lowest_key_version > key_version) { 131 if (lowest_key_version > key_version) {
132 lowest_key_version = key_version; 132 lowest_key_version = key_version;
133 lowest_fw_version = preamble->firmware_version; 133 lowest_fw_version = preamble->firmware_version;
134 } 134 }
135 else if (lowest_key_version == key_version && 135 else if (lowest_key_version == key_version &&
136 lowest_fw_version > preamble->firmware_version) { 136 lowest_fw_version > preamble->firmware_version) {
137 lowest_fw_version = preamble->firmware_version; 137 lowest_fw_version = preamble->firmware_version;
138 } 138 }
139 139
140 /* If we already have good firmware, no need to read another one; 140 /* If we already have good firmware, no need to read another one;
141 * we only needed to look at the versions to check for 141 * we only needed to look at the versions to check for
142 * rollback. */ 142 * rollback. */
143 if (-1 != good_index) 143 if (-1 != good_index)
144 continue; 144 continue;
145 145
146 /* Read the firmware data */ 146 /* Read the firmware data */
147 DigestInit(&lfi->body_digest_context, data_key->algorithm); 147 DigestInit(&lfi->body_digest_context, data_key->algorithm);
148 lfi->body_size_accum = 0; 148 lfi->body_size_accum = 0;
149 if (0 != GetFirmwareBody(params, index)) { 149 if (0 != GetFirmwareBody(params, index)) {
150 debug("GetFirmwareBody() failed for index %d\n", index); 150 VBDEBUG(("GetFirmwareBody() failed for index %d\n", index));
151 RSAPublicKeyFree(data_key); 151 RSAPublicKeyFree(data_key);
152 continue; 152 continue;
153 } 153 }
154 if (lfi->body_size_accum != preamble->body_signature.data_size) { 154 if (lfi->body_size_accum != preamble->body_signature.data_size) {
155 debug("Hash updated %d bytes but expected %d\n", 155 VBDEBUG(("Hash updated %d bytes but expected %d\n",
156 (int)lfi->body_size_accum, (int)preamble->body_signature.data_size); 156 (int)lfi->body_size_accum,
157 (int)preamble->body_signature.data_size));
157 RSAPublicKeyFree(data_key); 158 RSAPublicKeyFree(data_key);
158 continue; 159 continue;
159 } 160 }
160 161
161 /* Verify firmware data */ 162 /* Verify firmware data */
162 body_digest = DigestFinal(&lfi->body_digest_context); 163 body_digest = DigestFinal(&lfi->body_digest_context);
163 if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { 164 if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) {
164 debug("Firmware body verification failed.\n"); 165 VBDEBUG(("Firmware body verification failed.\n"));
165 RSAPublicKeyFree(data_key); 166 RSAPublicKeyFree(data_key);
166 Free(body_digest); 167 Free(body_digest);
167 continue; 168 continue;
168 } 169 }
169 170
170 /* Done with the digest and data key, so can free them now */ 171 /* Done with the digest and data key, so can free them now */
171 RSAPublicKeyFree(data_key); 172 RSAPublicKeyFree(data_key);
172 Free(body_digest); 173 Free(body_digest);
173 174
174 /* If we're still here, the firmware is valid. */ 175 /* If we're still here, the firmware is valid. */
175 debug("Firmware %d is valid.\n", index); 176 VBDEBUG(("Firmware %d is valid.\n", index));
176 if (-1 == good_index) { 177 if (-1 == good_index) {
177 VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; 178 VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob;
178 179
179 /* Copy the kernel sign key blob into the destination buffer */ 180 /* Copy the kernel sign key blob into the destination buffer */
180 PublicKeyInit(kdest, (uint8_t*)(kdest + 1), 181 PublicKeyInit(kdest, (uint8_t*)(kdest + 1),
181 (params->kernel_sign_key_size - sizeof(VbPublicKey))); 182 (params->kernel_sign_key_size - sizeof(VbPublicKey)));
182 183
183 if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) { 184 if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) {
184 debug("Kernel subkey too big for buffer.\n"); 185 VBDEBUG(("Kernel subkey too big for buffer.\n"));
185 continue; /* The firmware signature was good, but the public 186 continue; /* The firmware signature was good, but the public
186 * key was bigger that the caller can handle. */ 187 * key was bigger that the caller can handle. */
187 } 188 }
188 189
189 /* Save the key size we actually used */ 190 /* Save the key size we actually used */
190 params->kernel_sign_key_size = kdest->key_offset + kdest->key_size; 191 params->kernel_sign_key_size = kdest->key_offset + kdest->key_size;
191 192
192 /* Save the good index, now that we're sure we can actually use 193 /* Save the good index, now that we're sure we can actually use
193 * this firmware. That's the one we'll boot. */ 194 * this firmware. That's the one we'll boot. */
194 good_index = index; 195 good_index = index;
(...skipping 15 matching lines...) Expand all
210 211
211 /* Handle finding good firmware */ 212 /* Handle finding good firmware */
212 if (good_index >= 0) { 213 if (good_index >= 0) {
213 214
214 /* Update TPM if necessary */ 215 /* Update TPM if necessary */
215 if ((lowest_key_version > tpm_key_version) || 216 if ((lowest_key_version > tpm_key_version) ||
216 (lowest_key_version == tpm_key_version && 217 (lowest_key_version == tpm_key_version &&
217 lowest_fw_version > tpm_fw_version)) { 218 lowest_fw_version > tpm_fw_version)) {
218 if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version, 219 if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version,
219 (uint16_t)lowest_fw_version)) { 220 (uint16_t)lowest_fw_version)) {
220 debug("Unable to write stored versions.\n"); 221 VBDEBUG(("Unable to write stored versions.\n"));
221 return LOAD_FIRMWARE_RECOVERY; 222 return LOAD_FIRMWARE_RECOVERY;
222 } 223 }
223 } 224 }
224 225
225 /* Lock firmware versions in TPM */ 226 /* Lock firmware versions in TPM */
226 if (0 != RollbackFirmwareLock()) { 227 if (0 != RollbackFirmwareLock()) {
227 debug("Unable to lock firmware versions.\n"); 228 VBDEBUG(("Unable to lock firmware versions.\n"));
228 return LOAD_FIRMWARE_RECOVERY; 229 return LOAD_FIRMWARE_RECOVERY;
229 } 230 }
230 231
231 /* Success */ 232 /* Success */
232 debug("Will boot firmware index %d\n", (int)params->firmware_index); 233 VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index));
233 return LOAD_FIRMWARE_SUCCESS; 234 return LOAD_FIRMWARE_SUCCESS;
234 } 235 }
235 236
236 /* If we're still here, no good firmware, so go to recovery mode. */ 237 /* If we're still here, no good firmware, so go to recovery mode. */
237 debug("Alas, no good firmware.\n"); 238 VBDEBUG(("Alas, no good firmware.\n"));
238 return LOAD_FIRMWARE_RECOVERY; 239 return LOAD_FIRMWARE_RECOVERY;
239 } 240 }
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