| 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 |