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 * Common functions between firmware and kernel verified boot. | 5 * Common functions between firmware and kernel verified boot. |
6 * (Firmware portion) | 6 * (Firmware portion) |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "vboot_common.h" | 10 #include "vboot_common.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 119 |
120 rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), (int)key->key_size); | 120 rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), (int)key->key_size); |
121 if (!rsa) | 121 if (!rsa) |
122 return NULL; | 122 return NULL; |
123 | 123 |
124 rsa->algorithm = (int)key->algorithm; | 124 rsa->algorithm = (int)key->algorithm; |
125 return rsa; | 125 return rsa; |
126 } | 126 } |
127 | 127 |
128 | 128 |
129 int VerifyData(const uint8_t* data, const VbSignature *sig, | 129 int VerifyData(const uint8_t* data, uint64_t size, const VbSignature *sig, |
130 const RSAPublicKey* key) { | 130 const RSAPublicKey* key) { |
131 | 131 |
132 if (sig->sig_size != siglen_map[key->algorithm]) { | 132 if (sig->sig_size != siglen_map[key->algorithm]) { |
133 VBDEBUG(("Wrong signature size for algorithm.\n")); | 133 VBDEBUG(("Wrong signature size for algorithm.\n")); |
134 return 1; | 134 return 1; |
135 } | 135 } |
| 136 if (sig->data_size > size) { |
| 137 VBDEBUG(("Data buffer smaller than length of signed data.\n")); |
| 138 return 1; |
| 139 } |
136 | 140 |
137 if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size, | 141 if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size, |
138 GetSignatureDataC(sig), key->algorithm)) | 142 GetSignatureDataC(sig), key->algorithm)) |
139 return 1; | 143 return 1; |
140 | 144 |
141 return 0; | 145 return 0; |
142 } | 146 } |
143 | 147 |
144 | 148 |
145 int VerifyDigest(const uint8_t* digest, const VbSignature *sig, | 149 int VerifyDigest(const uint8_t* digest, const VbSignature *sig, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 if (!rsa) { | 198 if (!rsa) { |
195 VBDEBUG(("Invalid public key\n")); | 199 VBDEBUG(("Invalid public key\n")); |
196 return VBOOT_PUBLIC_KEY_INVALID; | 200 return VBOOT_PUBLIC_KEY_INVALID; |
197 } | 201 } |
198 | 202 |
199 /* Make sure advertised signature data sizes are sane. */ | 203 /* Make sure advertised signature data sizes are sane. */ |
200 if (block->key_block_size < sig->data_size) { | 204 if (block->key_block_size < sig->data_size) { |
201 VBDEBUG(("Signature calculated past end of the block\n")); | 205 VBDEBUG(("Signature calculated past end of the block\n")); |
202 return VBOOT_KEY_BLOCK_INVALID; | 206 return VBOOT_KEY_BLOCK_INVALID; |
203 } | 207 } |
204 rv = VerifyData((const uint8_t*)block, sig, rsa); | 208 rv = VerifyData((const uint8_t*)block, size, sig, rsa); |
205 RSAPublicKeyFree(rsa); | 209 RSAPublicKeyFree(rsa); |
206 if (rv) | 210 if (rv) |
207 return VBOOT_KEY_BLOCK_SIGNATURE; | 211 return VBOOT_KEY_BLOCK_SIGNATURE; |
208 } else { | 212 } else { |
209 /* Check hash */ | 213 /* Check hash */ |
210 uint8_t* header_checksum = NULL; | 214 uint8_t* header_checksum = NULL; |
211 int rv; | 215 int rv; |
212 | 216 |
213 sig = &block->key_block_checksum; | 217 sig = &block->key_block_checksum; |
214 | 218 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) { | 250 if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) { |
247 VBDEBUG(("Data key off end of signed data\n")); | 251 VBDEBUG(("Data key off end of signed data\n")); |
248 return VBOOT_KEY_BLOCK_INVALID; | 252 return VBOOT_KEY_BLOCK_INVALID; |
249 } | 253 } |
250 | 254 |
251 /* Success */ | 255 /* Success */ |
252 return VBOOT_SUCCESS; | 256 return VBOOT_SUCCESS; |
253 } | 257 } |
254 | 258 |
255 | 259 |
256 int VerifyFirmwarePreamble2(const VbFirmwarePreambleHeader* preamble, | 260 int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble, |
257 uint64_t size, const RSAPublicKey* key) { | 261 uint64_t size, const RSAPublicKey* key) { |
258 | 262 |
259 const VbSignature* sig = &preamble->preamble_signature; | 263 const VbSignature* sig = &preamble->preamble_signature; |
260 | 264 |
261 /* Sanity checks before attempting signature of data */ | 265 /* Sanity checks before attempting signature of data */ |
262 if (preamble->header_version_major != | 266 if (preamble->header_version_major != |
263 FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { | 267 FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { |
264 VBDEBUG(("Incompatible firmware preamble header version.\n")); | 268 VBDEBUG(("Incompatible firmware preamble header version.\n")); |
265 return VBOOT_PREAMBLE_INVALID; | 269 return VBOOT_PREAMBLE_INVALID; |
266 } | 270 } |
267 if (size < preamble->preamble_size) { | 271 if (size < preamble->preamble_size) { |
268 VBDEBUG(("Not enough data for preamble.\n")); | 272 VBDEBUG(("Not enough data for preamble.\n")); |
269 return VBOOT_PREAMBLE_INVALID; | 273 return VBOOT_PREAMBLE_INVALID; |
270 } | 274 } |
271 | 275 |
272 /* Check signature */ | 276 /* Check signature */ |
273 if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { | 277 if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { |
274 VBDEBUG(("Preamble signature off end of preamble\n")); | 278 VBDEBUG(("Preamble signature off end of preamble\n")); |
275 return VBOOT_PREAMBLE_INVALID; | 279 return VBOOT_PREAMBLE_INVALID; |
276 } | 280 } |
277 | 281 |
278 /* Make sure advertised signature data sizes are sane. */ | 282 /* Make sure advertised signature data sizes are sane. */ |
279 if (preamble->preamble_size < sig->data_size) { | 283 if (preamble->preamble_size < sig->data_size) { |
280 VBDEBUG(("Signature calculated past end of the block\n")); | 284 VBDEBUG(("Signature calculated past end of the block\n")); |
281 return VBOOT_PREAMBLE_INVALID; | 285 return VBOOT_PREAMBLE_INVALID; |
282 } | 286 } |
283 | 287 |
284 if (VerifyData((const uint8_t*)preamble, sig, key)) { | 288 if (VerifyData((const uint8_t*)preamble, size, sig, key)) { |
285 VBDEBUG(("Preamble signature validation failed\n")); | 289 VBDEBUG(("Preamble signature validation failed\n")); |
286 return VBOOT_PREAMBLE_SIGNATURE; | 290 return VBOOT_PREAMBLE_SIGNATURE; |
287 } | 291 } |
288 | 292 |
289 /* Verify we signed enough data */ | 293 /* Verify we signed enough data */ |
290 if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) { | 294 if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) { |
291 VBDEBUG(("Didn't sign enough data\n")); | 295 VBDEBUG(("Didn't sign enough data\n")); |
292 return VBOOT_PREAMBLE_INVALID; | 296 return VBOOT_PREAMBLE_INVALID; |
293 } | 297 } |
294 | 298 |
295 /* Verify body signature is inside the block */ | 299 /* Verify body signature is inside the block */ |
296 if (VerifySignatureInside(preamble, preamble->preamble_size, | 300 if (VerifySignatureInside(preamble, preamble->preamble_size, |
297 &preamble->body_signature)) { | 301 &preamble->body_signature)) { |
298 VBDEBUG(("Firmware body signature off end of preamble\n")); | 302 VBDEBUG(("Firmware body signature off end of preamble\n")); |
299 return VBOOT_PREAMBLE_INVALID; | 303 return VBOOT_PREAMBLE_INVALID; |
300 } | 304 } |
301 | 305 |
302 /* Verify kernel subkey is inside the block */ | 306 /* Verify kernel subkey is inside the block */ |
303 if (VerifyPublicKeyInside(preamble, preamble->preamble_size, | 307 if (VerifyPublicKeyInside(preamble, preamble->preamble_size, |
304 &preamble->kernel_subkey)) { | 308 &preamble->kernel_subkey)) { |
305 VBDEBUG(("Kernel subkey off end of preamble\n")); | 309 VBDEBUG(("Kernel subkey off end of preamble\n")); |
306 return VBOOT_PREAMBLE_INVALID; | 310 return VBOOT_PREAMBLE_INVALID; |
307 } | 311 } |
308 | 312 |
309 /* Success */ | 313 /* Success */ |
310 return VBOOT_SUCCESS; | 314 return VBOOT_SUCCESS; |
311 } | 315 } |
312 | 316 |
313 | 317 |
314 int VerifyKernelPreamble2(const VbKernelPreambleHeader* preamble, | 318 int VerifyKernelPreamble(const VbKernelPreambleHeader* preamble, |
315 uint64_t size, const RSAPublicKey* key) { | 319 uint64_t size, const RSAPublicKey* key) { |
316 | 320 |
317 const VbSignature* sig = &preamble->preamble_signature; | 321 const VbSignature* sig = &preamble->preamble_signature; |
318 | 322 |
319 /* Sanity checks before attempting signature of data */ | 323 /* Sanity checks before attempting signature of data */ |
320 if (preamble->header_version_major != KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { | 324 if (preamble->header_version_major != KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { |
321 VBDEBUG(("Incompatible kernel preamble header version.\n")); | 325 VBDEBUG(("Incompatible kernel preamble header version.\n")); |
322 return VBOOT_PREAMBLE_INVALID; | 326 return VBOOT_PREAMBLE_INVALID; |
323 } | 327 } |
324 if (size < preamble->preamble_size) { | 328 if (size < preamble->preamble_size) { |
325 VBDEBUG(("Not enough data for preamble.\n")); | 329 VBDEBUG(("Not enough data for preamble.\n")); |
326 return VBOOT_PREAMBLE_INVALID; | 330 return VBOOT_PREAMBLE_INVALID; |
327 } | 331 } |
328 | 332 |
329 /* Check signature */ | 333 /* Check signature */ |
330 if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { | 334 if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { |
331 VBDEBUG(("Preamble signature off end of preamble\n")); | 335 VBDEBUG(("Preamble signature off end of preamble\n")); |
332 return VBOOT_PREAMBLE_INVALID; | 336 return VBOOT_PREAMBLE_INVALID; |
333 } | 337 } |
334 if (VerifyData((const uint8_t*)preamble, sig, key)) { | 338 if (VerifyData((const uint8_t*)preamble, size, sig, key)) { |
335 VBDEBUG(("Preamble signature validation failed\n")); | 339 VBDEBUG(("Preamble signature validation failed\n")); |
336 return VBOOT_PREAMBLE_SIGNATURE; | 340 return VBOOT_PREAMBLE_SIGNATURE; |
337 } | 341 } |
338 | 342 |
339 /* Verify we signed enough data */ | 343 /* Verify we signed enough data */ |
340 if (sig->data_size < sizeof(VbKernelPreambleHeader)) { | 344 if (sig->data_size < sizeof(VbKernelPreambleHeader)) { |
341 VBDEBUG(("Didn't sign enough data\n")); | 345 VBDEBUG(("Didn't sign enough data\n")); |
342 return VBOOT_PREAMBLE_INVALID; | 346 return VBOOT_PREAMBLE_INVALID; |
343 } | 347 } |
344 | 348 |
345 /* Verify body signature is inside the block */ | 349 /* Verify body signature is inside the block */ |
346 if (VerifySignatureInside(preamble, preamble->preamble_size, | 350 if (VerifySignatureInside(preamble, preamble->preamble_size, |
347 &preamble->body_signature)) { | 351 &preamble->body_signature)) { |
348 VBDEBUG(("Kernel body signature off end of preamble\n")); | 352 VBDEBUG(("Kernel body signature off end of preamble\n")); |
349 return VBOOT_PREAMBLE_INVALID; | 353 return VBOOT_PREAMBLE_INVALID; |
350 } | 354 } |
351 | 355 |
352 /* Success */ | 356 /* Success */ |
353 return VBOOT_SUCCESS; | 357 return VBOOT_SUCCESS; |
354 } | 358 } |
OLD | NEW |