mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 00:51:29 +00:00
vboot2: Use more specific error codes, part 3
Error codes reported by 2common.c are now very specific, and tests verify the proper errors are reported. BUG=chromium:370082 BRANCH=none TEST=make clean && VBOOT2=1 COV=1 make Change-Id: I9480bd22b60ae339196c92918a8a984a9f05ac1a Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/202938 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
2145721c3c
commit
224f5ac761
@@ -175,25 +175,25 @@ int vb2_unpack_key(struct vb2_public_key *key,
|
||||
|
||||
if (packed_key->algorithm >= VB2_ALG_COUNT) {
|
||||
VB2_DEBUG("Invalid algorithm.\n");
|
||||
return VB2_ERROR_BAD_ALGORITHM;
|
||||
return VB2_ERROR_UNPACK_KEY_ALGORITHM;
|
||||
}
|
||||
|
||||
expected_key_size = vb2_packed_key_size(packed_key->algorithm);
|
||||
if (!expected_key_size || expected_key_size != packed_key->key_size) {
|
||||
VB2_DEBUG("Wrong key size for algorithm\n");
|
||||
return VB2_ERROR_BAD_KEY;
|
||||
return VB2_ERROR_UNPACK_KEY_SIZE;
|
||||
}
|
||||
|
||||
/* Make sure source buffer is 32-bit aligned */
|
||||
buf32 = (const uint32_t *)vb2_packed_key_data(packed_key);
|
||||
if (!vb_aligned(buf32, sizeof(uint32_t)))
|
||||
return VB2_ERROR_BUFFER_UNALIGNED;
|
||||
return VB2_ERROR_UNPACK_KEY_ALIGN;
|
||||
|
||||
/* Sanity check key array size */
|
||||
key->arrsize = buf32[0];
|
||||
if (key->arrsize * sizeof(uint32_t) !=
|
||||
vb2_rsa_sig_size(packed_key->algorithm))
|
||||
return VB2_ERROR_BAD_KEY;
|
||||
return VB2_ERROR_UNPACK_KEY_ARRAY_SIZE;
|
||||
|
||||
key->n0inv = buf32[1];
|
||||
|
||||
@@ -219,31 +219,31 @@ int vb2_verify_data(const uint8_t *data,
|
||||
int rv;
|
||||
|
||||
if (key->algorithm >= VB2_ALG_COUNT)
|
||||
return VB2_ERROR_BAD_ALGORITHM;
|
||||
return VB2_ERROR_VDATA_ALGORITHM;
|
||||
|
||||
if (sig->sig_size != vb2_rsa_sig_size(key->algorithm)) {
|
||||
VB2_DEBUG("Wrong data signature size for algorithm, "
|
||||
"sig_size=%d, expected %d for algorithm %d.\n",
|
||||
(int)sig->sig_size, vb2_rsa_sig_size(key->algorithm),
|
||||
key->algorithm);
|
||||
return VB2_ERROR_BAD_SIGNATURE;
|
||||
return VB2_ERROR_VDATA_SIG_SIZE;
|
||||
}
|
||||
|
||||
if (sig->data_size > size) {
|
||||
VB2_DEBUG("Data buffer smaller than length of signed data.\n");
|
||||
return VB2_ERROR_UNKNOWN;
|
||||
return VB2_ERROR_VDATA_NOT_ENOUGH_DATA;
|
||||
}
|
||||
|
||||
/* Digest goes at start of work buffer */
|
||||
digest_size = vb2_digest_size(key->algorithm);
|
||||
digest = vb2_workbuf_alloc(&wblocal, digest_size);
|
||||
if (!digest)
|
||||
return VB2_ERROR_WORKBUF_TOO_SMALL;
|
||||
return VB2_ERROR_VDATA_WORKBUF_DIGEST;
|
||||
|
||||
/* Hashing requires temp space for the context */
|
||||
dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
|
||||
if (!dc)
|
||||
return VB2_ERROR_WORKBUF_TOO_SMALL;
|
||||
return VB2_ERROR_VDATA_WORKBUF_HASHING;
|
||||
|
||||
rv = vb2_digest_init(dc, key->algorithm);
|
||||
if (rv)
|
||||
@@ -274,19 +274,19 @@ int vb2_verify_keyblock(struct vb2_keyblock *block,
|
||||
/* Sanity checks before attempting signature of data */
|
||||
if(size < sizeof(*block)) {
|
||||
VB2_DEBUG("Not enough space for key block header.\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER;
|
||||
}
|
||||
if (memcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
|
||||
VB2_DEBUG("Not a valid verified boot key block.\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_MAGIC;
|
||||
}
|
||||
if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
|
||||
VB2_DEBUG("Incompatible key block header version.\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
|
||||
}
|
||||
if (size < block->keyblock_size) {
|
||||
VB2_DEBUG("Not enough data for key block.\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Check signature */
|
||||
@@ -294,38 +294,38 @@ int vb2_verify_keyblock(struct vb2_keyblock *block,
|
||||
|
||||
if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) {
|
||||
VB2_DEBUG("Key block signature off end of block\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE;
|
||||
}
|
||||
|
||||
/* Make sure advertised signature data sizes are sane. */
|
||||
if (block->keyblock_size < sig->data_size) {
|
||||
VB2_DEBUG("Signature calculated past end of block\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH;
|
||||
}
|
||||
|
||||
VB2_DEBUG("Checking key block signature...\n");
|
||||
rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb);
|
||||
if (rv) {
|
||||
VB2_DEBUG("Invalid key block signature.\n");
|
||||
return VB2_ERROR_BAD_SIGNATURE;
|
||||
return VB2_ERROR_KEYBLOCK_SIG_INVALID;
|
||||
}
|
||||
|
||||
/* Verify we signed enough data */
|
||||
if (sig->data_size < sizeof(struct vb2_keyblock)) {
|
||||
VB2_DEBUG("Didn't sign enough data\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Verify data key is inside the block and inside signed data */
|
||||
if (vb2_verify_packed_key_inside(block, block->keyblock_size,
|
||||
&block->data_key)) {
|
||||
VB2_DEBUG("Data key off end of key block\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE;
|
||||
}
|
||||
if (vb2_verify_packed_key_inside(block, sig->data_size,
|
||||
&block->data_key)) {
|
||||
VB2_DEBUG("Data key off end of signed data\n");
|
||||
return VB2_ERROR_BAD_KEYBLOCK;
|
||||
return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
@@ -344,60 +344,60 @@ int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
|
||||
/* Sanity checks before attempting signature of data */
|
||||
if(size < EXPECTED_VB2FIRMWAREPREAMBLEHEADER2_1_SIZE) {
|
||||
VB2_DEBUG("Not enough data for preamble header 2.1.\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
|
||||
}
|
||||
if (preamble->header_version_major !=
|
||||
FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
|
||||
VB2_DEBUG("Incompatible firmware preamble header version.\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_HEADER_VERSION;
|
||||
}
|
||||
|
||||
if (preamble->header_version_minor < 1) {
|
||||
VB2_DEBUG("Only preamble header 2.1+ supported\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_HEADER_OLD;
|
||||
}
|
||||
|
||||
if (size < preamble->preamble_size) {
|
||||
VB2_DEBUG("Not enough data for preamble.\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_SIZE;
|
||||
}
|
||||
|
||||
/* Check signature */
|
||||
if (vb2_verify_signature_inside(preamble, preamble->preamble_size,
|
||||
sig)) {
|
||||
VB2_DEBUG("Preamble signature off end of preamble\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_SIG_OUTSIDE;
|
||||
}
|
||||
|
||||
/* Make sure advertised signature data sizes are sane. */
|
||||
if (preamble->preamble_size < sig->data_size) {
|
||||
VB2_DEBUG("Signature calculated past end of the block\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH;
|
||||
}
|
||||
|
||||
if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) {
|
||||
VB2_DEBUG("Preamble signature validation failed\n");
|
||||
return VB2_ERROR_BAD_SIGNATURE;
|
||||
return VB2_ERROR_PREAMBLE_SIG_INVALID;
|
||||
}
|
||||
|
||||
/* Verify we signed enough data */
|
||||
if (sig->data_size < sizeof(struct vb2_fw_preamble)) {
|
||||
VB2_DEBUG("Didn't sign enough data\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Verify body signature is inside the signed data */
|
||||
if (vb2_verify_signature_inside(preamble, sig->data_size,
|
||||
&preamble->body_signature)) {
|
||||
VB2_DEBUG("Firmware body signature off end of preamble\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE;
|
||||
}
|
||||
|
||||
/* Verify kernel subkey is inside the signed data */
|
||||
if (vb2_verify_packed_key_inside(preamble, sig->data_size,
|
||||
&preamble->kernel_subkey)) {
|
||||
VB2_DEBUG("Kernel subkey off end of preamble\n");
|
||||
return VB2_ERROR_BAD_PREAMBLE;
|
||||
return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
|
||||
@@ -28,9 +28,9 @@ int vb2_init_context(struct vb2_context *ctx)
|
||||
* store a recovery reason.
|
||||
*/
|
||||
if (ctx->workbuf_size < sizeof(*sd))
|
||||
return VB2_ERROR_WORKBUF_TOO_SMALL;
|
||||
return VB2_ERROR_INITCTX_WORKBUF_SMALL;
|
||||
if (!vb_aligned(ctx->workbuf, sizeof(uint32_t)))
|
||||
return VB2_ERROR_BUFFER_UNALIGNED;
|
||||
return VB2_ERROR_INITCTX_WORKBUF_ALIGN;
|
||||
|
||||
/* Initialize the shared data at the start of the work buffer */
|
||||
memset(sd, 0, sizeof(*sd));
|
||||
|
||||
@@ -125,6 +125,114 @@ enum vb2_return_code {
|
||||
/* Member data outside parent in vb2_verify_member_inside() */
|
||||
VB2_ERROR_INSIDE_DATA_OUTSIDE,
|
||||
|
||||
/* Bad algorithm in vb2_unpack_key() */
|
||||
VB2_ERROR_UNPACK_KEY_ALGORITHM,
|
||||
|
||||
/* Bad key size in vb2_unpack_key() */
|
||||
VB2_ERROR_UNPACK_KEY_SIZE,
|
||||
|
||||
/* Bad key alignment in vb2_unpack_key() */
|
||||
VB2_ERROR_UNPACK_KEY_ALIGN,
|
||||
|
||||
/* Bad key array size in vb2_unpack_key() */
|
||||
VB2_ERROR_UNPACK_KEY_ARRAY_SIZE,
|
||||
|
||||
/* Bad algorithm in vb2_verify_data() */
|
||||
VB2_ERROR_VDATA_ALGORITHM,
|
||||
|
||||
/* Incorrect signature size for algorithm in vb2_verify_data() */
|
||||
VB2_ERROR_VDATA_SIG_SIZE,
|
||||
|
||||
/* Data smaller than length of signed data in vb2_verify_data() */
|
||||
VB2_ERROR_VDATA_NOT_ENOUGH_DATA,
|
||||
|
||||
/* Not enough work buffer for digest in vb2_verify_data() */
|
||||
VB2_ERROR_VDATA_WORKBUF_DIGEST,
|
||||
|
||||
/* Not enough work buffer for hash temp data in vb2_verify_data() */
|
||||
VB2_ERROR_VDATA_WORKBUF_HASHING,
|
||||
|
||||
/**********************************************************************
|
||||
* Keyblock verification errors (all in vb2_verify_keyblock())
|
||||
*/
|
||||
VB2_ERROR_KEYBLOCK = VB2_ERROR_BASE + 0x060000,
|
||||
|
||||
/* Data buffer too small for header */
|
||||
VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER,
|
||||
|
||||
/* Magic number not present */
|
||||
VB2_ERROR_KEYBLOCK_MAGIC,
|
||||
|
||||
/* Header version incompatible */
|
||||
VB2_ERROR_KEYBLOCK_HEADER_VERSION,
|
||||
|
||||
/* Data buffer too small for keyblock */
|
||||
VB2_ERROR_KEYBLOCK_SIZE,
|
||||
|
||||
/* Signature data offset outside keyblock */
|
||||
VB2_ERROR_KEYBLOCK_SIG_OUTSIDE,
|
||||
|
||||
/* Signature signed more data than size of keyblock */
|
||||
VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH,
|
||||
|
||||
/* Signature signed less data than size of keyblock header */
|
||||
VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE,
|
||||
|
||||
/* Signature invalid */
|
||||
VB2_ERROR_KEYBLOCK_SIG_INVALID,
|
||||
|
||||
/* Data key outside keyblock */
|
||||
VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE,
|
||||
|
||||
/* Data key outside signed part of keyblock */
|
||||
VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED,
|
||||
|
||||
/**********************************************************************
|
||||
* Preamble verification errors (all in vb2_verify_preamble())
|
||||
*/
|
||||
VB2_ERROR_PREAMBLE = VB2_ERROR_BASE + 0x070000,
|
||||
|
||||
/* Preamble data too small to contain header */
|
||||
VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
|
||||
|
||||
/* Header version incompatible */
|
||||
VB2_ERROR_PREAMBLE_HEADER_VERSION,
|
||||
|
||||
/* Header version too old */
|
||||
VB2_ERROR_PREAMBLE_HEADER_OLD,
|
||||
|
||||
/* Data buffer too small for preamble */
|
||||
VB2_ERROR_PREAMBLE_SIZE,
|
||||
|
||||
/* Signature data offset outside preamble */
|
||||
VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
|
||||
|
||||
/* Signature signed more data than size of preamble */
|
||||
VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH,
|
||||
|
||||
/* Signature signed less data than size of preamble header */
|
||||
VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
|
||||
|
||||
/* Signature invalid */
|
||||
VB2_ERROR_PREAMBLE_SIG_INVALID,
|
||||
|
||||
/* Body signature outside preamble */
|
||||
VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
|
||||
|
||||
/* Kernel subkey outside preamble */
|
||||
VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE,
|
||||
|
||||
/**********************************************************************
|
||||
* Misc higher-level code errors
|
||||
*/
|
||||
VB2_ERROR_MISC = VB2_ERROR_BASE + 0x080000,
|
||||
|
||||
/* Work buffer too small in vb2_init_context() */
|
||||
VB2_ERROR_INITCTX_WORKBUF_SMALL,
|
||||
|
||||
/* Work buffer unaligned in vb2_init_context() */
|
||||
VB2_ERROR_INITCTX_WORKBUF_ALIGN,
|
||||
|
||||
/**********************************************************************
|
||||
* TODO: errors which must still be made specific
|
||||
*/
|
||||
|
||||
@@ -33,40 +33,40 @@ static void test_unpack_key(const VbPublicKey *orig_key)
|
||||
uint32_t size = key2->key_offset + key2->key_size;
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size),
|
||||
0, "vb2_unpack_key() ok");
|
||||
TEST_SUCC(vb2_unpack_key(&rsa, buf, size), "vb2_unpack_key() ok");
|
||||
|
||||
TEST_EQ(rsa.algorithm, key2->algorithm, "vb2_unpack_key() algorithm");
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
key2->algorithm = VB2_ALG_COUNT;
|
||||
TEST_NEQ(vb2_unpack_key(&rsa, buf, size),
|
||||
0, "vb2_unpack_key() invalid algorithm");
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size),
|
||||
VB2_ERROR_UNPACK_KEY_ALGORITHM,
|
||||
"vb2_unpack_key() invalid algorithm");
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
key2->key_size--;
|
||||
TEST_NEQ(vb2_unpack_key(&rsa, buf, size),
|
||||
0, "vb2_unpack_key() invalid size");
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size),
|
||||
VB2_ERROR_UNPACK_KEY_SIZE,
|
||||
"vb2_unpack_key() invalid size");
|
||||
key2->key_size++;
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
key2->key_offset++;
|
||||
TEST_NEQ(vb2_unpack_key(&rsa, buf, size + 1),
|
||||
0, "vb2_unpack_key() unaligned data");
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size + 1),
|
||||
VB2_ERROR_UNPACK_KEY_ALIGN,
|
||||
"vb2_unpack_key() unaligned data");
|
||||
key2->key_offset--;
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
*(uint32_t *)(buf + key2->key_offset) /= 2;
|
||||
TEST_NEQ(vb2_unpack_key(&rsa, buf, size),
|
||||
0, "vb2_unpack_key() invalid key array size");
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
TEST_NEQ(vb2_unpack_key(&rsa, buf, size - 1),
|
||||
0, "vb2_unpack_key() buffer too small");
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size),
|
||||
0, "vb2_unpack_key() ok2");
|
||||
VB2_ERROR_UNPACK_KEY_ARRAY_SIZE,
|
||||
"vb2_unpack_key() invalid key array size");
|
||||
|
||||
PublicKeyCopy(key, orig_key);
|
||||
TEST_EQ(vb2_unpack_key(&rsa, buf, size - 1),
|
||||
VB2_ERROR_INSIDE_DATA_OUTSIDE,
|
||||
"vb2_unpack_key() buffer too small");
|
||||
|
||||
free(key);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
* Tests for firmware image library.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "2sysincludes.h"
|
||||
#include "2common.h"
|
||||
#include "2rsa.h"
|
||||
|
||||
#include "file_keys.h"
|
||||
#include "host_common.h"
|
||||
@@ -17,9 +19,6 @@
|
||||
#include "vboot_common.h"
|
||||
#include "test_common.h"
|
||||
|
||||
#include "2common.h"
|
||||
#include "2rsa.h"
|
||||
|
||||
static void resign_keyblock(struct vb2_keyblock *h, const VbPrivateKey *key)
|
||||
{
|
||||
VbSignature *sig =
|
||||
@@ -44,9 +43,9 @@ static void test_verify_keyblock(const VbPublicKey *public_key,
|
||||
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
||||
|
||||
/* Unpack public key */
|
||||
TEST_EQ(vb2_unpack_key(&key, (uint8_t *)public_key,
|
||||
public_key->key_offset + public_key->key_size),
|
||||
0, "vb2_verify_keyblock public key");
|
||||
TEST_SUCC(vb2_unpack_key(&key, (uint8_t *)public_key,
|
||||
public_key->key_offset + public_key->key_size),
|
||||
"vb2_verify_keyblock public key");
|
||||
|
||||
hdr = (struct vb2_keyblock *)
|
||||
KeyBlockCreate(data_key, private_key, 0x1234);
|
||||
@@ -57,69 +56,76 @@ static void test_verify_keyblock(const VbPublicKey *public_key,
|
||||
h = (struct vb2_keyblock *)malloc(hsize + 2048);
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() ok using key");
|
||||
TEST_SUCC(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
"vb2_verify_keyblock() ok using key");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize - 1, &key, &wb),
|
||||
0, "vb2_verify_keyblock() size--");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize - 1, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIZE, "vb2_verify_keyblock() size--");
|
||||
|
||||
/* Buffer is allowed to be bigger than keyblock */
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize + 1, &key, &wb),
|
||||
0, "vb2_verify_keyblock() size++");
|
||||
TEST_SUCC(vb2_verify_keyblock(h, hsize + 1, &key, &wb),
|
||||
"vb2_verify_keyblock() size++");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->magic[0] &= 0x12;
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() magic");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_MAGIC, "vb2_verify_keyblock() magic");
|
||||
|
||||
/* Care about major version but not minor */
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_major++;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() major++");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_HEADER_VERSION,
|
||||
"vb2_verify_keyblock() major++");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_major--;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() major--");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_HEADER_VERSION,
|
||||
"vb2_verify_keyblock() major--");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_minor++;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() minor++");
|
||||
TEST_SUCC(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
"vb2_verify_keyblock() minor++");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_minor--;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() minor--");
|
||||
TEST_SUCC(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
"vb2_verify_keyblock() minor--");
|
||||
|
||||
/* Check signature */
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->keyblock_signature.sig_offset = hsize;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() sig off end");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIG_OUTSIDE,
|
||||
"vb2_verify_keyblock() sig off end");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->keyblock_signature.sig_size--;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() sig too small");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIG_INVALID,
|
||||
"vb2_verify_keyblock() sig too small");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
((uint8_t *)vb2_packed_key_data(&h->data_key))[0] ^= 0x34;
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() sig mismatch");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIG_INVALID,
|
||||
"vb2_verify_keyblock() sig mismatch");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->keyblock_signature.data_size = h->keyblock_size + 1;
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() sig data past end of block");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH,
|
||||
"vb2_verify_keyblock() sig data past end of block");
|
||||
|
||||
/* Check that we signed header and data key */
|
||||
Memcpy(h, hdr, hsize);
|
||||
@@ -127,18 +133,21 @@ static void test_verify_keyblock(const VbPublicKey *public_key,
|
||||
h->data_key.key_offset = 0;
|
||||
h->data_key.key_size = 0;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() didn't sign header");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE,
|
||||
"vb2_verify_keyblock() didn't sign header");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->data_key.key_offset = hsize;
|
||||
resign_keyblock(h, private_key);
|
||||
TEST_NEQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
0, "vb2_verify_keyblock() data key off end");
|
||||
TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE,
|
||||
"vb2_verify_keyblock() data key off end");
|
||||
|
||||
/* Corner cases for error checking */
|
||||
TEST_NEQ(vb2_verify_keyblock(NULL, 4, &key, &wb),
|
||||
0, "vb2_verify_keyblock size too small");
|
||||
TEST_EQ(vb2_verify_keyblock(NULL, 4, &key, &wb),
|
||||
VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER,
|
||||
"vb2_verify_keyblock size too small");
|
||||
|
||||
/*
|
||||
* TODO: verify parser can support a bigger header (i.e., one where
|
||||
@@ -175,9 +184,9 @@ static void test_verify_fw_preamble(const VbPublicKey *public_key,
|
||||
/* Create a dummy signature */
|
||||
VbSignature *body_sig = SignatureAlloc(56, 78);
|
||||
|
||||
TEST_EQ(vb2_unpack_key(&rsa, (uint8_t *)public_key,
|
||||
public_key->key_offset + public_key->key_size),
|
||||
0, "vb2_verify_fw_preamble() prereq key");
|
||||
TEST_SUCC(vb2_unpack_key(&rsa, (uint8_t *)public_key,
|
||||
public_key->key_offset + public_key->key_size),
|
||||
"vb2_verify_fw_preamble() prereq key");
|
||||
|
||||
hdr = (struct vb2_fw_preamble *)
|
||||
CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig,
|
||||
@@ -190,63 +199,72 @@ static void test_verify_fw_preamble(const VbPublicKey *public_key,
|
||||
h = (struct vb2_fw_preamble *)malloc(hsize + 16384);
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() ok using key");
|
||||
TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
"vb2_verify_fw_preamble() ok using key");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, 4, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() size tiny");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, 4, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
|
||||
"vb2_verify_fw_preamble() size tiny");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize - 1, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() size--");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize - 1, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_SIZE,
|
||||
"vb2_verify_fw_preamble() size--");
|
||||
|
||||
/* Buffer is allowed to be bigger than preamble */
|
||||
Memcpy(h, hdr, hsize);
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize + 1, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() size++");
|
||||
TEST_SUCC(vb2_verify_fw_preamble(h, hsize + 1, &rsa, &wb),
|
||||
"vb2_verify_fw_preamble() size++");
|
||||
|
||||
/* Care about major version but not minor */
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_major++;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() major++");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_HEADER_VERSION
|
||||
, "vb2_verify_fw_preamble() major++");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_major--;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() major--");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_HEADER_VERSION,
|
||||
"vb2_verify_fw_preamble() major--");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_minor++;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() minor++");
|
||||
TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
"vb2_verify_fw_preamble() minor++");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->header_version_minor--;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() 2.0 not supported");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_HEADER_OLD,
|
||||
"vb2_verify_fw_preamble() 2.0 not supported");
|
||||
|
||||
/* Check signature */
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->preamble_signature.sig_offset = hsize;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() sig off end");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
|
||||
"vb2_verify_fw_preamble() sig off end");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->preamble_signature.sig_size--;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() sig too small");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_SIG_INVALID,
|
||||
"vb2_verify_fw_preamble() sig too small");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
((uint8_t *)vb2_packed_key_data(&h->kernel_subkey))[0] ^= 0x34;
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() sig mismatch");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_SIG_INVALID,
|
||||
"vb2_verify_fw_preamble() sig mismatch");
|
||||
|
||||
/* Check that we signed header, kernel subkey, and body sig */
|
||||
Memcpy(h, hdr, hsize);
|
||||
@@ -256,20 +274,23 @@ static void test_verify_fw_preamble(const VbPublicKey *public_key,
|
||||
h->body_signature.sig_offset = 0;
|
||||
h->body_signature.sig_size = 0;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() didn't sign header");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
|
||||
"vb2_verify_fw_preamble() didn't sign header");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->kernel_subkey.key_offset = hsize;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() kernel subkey off end");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE,
|
||||
"vb2_verify_fw_preamble() kernel subkey off end");
|
||||
|
||||
Memcpy(h, hdr, hsize);
|
||||
h->body_signature.sig_offset = hsize;
|
||||
resign_fw_preamble(h, private_key);
|
||||
TEST_NEQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
0, "vb2_verify_fw_preamble() body sig off end");
|
||||
TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
|
||||
VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
|
||||
"vb2_verify_fw_preamble() body sig off end");
|
||||
|
||||
/* TODO: verify with extra padding at end of header. */
|
||||
|
||||
|
||||
@@ -26,24 +26,26 @@ static void misc_test(void)
|
||||
.workbuf_size = sizeof(workbuf),
|
||||
};
|
||||
|
||||
TEST_EQ(vb2_init_context(&c), 0, "Init context good");
|
||||
TEST_SUCC(vb2_init_context(&c), "Init context good");
|
||||
TEST_EQ(c.workbuf_used, sizeof(struct vb2_shared_data),
|
||||
"Init vbsd");
|
||||
|
||||
/* Don't re-init if used is non-zero */
|
||||
c.workbuf_used = 200;
|
||||
TEST_EQ(vb2_init_context(&c), 0, "Re-init context good");
|
||||
TEST_SUCC(vb2_init_context(&c), "Re-init context good");
|
||||
TEST_EQ(c.workbuf_used, 200, "Didn't re-init");
|
||||
|
||||
/* Handle workbuf errors */
|
||||
c.workbuf_used = 0;
|
||||
c.workbuf_size = sizeof(struct vb2_shared_data) - 1;
|
||||
TEST_NEQ(vb2_init_context(&c), 0, "Init too small");
|
||||
TEST_EQ(vb2_init_context(&c),
|
||||
VB2_ERROR_INITCTX_WORKBUF_SMALL, "Init too small");
|
||||
c.workbuf_size = sizeof(workbuf);
|
||||
|
||||
/* Handle workbuf unaligned */
|
||||
c.workbuf++;
|
||||
TEST_NEQ(vb2_init_context(&c), 0, "Init unaligned");
|
||||
TEST_EQ(vb2_init_context(&c),
|
||||
VB2_ERROR_INITCTX_WORKBUF_ALIGN, "Init unaligned");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
||||
Reference in New Issue
Block a user