OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |