diff options
Diffstat (limited to 'firmware/lib/vboot_common.c')
-rw-r--r-- | firmware/lib/vboot_common.c | 255 |
1 files changed, 0 insertions, 255 deletions
diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c index 56ba35df..3d5f2e22 100644 --- a/firmware/lib/vboot_common.c +++ b/firmware/lib/vboot_common.c @@ -123,261 +123,6 @@ int PublicKeyCopy(VbPublicKey *dest, const VbPublicKey *src) return 0; } -RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key) -{ - RSAPublicKey *rsa; - uint64_t key_size; - - if (kNumAlgorithms <= key->algorithm) { - VBDEBUG(("Invalid algorithm.\n")); - return NULL; - } - if (!RSAProcessedKeySize(key->algorithm, &key_size) || - key_size != key->key_size) { - VBDEBUG(("Wrong key size for algorithm\n")); - return NULL; - } - - rsa = RSAPublicKeyFromBuf(GetPublicKeyDataC(key), key->key_size); - if (!rsa) - return NULL; - - rsa->algorithm = (unsigned int)key->algorithm; - return rsa; -} - -int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig, - const RSAPublicKey *key) -{ - VBDEBUG((" - sig_size=%d, expecting %d for algorithm %d\n", - (unsigned)sig->sig_size, siglen_map[key->algorithm], - key->algorithm)); - if (sig->sig_size != siglen_map[key->algorithm]) { - VBDEBUG(("Wrong data signature size for algorithm, " - "sig_size=%d, expected %d for algorithm %d.\n", - (int)sig->sig_size, siglen_map[key->algorithm], - key->algorithm)); - return 1; - } - if (sig->data_size > size) { - VBDEBUG(("Data buffer smaller than length of signed data.\n")); - return 1; - } - - if (!RSAVerifyBinary_f(NULL, key, data, sig->data_size, - GetSignatureDataC(sig), key->algorithm)) - return 1; - - return 0; -} - -int VerifyDigest(const uint8_t *digest, const VbSignature *sig, - const RSAPublicKey *key) -{ - if (sig->sig_size != siglen_map[key->algorithm]) { - VBDEBUG(("Wrong digest signature size for algorithm.\n")); - return 1; - } - - if (!RSAVerifyBinaryWithDigest_f(NULL, key, digest, - GetSignatureDataC(sig), - key->algorithm)) - return 1; - - return 0; -} - -int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size, - const VbPublicKey *key, int hash_only) -{ - const VbSignature *sig; - - /* Sanity checks before attempting signature of data */ - if(size < sizeof(VbKeyBlockHeader)) { - VBDEBUG(("Not enough space for key block header.\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (vb2_safe_memcmp(block->magic, KEY_BLOCK_MAGIC, - KEY_BLOCK_MAGIC_SIZE)) { - VBDEBUG(("Not a valid verified boot key block.\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) { - VBDEBUG(("Incompatible key block header version.\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (size < block->key_block_size) { - VBDEBUG(("Not enough data for key block.\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (!hash_only && !key) { - VBDEBUG(("Missing required public key.\n")); - return VBOOT_PUBLIC_KEY_INVALID; - } - - /* - * Check signature or hash, depending on the hash_only parameter. Note - * that we don't require a key even if the keyblock has a signature, - * because the caller may not care if the keyblock itself is signed - * (for example, booting a Google-signed kernel in developer mode). - */ - if (hash_only) { - /* Check hash */ - uint8_t header_checksum[VB2_SHA512_DIGEST_SIZE]; - int rv; - - sig = &block->key_block_checksum; - - if (VerifySignatureInside(block, block->key_block_size, sig)) { - VBDEBUG(("Key block hash off end of block\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (sig->sig_size != VB2_SHA512_DIGEST_SIZE) { - VBDEBUG(("Wrong hash size for key block.\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - - /* Make sure advertised signature data sizes are sane. */ - if (block->key_block_size < sig->data_size) { - VBDEBUG(("Signature calculated past end of block\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - - VBDEBUG(("Checking key block hash only...\n")); - rv = vb2_digest_buffer((const uint8_t *)block, - sig->data_size, - VB2_HASH_SHA512, - header_checksum, - sizeof(header_checksum)); - if (!rv) - rv = vb2_safe_memcmp(header_checksum, - GetSignatureDataC(sig), - sizeof(header_checksum)); - - if (rv) { - VBDEBUG(("Invalid key block hash.\n")); - return VBOOT_KEY_BLOCK_HASH; - } - } else { - /* Check signature */ - RSAPublicKey *rsa; - int rv; - - sig = &block->key_block_signature; - - if (VerifySignatureInside(block, block->key_block_size, sig)) { - VBDEBUG(("Key block signature off end of block\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - - rsa = PublicKeyToRSA(key); - if (!rsa) { - VBDEBUG(("Invalid public key\n")); - return VBOOT_PUBLIC_KEY_INVALID; - } - - /* Make sure advertised signature data sizes are sane. */ - if (block->key_block_size < sig->data_size) { - VBDEBUG(("Signature calculated past end of block\n")); - RSAPublicKeyFree(rsa); - return VBOOT_KEY_BLOCK_INVALID; - } - - VBDEBUG(("Checking key block signature...\n")); - rv = VerifyData((const uint8_t *)block, size, sig, rsa); - RSAPublicKeyFree(rsa); - if (rv) { - VBDEBUG(("Invalid key block signature.\n")); - return VBOOT_KEY_BLOCK_SIGNATURE; - } - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(VbKeyBlockHeader)) { - VBDEBUG(("Didn't sign enough data\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - - /* Verify data key is inside the block and inside signed data */ - if (VerifyPublicKeyInside(block, block->key_block_size, - &block->data_key)) { - VBDEBUG(("Data key off end of key block\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - if (VerifyPublicKeyInside(block, sig->data_size, &block->data_key)) { - VBDEBUG(("Data key off end of signed data\n")); - return VBOOT_KEY_BLOCK_INVALID; - } - - /* Success */ - return VBOOT_SUCCESS; -} - -int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble, - uint64_t size, const RSAPublicKey *key) -{ - const VbSignature *sig = &preamble->preamble_signature; - - /* Sanity checks before attempting signature of data */ - if(size < sizeof(VbKernelPreambleHeader)) { - VBDEBUG(("Not enough data for preamble header.\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (preamble->header_version_major != - KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) { - VBDEBUG(("Incompatible kernel preamble header version.\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (size < preamble->preamble_size) { - VBDEBUG(("Not enough data for preamble.\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Check signature */ - if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { - VBDEBUG(("Preamble signature off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (VerifyData((const uint8_t *)preamble, size, sig, key)) { - VBDEBUG(("Preamble signature validation failed\n")); - return VBOOT_PREAMBLE_SIGNATURE; - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(VbKernelPreambleHeader)) { - VBDEBUG(("Didn't sign enough data\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Verify body signature is inside the signed data */ - if (VerifySignatureInside(preamble, sig->data_size, - &preamble->body_signature)) { - VBDEBUG(("Kernel body signature off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* - * If the preamble header version is at least 2.1, verify we have space - * for the added fields from >2.1. - */ - if (preamble->header_version_minor >= 1) { - if((preamble->header_version_minor == 1) && - (size < EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE)) { - VBDEBUG(("Not enough data for preamble header 2.1.\n")); - return VBOOT_PREAMBLE_INVALID; - } - - if((preamble->header_version_minor == 2) && - (size < EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE)) { - VBDEBUG(("Not enough data for preamble header 2.2.\n")); - return VBOOT_PREAMBLE_INVALID; - } - } - - /* Success */ - return VBOOT_SUCCESS; -} - int VbGetKernelVmlinuzHeader(const VbKernelPreambleHeader *preamble, uint64_t *vmlinuz_header_address, uint64_t *vmlinuz_header_size) |