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