summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2016-10-14 11:04:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-10-29 19:41:08 -0700
commit13b109762a3bfec025a9bfcb3ead927d0291280e (patch)
tree7cc62ff1a42b8979223ab0ee3894cd70bcb71983
parentf41cd04d9eeefe7b7b98c67484ee96ba4fbf1125 (diff)
downloadvboot-13b109762a3bfec025a9bfcb3ead927d0291280e.tar.gz
vboot: use vb2 verification functions for kernel verification
This removes old vboot1 functions in favor of the new vboot2 functions. BUG=chromium:611535 BRANCH=none TEST=make runtests; emerge-kevin coreboot depthcharge Change-Id: Idc64f7714bbd9d4fa82d14b6b5d73d71c61de854 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/400900 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--Makefile10
-rw-r--r--firmware/2lib/include/2common.h6
-rw-r--r--firmware/lib/include/vboot_common.h42
-rw-r--r--firmware/lib/vboot_api_kernel.c69
-rw-r--r--firmware/lib/vboot_common.c255
-rw-r--r--firmware/lib/vboot_kernel.c88
-rw-r--r--firmware/lib20/kernel.c2
-rw-r--r--firmware/linktest/main.c5
-rw-r--r--tests/vboot_api_kernel5_tests.c75
-rw-r--r--tests/vboot_common2_tests.c303
-rw-r--r--tests/vboot_common3_tests.c270
-rw-r--r--tests/vboot_kernel_tests.c76
12 files changed, 209 insertions, 992 deletions
diff --git a/Makefile b/Makefile
index f2969d1d..91e48ccc 100644
--- a/Makefile
+++ b/Makefile
@@ -740,8 +740,6 @@ TEST_NAMES = \
tests/vboot_api_kernel6_tests \
tests/vboot_audio_tests \
tests/vboot_common_tests \
- tests/vboot_common2_tests \
- tests/vboot_common3_tests \
tests/vboot_display_tests \
tests/vboot_kernel_tests \
tests/vboot_nvstorage_test \
@@ -941,7 +939,7 @@ fwlinktest: ${BUILD}/firmware/linktest/main
.PHONY: fwlib
fwlib: $(if ${FIRMWARE_ARCH},${FWLIB},fwlinktest)
-${FWLIB}: ${FWLIB_OBJS} ${FWLIB2X_OBJS}
+${FWLIB}: ${FWLIB_OBJS} ${FWLIB2X_OBJS} ${FWLIB20_OBJS}
@${PRINTF} " RM $(subst ${BUILD}/,,$@)\n"
${Q}rm -f $@
@${PRINTF} " AR $(subst ${BUILD}/,,$@)\n"
@@ -1260,8 +1258,6 @@ ${BUILD}/utility/bdb_extend: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/bdb_extend: LIBS += ${UTILBDB} ${FWLIB2X}
${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS}
-${BUILD}/tests/vboot_common2_tests: LDLIBS += ${CRYPTO_LIBS}
-${BUILD}/tests/vboot_common3_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb20_common2_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb20_common3_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/verify_kernel: LDLIBS += ${CRYPTO_LIBS}
@@ -1438,8 +1434,6 @@ endif
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel6_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_audio_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_common_tests
- ${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS}
- ${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS}
${RUNTEST} ${BUILD_RUN}/tests/vboot_display_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_kernel_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_nvstorage_test
@@ -1488,8 +1482,6 @@ runfutiltests: test_setup
# Not run by automated build.
.PHONY: runlongtests
runlongtests: test_setup genkeys genfuzztestcases
- ${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS} --all
- ${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS} --all
${RUNTEST} ${BUILD_RUN}/tests/vb20_common2_tests ${TEST_KEYS} --all
${RUNTEST} ${BUILD_RUN}/tests/vb20_common3_tests ${TEST_KEYS} --all
${RUNTEST} ${BUILD_RUN}/tests/vb21_common2_tests ${TEST_KEYS} --all
diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h
index 4622ab13..39c8caff 100644
--- a/firmware/2lib/include/2common.h
+++ b/firmware/2lib/include/2common.h
@@ -194,4 +194,10 @@ const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm hash_alg);
/* Size of work buffer sufficient for vb2_verify_fw_preamble() worst case. */
#define VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES
+/*
+ * Size of work buffer sufficient for vb2_verify_kernel_preamble() worst
+ * case.
+ */
+#define VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES
+
#endif /* VBOOT_REFERENCE_VBOOT_2COMMON_H_ */
diff --git a/firmware/lib/include/vboot_common.h b/firmware/lib/include/vboot_common.h
index 5b783e27..762448bb 100644
--- a/firmware/lib/include/vboot_common.h
+++ b/firmware/lib/include/vboot_common.h
@@ -90,48 +90,6 @@ void PublicKeyInit(VbPublicKey *key, uint8_t *key_data, uint64_t key_size);
int PublicKeyCopy(VbPublicKey *dest, const VbPublicKey *src);
/**
- * Convert a public key to RsaPublicKey format. The returned key must be freed
- * using RSAPublicKeyFree().
- *
- * Returns NULL if error.
- */
-RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key);
-
-/**
- * Verify [data] matches signature [sig] using [key]. [size] is the size of
- * the data buffer; the amount of data to be validated is contained in
- * sig->data_size.
- */
-int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
- const RSAPublicKey *key);
-
-/**
- * Verify a secure hash digest from vb2_digest_buffer() or
- * vb2_digest_finalize(), using [key]. Returns 0 on success.
- */
-int VerifyDigest(const uint8_t *digest, const VbSignature *sig,
- const RSAPublicKey *key);
-
-/**
- * Check the sanity of a key block of size [size] bytes, using public key
- * [key]. If hash_only is non-zero, uses only the block checksum to verify the
- * key block. Header fields are also checked for sanity. Does not verify key
- * index or key block flags.
- */
-int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
- const VbPublicKey *key, int hash_only);
-
-/**
- * Check the sanity of a kernel preamble of size [size] bytes, using public key
- * [key].
- *
- * Returns VBOOT_SUCCESS if successful.
- */
-int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
- uint64_t size, const RSAPublicKey *key);
-
-
-/**
* Retrieve the 16-bit vmlinuz header address and size from the kernel preamble
* if there is one. These are only available in Kernel Preamble Header version
* >= 2.1. If given a header 2.0 or lower, will set address and size to 0 (this
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 1360971f..6f896fbf 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -9,12 +9,14 @@
#include "2sysincludes.h"
#include "2common.h"
+#include "2rsa.h"
#include "gbb_access.h"
#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "region.h"
#include "rollback_index.h"
#include "utility.h"
+#include "vb2_common.h"
#include "vboot_api.h"
#include "vboot_audio.h"
#include "vboot_common.h"
@@ -1335,12 +1337,13 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
VbKeyBlockHeader *key_block;
VbSharedDataHeader *shared =
(VbSharedDataHeader *)cparams->shared_data_blob;
- RSAPublicKey *data_key = NULL;
VbKernelPreambleHeader *preamble;
uint64_t body_offset;
int hash_only = 0;
int dev_switch;
uint32_t allow_fastboot_full_cap = 0;
+ uint8_t *workbuf = NULL;
+ struct vb2_workbuf wb;
if ((boot_image == NULL) || (image_size == 0))
return VBERROR_INVALID_PARAMETER;
@@ -1399,10 +1402,35 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
/* If we fail at any step, retval returned would be invalid kernel. */
retval = VBERROR_INVALID_KERNEL_FOUND;
+ /* Allocate work buffer */
+ workbuf = (uint8_t *)
+ VbExMalloc(VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+ if (!workbuf)
+ goto fail;
+ vb2_workbuf_init(&wb, workbuf,
+ VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+
/* Verify the key block. */
key_block = (VbKeyBlockHeader *)kbuf;
- if (0 != KeyBlockVerify(key_block, image_size, kernel_subkey,
- hash_only)) {
+ struct vb2_keyblock *keyblock2 = (struct vb2_keyblock *)kbuf;
+ int rv;
+ if (hash_only) {
+ rv = vb2_verify_keyblock_hash(keyblock2, image_size, &wb);
+ } else {
+ /* Unpack kernel subkey */
+ struct vb2_public_key kernel_subkey2;
+ if (VB2_SUCCESS != vb2_unpack_key(&kernel_subkey2,
+ (const uint8_t *)kernel_subkey,
+ kernel_subkey->key_offset +
+ kernel_subkey->key_size)) {
+ VBDEBUG(("Unable to unpack kernel subkey\n"));
+ goto fail;
+ }
+ rv = vb2_verify_keyblock(keyblock2, image_size,
+ &kernel_subkey2, &wb);
+ }
+
+ if (VB2_SUCCESS != rv) {
VBDEBUG(("Verifying key block signature/hash failed.\n"));
goto fail;
}
@@ -1423,18 +1451,27 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
}
/* Get key for preamble/data verification from the key block. */
- data_key = PublicKeyToRSA(&key_block->data_key);
- if (!data_key) {
- VBDEBUG(("Data key bad.\n"));
+ struct vb2_public_key data_key2;
+ if (VB2_SUCCESS !=
+ vb2_unpack_key(&data_key2,
+ (const uint8_t *)&keyblock2->data_key,
+ keyblock2->data_key.key_offset +
+ keyblock2->data_key.key_size)) {
+ VBDEBUG(("Unable to unpack kernel data key\n"));
goto fail;
}
/* Verify the preamble, which follows the key block */
preamble = (VbKernelPreambleHeader *)(kbuf + key_block->key_block_size);
- if ((0 != VerifyKernelPreamble(preamble,
- image_size -
- key_block->key_block_size,
- data_key))) {
+ struct vb2_kernel_preamble *preamble2 =
+ (struct vb2_kernel_preamble *)
+ (kbuf + key_block->key_block_size);
+
+ if (VB2_SUCCESS != vb2_verify_kernel_preamble(
+ preamble2,
+ image_size - key_block->key_block_size,
+ &data_key2,
+ &wb)) {
VBDEBUG(("Preamble verification failed.\n"));
goto fail;
}
@@ -1443,9 +1480,11 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
/* Verify kernel data */
body_offset = key_block->key_block_size + preamble->preamble_size;
- if (0 != VerifyData((const uint8_t *)(kbuf + body_offset),
- image_size - body_offset,
- &preamble->body_signature, data_key)) {
+ if (VB2_SUCCESS != vb2_verify_data(
+ (const uint8_t *)(kbuf + body_offset),
+ image_size - body_offset,
+ (struct vb2_signature *)&preamble->body_signature,
+ &data_key2, &wb)) {
VBDEBUG(("Kernel data verification failed.\n"));
goto fail;
}
@@ -1464,10 +1503,10 @@ VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams,
fail:
VbApiKernelFree(cparams);
- if (NULL != data_key)
- RSAPublicKeyFree(data_key);
if (NULL != kernel_subkey)
VbExFree(kernel_subkey);
+ if (NULL != workbuf)
+ VbExFree(workbuf);
return retval;
}
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)
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index be5389a4..cf6f92bc 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -7,8 +7,10 @@
*/
#include "sysincludes.h"
+#include "2sysincludes.h"
#include "2common.h"
+#include "2rsa.h"
#include "2sha.h"
#include "cgptlib.h"
#include "cgptlib_internal.h"
@@ -19,6 +21,7 @@
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
+#include "vb2_common.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"
@@ -37,14 +40,14 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
VbSharedDataHeader *shared =
(VbSharedDataHeader *)params->shared_data_blob;
VbSharedDataKernelCall *shcall = NULL;
- VbNvContext* vnc = params->nv_context;
- VbPublicKey* kernel_subkey = NULL;
+ VbNvContext *vnc = params->nv_context;
+ VbPublicKey *kernel_subkey = NULL;
int free_kernel_subkey = 0;
GptData gpt;
uint64_t part_start, part_size;
uint64_t blba;
uint64_t kbuf_sectors;
- uint8_t* kbuf = NULL;
+ uint8_t *kbuf = NULL;
int found_partitions = 0;
int good_partition = -1;
int good_partition_key_block_valid = 0;
@@ -58,6 +61,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
VbError_t retval = VBERROR_UNKNOWN;
int recovery = VBNV_RECOVERY_LK_UNSPECIFIED;
+ uint8_t *workbuf = NULL;
+ struct vb2_workbuf wb;
+
/* Sanity Checks */
if (!params->bytes_per_lba ||
!params->streaming_lba_count) {
@@ -141,17 +147,34 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
}
/* Allocate kernel header buffers */
- kbuf = (uint8_t*)VbExMalloc(KBUF_SIZE);
+ kbuf = (uint8_t *)VbExMalloc(KBUF_SIZE);
if (!kbuf)
goto bad_gpt;
+ /* Allocate work buffer */
+ workbuf = (uint8_t *)
+ VbExMalloc(VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+ if (!workbuf)
+ goto bad_gpt;
+ vb2_workbuf_init(&wb, workbuf,
+ VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES);
+
+ /* Unpack kernel subkey */
+ struct vb2_public_key kernel_subkey2;
+ if (VB2_SUCCESS != vb2_unpack_key(&kernel_subkey2,
+ (const uint8_t *)kernel_subkey,
+ kernel_subkey->key_offset +
+ kernel_subkey->key_size)) {
+ VBDEBUG(("Unable to unpack kernel subkey\n"));
+ goto bad_gpt;
+ }
+
/* Loop over candidate kernel partitions */
while (GPT_SUCCESS ==
GptNextKernelEntry(&gpt, &part_start, &part_size)) {
VbSharedDataKernelPart *shpart = NULL;
VbKeyBlockHeader *key_block;
VbKernelPreambleHeader *preamble;
- RSAPublicKey *data_key = NULL;
VbExStream_t stream = NULL;
uint64_t key_version;
uint32_t combined_version;
@@ -197,8 +220,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
/* Verify the key block. */
key_block = (VbKeyBlockHeader*)kbuf;
- if (0 != KeyBlockVerify(key_block, KBUF_SIZE,
- kernel_subkey, 0)) {
+ struct vb2_keyblock *keyblock2 = (struct vb2_keyblock *)kbuf;
+ if (VB2_SUCCESS != vb2_verify_keyblock(keyblock2, KBUF_SIZE,
+ &kernel_subkey2, &wb)) {
VBDEBUG(("Verifying key block signature failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;
key_block_valid = 0;
@@ -222,8 +246,9 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
* Allow the kernel if the SHA-512 hash of the key
* block is valid.
*/
- if (0 != KeyBlockVerify(key_block, KBUF_SIZE,
- kernel_subkey, 1)) {
+ if (VB2_SUCCESS !=
+ vb2_verify_keyblock_hash(keyblock2, KBUF_SIZE,
+ &wb)) {
VBDEBUG(("Verifying key block hash failed.\n"));
shpart->check_result =
VBSD_LKP_CHECK_KEY_BLOCK_HASH;
@@ -309,20 +334,29 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
}
/* Get key for preamble/data verification from the key block. */
- data_key = PublicKeyToRSA(&key_block->data_key);
- if (!data_key) {
- VBDEBUG(("Data key bad.\n"));
+ struct vb2_public_key data_key2;
+ if (VB2_SUCCESS !=
+ vb2_unpack_key(&data_key2,
+ (const uint8_t *)&keyblock2->data_key,
+ keyblock2->data_key.key_offset +
+ keyblock2->data_key.key_size)) {
+ VBDEBUG(("Unable to unpack kernel data key\n"));
shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
goto bad_kernel;
}
/* Verify the preamble, which follows the key block */
preamble = (VbKernelPreambleHeader *)
- (kbuf + key_block->key_block_size);
- if ((0 != VerifyKernelPreamble(
- preamble,
- KBUF_SIZE - key_block->key_block_size,
- data_key))) {
+ (kbuf + key_block->key_block_size);
+ struct vb2_kernel_preamble *preamble2 =
+ (struct vb2_kernel_preamble *)
+ (kbuf + key_block->key_block_size);
+
+ if (VB2_SUCCESS != vb2_verify_kernel_preamble(
+ preamble2,
+ KBUF_SIZE - key_block->key_block_size,
+ &data_key2,
+ &wb)) {
VBDEBUG(("Preamble verification failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
goto bad_kernel;
@@ -442,18 +476,17 @@ VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
stream = NULL;
/* Verify kernel data */
- if (0 != VerifyData((const uint8_t *)params->kernel_buffer,
- params->kernel_buffer_size,
- &preamble->body_signature, data_key)) {
+ struct vb2_signature *body_sig = (struct vb2_signature *)
+ &preamble->body_signature;
+ if (VB2_SUCCESS != vb2_verify_data(
+ (const uint8_t *)params->kernel_buffer,
+ params->kernel_buffer_size,
+ body_sig, &data_key2, &wb)) {
VBDEBUG(("Kernel data verification failed.\n"));
shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA;
goto bad_kernel;
}
- /* Done with the kernel signing key, so can free it now */
- RSAPublicKeyFree(data_key);
- data_key = NULL;
-
/*
* If we're still here, the kernel is valid. Save the first
* good partition we find; that's the one we'll boot.
@@ -517,8 +550,6 @@ bad_kernel:
/* Handle errors parsing this kernel */
if (NULL != stream)
VbExStreamClose(stream);
- if (NULL != data_key)
- RSAPublicKeyFree(data_key);
VBDEBUG(("Marking kernel as invalid.\n"));
GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
@@ -527,8 +558,9 @@ bad_kernel:
} /* while(GptNextKernelEntry) */
bad_gpt:
-
- /* Free kernel buffer */
+ /* Free buffers */
+ if (workbuf)
+ VbExFree(workbuf);
if (kbuf)
VbExFree(kbuf);
diff --git a/firmware/lib20/kernel.c b/firmware/lib20/kernel.c
index c50614df..809e1b66 100644
--- a/firmware/lib20/kernel.c
+++ b/firmware/lib20/kernel.c
@@ -462,7 +462,7 @@ void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble,
* Set header and size only if the preamble header version is >
* 2.1 as they don't exist in version 2.0 (Note that we don't
* need to check header_version_major; if that's not 2 then
- * VerifyKernelPreamble() would have already failed.
+ * vb2_verify_kernel_preamble() would have already failed.
*/
*vmlinuz_header_address = preamble->vmlinuz_header_address;
*vmlinuz_header_size = preamble->vmlinuz_header_size;
diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c
index 9dca9571..6629cc5c 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -67,11 +67,6 @@ int main(void)
VerifySignatureInside(0, 0, 0);
PublicKeyInit(0, 0, 0);
PublicKeyCopy(0, 0);
- PublicKeyToRSA(0);
- VerifyData(0, 0, 0, 0);
- VerifyDigest(0, 0, 0);
- KeyBlockVerify(0, 0, 0, 0);
- VerifyKernelPreamble(0, 0, 0);
VbSharedDataInit(0, 0);
VbSharedDataReserve(0, 0);
VbSharedDataSetKernelKey(0, 0);
diff --git a/tests/vboot_api_kernel5_tests.c b/tests/vboot_api_kernel5_tests.c
index 04ee7669..d752f6b7 100644
--- a/tests/vboot_api_kernel5_tests.c
+++ b/tests/vboot_api_kernel5_tests.c
@@ -10,10 +10,14 @@
#include <stdlib.h>
#include <string.h>
+#include "2sysincludes.h"
+#include "2common.h"
+#include "2rsa.h"
#include "gbb_header.h"
#include "host_common.h"
#include "load_kernel_fw.h"
#include "test_common.h"
+#include "vb2_common.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"
@@ -31,8 +35,7 @@ static uint8_t kernel_buffer[80000];
static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
static int preamble_verify_fail;
static int verify_data_fail;
-static RSAPublicKey *mock_data_key;
-static int mock_data_key_allocated;
+static int unpack_key_fail;
static VbNvContext vnc;
static VbKeyBlockHeader kbh;
@@ -69,9 +72,6 @@ static void ResetMocks(void)
preamble_verify_fail = 0;
verify_data_fail = 0;
- mock_data_key = (RSAPublicKey *)"TestDataKey";
- mock_data_key_allocated = 0;
-
memset(&kbh, 0, sizeof(kbh));
kbh.data_key.key_version = 2;
kbh.key_block_flags = -1;
@@ -96,53 +96,68 @@ static void copy_kbh(void)
}
/* Mocks */
-int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
- const VbPublicKey *key, int hash_only) {
- hash_only_check = hash_only;
+int vb2_unpack_key(struct vb2_public_key *key,
+ const uint8_t *buf,
+ uint32_t size)
+{
+ if (--unpack_key_fail == 0)
+ return VB2_ERROR_MOCK;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_verify_keyblock(struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
+{
+ hash_only_check = 0;
if (key_block_verify_fail)
- return VBERROR_SIMULATED;
+ return VB2_ERROR_MOCK;
/* Use this as an opportunity to override the key block */
memcpy((void *)block, &kbh, sizeof(kbh));
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
-RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
+int vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_workbuf *wb)
{
- TEST_EQ(mock_data_key_allocated, 0, " mock data key not allocated");
-
- if (mock_data_key)
- mock_data_key_allocated++;
+ hash_only_check = 1;
- return mock_data_key;
-}
+ if (key_block_verify_fail)
+ return VB2_ERROR_MOCK;
-void RSAPublicKeyFree(RSAPublicKey* key)
-{
- TEST_EQ(mock_data_key_allocated, 1, " mock data key allocated");
- TEST_PTR_EQ(key, mock_data_key, " data key ptr");
- mock_data_key_allocated--;
+ /* Use this as an opportunity to override the key block */
+ memcpy((void *)block, &kbh, sizeof(kbh));
+ return VB2_SUCCESS;
}
-int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
- uint64_t size, const RSAPublicKey *key)
+int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
{
if (preamble_verify_fail)
- return VBERROR_SIMULATED;
+ return VB2_ERROR_MOCK;
/* Use this as an opportunity to override the preamble */
memcpy((void *)preamble, &kph, sizeof(kph));
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
-int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
- const RSAPublicKey *key)
+int vb2_verify_data(const uint8_t *data,
+ uint32_t size,
+ struct vb2_signature *sig,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
{
if (verify_data_fail)
- return VBERROR_SIMULATED;
+ return VB2_ERROR_MOCK;
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
VbError_t VbExNvStorageRead(uint8_t *buf)
diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c
deleted file mode 100644
index 386f487f..00000000
--- a/tests/vboot_common2_tests.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Tests for firmware image library.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "2sysincludes.h"
-#include "2common.h"
-#include "2sha.h"
-#include "cryptolib.h"
-#include "file_keys.h"
-#include "host_common.h"
-#include "test_common.h"
-#include "vboot_common.h"
-
-static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key)
-{
- RSAPublicKey *rsa;
- VbPublicKey *key =
- (VbPublicKey *)vb2_alloc_packed_key(orig_key->key_size, 0, 0);
-
- PublicKeyCopy(key, orig_key);
- key->algorithm = kNumAlgorithms;
- TEST_EQ((size_t)PublicKeyToRSA(key), 0,
- "PublicKeyToRSA() invalid algorithm");
-
- PublicKeyCopy(key, orig_key);
- key->key_size -= 1;
- TEST_EQ((size_t)PublicKeyToRSA(key), 0,
- "PublicKeyToRSA() invalid size");
-
- rsa = PublicKeyToRSA(orig_key);
- TEST_NEQ((size_t)rsa, 0, "PublicKeyToRSA() ok");
- if (rsa) {
- TEST_EQ((int)rsa->algorithm, (int)key->algorithm,
- "PublicKeyToRSA() algorithm");
- RSAPublicKeyFree(rsa);
- }
-
- free(key);
-}
-
-static void VerifyDataTest(const VbPublicKey *public_key,
- const struct vb2_private_key *private_key)
-{
- const uint8_t test_data[] = "This is some test data to sign.";
- const uint64_t test_size = sizeof(test_data);
- VbSignature *sig;
- RSAPublicKey *rsa;
-
- sig = (VbSignature *)vb2_calculate_signature(test_data, test_size,
- private_key);
- TEST_PTR_NEQ(sig, 0, "VerifyData() calculate signature");
-
- rsa = PublicKeyToRSA(public_key);
- TEST_PTR_NEQ(rsa, 0, "VerifyData() calculate rsa");
-
- if (!sig || !rsa)
- return;
-
- TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 0,
- "VerifyData() ok");
-
- sig->sig_size -= 16;
- TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 1,
- "VerifyData() wrong sig size");
- sig->sig_size += 16;
-
- TEST_EQ(VerifyData(test_data, test_size - 1, sig, rsa), 1,
- "VerifyData() input buffer too small");
-
- GetSignatureData(sig)[0] ^= 0x5A;
- TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 1,
- "VerifyData() wrong sig");
-
- RSAPublicKeyFree(rsa);
- free(sig);
-}
-
-static void VerifyDigestTest(const VbPublicKey *public_key,
- const struct vb2_private_key *private_key)
-{
- const uint8_t test_data[] = "This is some other test data to sign.";
- VbSignature *sig;
- RSAPublicKey *rsa;
- uint8_t digest[VB2_MAX_DIGEST_SIZE];
-
- sig = (VbSignature *)vb2_calculate_signature(test_data,
- sizeof(test_data),
- private_key);
- rsa = PublicKeyToRSA(public_key);
- TEST_SUCC(vb2_digest_buffer(test_data, sizeof(test_data),
- vb2_crypto_to_hash(public_key->algorithm),
- digest, sizeof(digest)),
- "VerifyData() digest");
-
- TEST_NEQ(sig && rsa, 0, "VerifyData() prerequisites");
- if (!sig || !rsa)
- return;
-
- TEST_EQ(VerifyDigest(digest, sig, rsa), 0, "VerifyDigest() ok");
-
- GetSignatureData(sig)[0] ^= 0x5A;
- TEST_EQ(VerifyDigest(digest, sig, rsa), 1, "VerifyDigest() wrong sig");
-
- sig->sig_size = 1;
- TEST_EQ(VerifyDigest(digest, sig, rsa), 1, "VerifyDigest() sig size");
-
- RSAPublicKeyFree(rsa);
- free(sig);
-}
-
-static void ReSignKernelPreamble(VbKernelPreambleHeader *h,
- const struct vb2_private_key *key)
-{
- struct vb2_signature *sig = vb2_calculate_signature(
- (const uint8_t *)h, h->preamble_signature.data_size, key);
-
- vb2_copy_signature((struct vb2_signature *)&h->preamble_signature, sig);
- free(sig);
-}
-
-static void VerifyKernelPreambleTest(const VbPublicKey *public_key,
- const struct vb2_private_key *private_key)
-{
- VbKernelPreambleHeader *hdr;
- VbKernelPreambleHeader *h;
- RSAPublicKey *rsa;
- unsigned hsize;
-
- /* Create a dummy signature */
- struct vb2_signature *body_sig = vb2_alloc_signature(56, 78);
-
- rsa = PublicKeyToRSA(public_key);
- hdr = (VbKernelPreambleHeader *)
- vb2_create_kernel_preamble(0x1234, 0x100000, 0x300000, 0x4000,
- body_sig, 0, 0, 0, 0, private_key);
- TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble() prerequisites");
- if (!hdr) {
- free(body_sig);
- RSAPublicKeyFree(rsa);
- return;
- }
-
- hsize = (unsigned) hdr->preamble_size;
- h = (VbKernelPreambleHeader *)malloc(hsize + 16384);
-
- TEST_EQ(VerifyKernelPreamble(hdr, hsize, rsa), 0,
- "VerifyKernelPreamble() ok using key");
- TEST_NEQ(VerifyKernelPreamble(hdr, hsize - 1, rsa), 0,
- "VerifyKernelPreamble() size--");
- TEST_NEQ(VerifyKernelPreamble(hdr, 4, rsa), 0,
- "VerifyKernelPreamble() size tiny");
- TEST_EQ(VerifyKernelPreamble(hdr, hsize + 1, rsa), 0,
- "VerifyKernelPreamble() size++");
-
- /* Care about major version but not minor */
- memcpy(h, hdr, hsize);
- h->header_version_major++;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() major++");
-
- memcpy(h, hdr, hsize);
- h->header_version_major--;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() major--");
-
- memcpy(h, hdr, hsize);
- h->header_version_minor++;
- ReSignKernelPreamble(h, private_key);
- TEST_EQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() minor++");
-
- memcpy(h, hdr, hsize);
- h->header_version_minor--;
- ReSignKernelPreamble(h, private_key);
- TEST_EQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() minor--");
-
- /* Check signature */
- memcpy(h, hdr, hsize);
- h->preamble_signature.sig_offset = hsize;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() sig off end");
-
- memcpy(h, hdr, hsize);
- h->preamble_signature.sig_size--;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() sig too small");
-
- memcpy(h, hdr, hsize);
- GetSignatureData(&h->body_signature)[0] ^= 0x34;
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() sig mismatch");
-
- /* Check that we signed header and body sig */
- memcpy(h, hdr, hsize);
- h->preamble_signature.data_size = 4;
- h->body_signature.sig_offset = 0;
- h->body_signature.sig_size = 0;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() didn't sign header");
-
- memcpy(h, hdr, hsize);
- h->body_signature.sig_offset = hsize;
- ReSignKernelPreamble(h, private_key);
- TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
- "VerifyKernelPreamble() body sig off end");
-
- /* TODO: verify parser can support a bigger header. */
-
- free(h);
- RSAPublicKeyFree(rsa);
- free(hdr);
- free(body_sig);
-}
-
-int test_algorithm(int key_algorithm, const char *keys_dir)
-{
- char filename[1024];
- int rsa_len = siglen_map[key_algorithm] * 8;
-
- VbPublicKey *public_key = NULL;
-
- printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]);
-
- snprintf(filename, sizeof(filename),
- "%s/key_rsa%d.pem", keys_dir, rsa_len);
- struct vb2_private_key *private_key =
- vb2_read_private_key_pem(filename, key_algorithm);
- if (!private_key) {
- fprintf(stderr, "Error reading private_key: %s\n", filename);
- return 1;
- }
-
- snprintf(filename, sizeof(filename),
- "%s/key_rsa%d.keyb", keys_dir, rsa_len);
- public_key = (VbPublicKey *)vb2_read_packed_keyb(filename,
- key_algorithm, 1);
- if (!public_key) {
- fprintf(stderr, "Error reading public_key: %s\n", filename);
- free(private_key);
- return 1;
- }
-
- VerifyPublicKeyToRSA(public_key);
- VerifyDataTest(public_key, private_key);
- VerifyDigestTest(public_key, private_key);
- VerifyKernelPreambleTest(public_key, private_key);
-
- free(public_key);
- free(private_key);
-
- return 0;
-}
-
-/*
- * Test only the algorithms we use:
- * 4 (rsa2048 sha256)
- * 7 (rsa4096 sha256)
- * 11 (rsa8192 sha512)
- */
-const int key_algs[] = {4, 7, 11};
-
-int main(int argc, char *argv[]) {
- if (argc == 2) {
- int i;
-
- for (i = 0; i < ARRAY_SIZE(key_algs); i++) {
- if (test_algorithm(key_algs[i], argv[1]))
- return 1;
- }
-
- } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
- /* Test all the algorithms */
- int alg;
-
- for (alg = 0; alg < kNumAlgorithms; alg++) {
- if (test_algorithm(alg, argv[1]))
- return 1;
- }
-
- } else {
- fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
- return -1;
- }
-
- if (vboot_api_stub_check_memory())
- return 255;
-
- return gTestSuccess ? 0 : 255;
-}
diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c
deleted file mode 100644
index 390b7f30..00000000
--- a/tests/vboot_common3_tests.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Tests for firmware image library.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "2sysincludes.h"
-#include "2common.h"
-#include "2sha.h"
-#include "cryptolib.h"
-#include "file_keys.h"
-#include "host_common.h"
-#include "test_common.h"
-#include "vboot_common.h"
-
-
-static void ReChecksumKeyBlock(VbKeyBlockHeader *h)
-{
- vb2_digest_buffer((const uint8_t *)h,
- h->key_block_checksum.data_size,
- VB2_HASH_SHA512,
- GetSignatureData(&h->key_block_checksum),
- VB2_SHA512_DIGEST_SIZE);
-}
-
-static void KeyBlockVerifyTest(const VbPublicKey *public_key,
- const struct vb2_private_key *private_key,
- const struct vb2_packed_key *data_key)
-{
- VbKeyBlockHeader *hdr;
- VbKeyBlockHeader *h;
- unsigned hsize;
-
- hdr = (VbKeyBlockHeader *)
- vb2_create_keyblock((struct vb2_packed_key *)data_key,
- private_key,
- 0x1234);
- TEST_NEQ((size_t)hdr, 0, "KeyBlockVerify() prerequisites");
- if (!hdr)
- return;
- hsize = (unsigned) hdr->key_block_size;
- h = (VbKeyBlockHeader *)malloc(hsize + 1024);
-
- TEST_EQ(KeyBlockVerify(hdr, hsize, NULL, 1), 0,
- "KeyBlockVerify() ok using checksum");
- TEST_EQ(KeyBlockVerify(hdr, hsize, public_key, 0), 0,
- "KeyBlockVerify() ok using key");
- TEST_NEQ(KeyBlockVerify(hdr, hsize, NULL, 0), 0,
- "KeyBlockVerify() missing key");
-
- TEST_NEQ(KeyBlockVerify(hdr, hsize - 1, NULL, 1), 0,
- "KeyBlockVerify() size--");
- TEST_EQ(KeyBlockVerify(hdr, hsize + 1, NULL, 1), 0,
- "KeyBlockVerify() size++");
-
- memcpy(h, hdr, hsize);
- h->magic[0] &= 0x12;
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() magic");
-
- /* Care about major version but not minor */
- memcpy(h, hdr, hsize);
- h->header_version_major++;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() major++");
-
- memcpy(h, hdr, hsize);
- h->header_version_major--;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() major--");
-
- memcpy(h, hdr, hsize);
- h->header_version_minor++;
- ReChecksumKeyBlock(h);
- TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() minor++");
-
- memcpy(h, hdr, hsize);
- h->header_version_minor--;
- ReChecksumKeyBlock(h);
- TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() minor--");
-
- /* Check hash */
- memcpy(h, hdr, hsize);
- h->key_block_checksum.sig_offset = hsize;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() checksum off end");
-
- memcpy(h, hdr, hsize);
- h->key_block_checksum.sig_size /= 2;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() checksum too small");
-
- memcpy(h, hdr, hsize);
- GetPublicKeyData(&h->data_key)[0] ^= 0x34;
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() checksum mismatch");
-
- /* Check signature */
- memcpy(h, hdr, hsize);
- h->key_block_signature.sig_offset = hsize;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
- "KeyBlockVerify() sig off end");
-
- memcpy(h, hdr, hsize);
- h->key_block_signature.sig_size--;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
- "KeyBlockVerify() sig too small");
-
- memcpy(h, hdr, hsize);
- GetPublicKeyData(&h->data_key)[0] ^= 0x34;
- TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
- "KeyBlockVerify() sig mismatch");
-
- memcpy(h, hdr, hsize);
- h->key_block_checksum.data_size = h->key_block_size + 1;
- TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 1), 0,
- "KeyBlockVerify() checksum data past end of block");
-
- /* Check that we signed header and data key */
- memcpy(h, hdr, hsize);
- h->key_block_checksum.data_size = 4;
- h->data_key.key_offset = 0;
- h->data_key.key_size = 0;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() didn't sign header");
-
- memcpy(h, hdr, hsize);
- h->data_key.key_offset = hsize;
- ReChecksumKeyBlock(h);
- TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
- "KeyBlockVerify() data key off end");
-
- /* Corner cases for error checking */
- TEST_NEQ(KeyBlockVerify(NULL, 4, NULL, 1), 0,
- "KeyBlockVerify size too small");
-
- /*
- * TODO: verify parser can support a bigger header (i.e., one where
- * data_key.key_offset is bigger than expected).
- */
-
- free(h);
- free(hdr);
-}
-
-int test_permutation(int signing_key_algorithm, int data_key_algorithm,
- const char *keys_dir)
-{
- char filename[1024];
- int signing_rsa_len = siglen_map[signing_key_algorithm] * 8;
- int data_rsa_len = siglen_map[data_key_algorithm] * 8;
-
- struct vb2_private_key *signing_private_key = NULL;
- struct vb2_packed_key *data_public_key = NULL;
- VbPublicKey *signing_public_key = NULL;
- int retval = 1;
-
- printf("***Testing signing algorithm: %s\n",
- algo_strings[signing_key_algorithm]);
- printf("***With data key algorithm: %s\n",
- algo_strings[data_key_algorithm]);
-
- snprintf(filename, sizeof(filename),
- "%s/key_rsa%d.pem", keys_dir, signing_rsa_len);
- signing_private_key =
- vb2_read_private_key_pem(filename, signing_key_algorithm);
- if (!signing_private_key) {
- fprintf(stderr, "Error reading signing_private_key: %s\n",
- filename);
- goto cleanup;
- }
-
- snprintf(filename, sizeof(filename),
- "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
- signing_public_key = (VbPublicKey *)
- vb2_read_packed_keyb(filename, signing_key_algorithm, 1);
- if (!signing_public_key) {
- fprintf(stderr, "Error reading signing_public_key: %s\n",
- filename);
- goto cleanup;
- }
-
- snprintf(filename, sizeof(filename),
- "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
- data_public_key = vb2_read_packed_keyb(filename, data_key_algorithm, 1);
- if (!data_public_key) {
- fprintf(stderr, "Error reading data_public_key: %s\n",
- filename);
- goto cleanup;
- }
-
- KeyBlockVerifyTest(signing_public_key, signing_private_key,
- data_public_key);
- retval = 0;
-
-cleanup:
- if (signing_public_key)
- free(signing_public_key);
- if (signing_private_key)
- free(signing_private_key);
- if (data_public_key)
- free(data_public_key);
-
- return retval;
-}
-
-struct test_perm
-{
- int signing_algorithm;
- int data_key_algorithm;
-};
-
-/*
- * Permutations of signing and data key algorithms in active use:
- * 7 (rsa4096 sha256) - 4 (rsa2048 sha256)
- * 11 (rsa8192 sha512) - 4 (rsa2048 sha256)
- * 11 (rsa8192 sha512) - 7 (rsa4096 sha256)
- */
-const struct test_perm test_perms[] = {{7, 4}, {11, 4}, {11, 7}};
-
-int main(int argc, char *argv[])
-{
- if (argc == 2) {
- /* Test only the algorithms we use */
- int i;
-
- for (i = 0; i < ARRAY_SIZE(test_perms); i++) {
- if (test_permutation(test_perms[i].signing_algorithm,
- test_perms[i].data_key_algorithm,
- argv[1]))
- return 1;
- }
-
- } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
- /* Test all the algorithms */
- int sign_alg, data_alg;
-
- for (sign_alg = 0; sign_alg < kNumAlgorithms; sign_alg++) {
- for (data_alg = 0; data_alg < kNumAlgorithms;
- data_alg++) {
- if (test_permutation(sign_alg, data_alg,
- argv[1]))
- return 1;
- }
- }
- } else {
- fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
- return -1;
- }
-
- if (vboot_api_stub_check_memory())
- return 255;
-
- return gTestSuccess ? 0 : 255;
-}
diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c
index e3695ab1..994b792c 100644
--- a/tests/vboot_kernel_tests.c
+++ b/tests/vboot_kernel_tests.c
@@ -23,6 +23,7 @@
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "test_common.h"
+#include "vb2_struct.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"
@@ -54,8 +55,7 @@ static int gpt_init_fail;
static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
static int preamble_verify_fail;
static int verify_data_fail;
-static RSAPublicKey *mock_data_key;
-static int mock_data_key_allocated;
+static int unpack_key_fail;
static int gpt_flag_external;
static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
@@ -130,9 +130,7 @@ static void ResetMocks(void)
key_block_verify_fail = 0;
preamble_verify_fail = 0;
verify_data_fail = 0;
-
- mock_data_key = (RSAPublicKey *)"TestDataKey";
- mock_data_key_allocated = 0;
+ unpack_key_fail = 0;
gpt_flag_external = 0;
@@ -246,54 +244,64 @@ void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
memcpy(dest, fake_guid, sizeof(fake_guid));
}
-int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
- const VbPublicKey *key, int hash_only) {
-
- if (hash_only && key_block_verify_fail >= 2)
- return VBERROR_SIMULATED;
- else if (!hash_only && key_block_verify_fail >= 1)
- return VBERROR_SIMULATED;
+int vb2_unpack_key(struct vb2_public_key *key,
+ const uint8_t *buf,
+ uint32_t size)
+{
+ if (--unpack_key_fail == 0)
+ return VB2_ERROR_MOCK;
- /* Use this as an opportunity to override the key block */
- memcpy((void *)block, &kbh, sizeof(kbh));
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
-RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
+int vb2_verify_keyblock(struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
{
- TEST_EQ(mock_data_key_allocated, 0, " mock data key not allocated");
+ if (key_block_verify_fail >= 1)
+ return VB2_ERROR_MOCK;
- if (mock_data_key)
- mock_data_key_allocated++;
-
- return mock_data_key;
+ /* Use this as an opportunity to override the key block */
+ memcpy((void *)block, &kbh, sizeof(kbh));
+ return VB2_SUCCESS;
}
-void RSAPublicKeyFree(RSAPublicKey* key)
+int vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_workbuf *wb)
{
- TEST_EQ(mock_data_key_allocated, 1, " mock data key allocated");
- TEST_PTR_EQ(key, mock_data_key, " data key ptr");
- mock_data_key_allocated--;
+ if (key_block_verify_fail >= 2)
+ return VB2_ERROR_MOCK;
+
+ /* Use this as an opportunity to override the key block */
+ memcpy((void *)block, &kbh, sizeof(kbh));
+ return VB2_SUCCESS;
}
-int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
- uint64_t size, const RSAPublicKey *key)
+int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
{
if (preamble_verify_fail)
- return VBERROR_SIMULATED;
+ return VB2_ERROR_MOCK;
/* Use this as an opportunity to override the preamble */
memcpy((void *)preamble, &kph, sizeof(kph));
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
-int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
- const RSAPublicKey *key)
+int vb2_verify_data(const uint8_t *data,
+ uint32_t size,
+ struct vb2_signature *sig,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
{
if (verify_data_fail)
- return VBERROR_SIMULATED;
+ return VB2_ERROR_MOCK;
- return VBERROR_SUCCESS;
+ return VB2_SUCCESS;
}
int vb2_digest_buffer(const uint8_t *buf,
@@ -727,7 +735,7 @@ static void LoadKernelTest(void)
TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
ResetMocks();
- mock_data_key = NULL;
+ unpack_key_fail = 2;
TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
"Bad data key");