123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /* 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 vboot_api_kernel.c
- */
- #include <stdint.h>
- #include <stdio.h>
- #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"
- #include "vboot_nvstorage.h"
- #include "vboot_struct.h"
- /* Mock data */
- static VbCommonParams cparams;
- static VbSelectAndLoadKernelParams kparams;
- static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
- static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
- static GoogleBinaryBlockHeader gbb;
- 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 int unpack_key_fail;
- static VbNvContext vnc;
- static VbKeyBlockHeader kbh;
- static VbKernelPreambleHeader kph;
- static int hash_only_check;
- /**
- * Reset mock data (for use before each test)
- */
- static void ResetMocks(void)
- {
- memset(&cparams, 0, sizeof(cparams));
- cparams.shared_data_size = sizeof(shared_data);
- cparams.shared_data_blob = shared_data;
- cparams.gbb_data = &gbb;
- cparams.gbb_size = sizeof(gbb);
- memset(&kparams, 0, sizeof(kparams));
- memset(&gbb, 0, sizeof(gbb));
- gbb.major_version = GBB_MAJOR_VER;
- gbb.minor_version = GBB_MINOR_VER;
- gbb.flags = 0;
- memset(&vnc, 0, sizeof(vnc));
- VbNvSetup(&vnc);
- VbNvTeardown(&vnc); /* So CRC gets generated */
- memset(&shared_data, 0, sizeof(shared_data));
- VbSharedDataInit(shared, sizeof(shared_data));
- key_block_verify_fail = 0;
- preamble_verify_fail = 0;
- verify_data_fail = 0;
- memset(&kbh, 0, sizeof(kbh));
- kbh.data_key.key_version = 2;
- kbh.key_block_flags = -1;
- kbh.key_block_size = sizeof(kbh);
- memset(&kph, 0, sizeof(kph));
- kph.kernel_version = 1;
- kph.preamble_size = 4096 - kbh.key_block_size;
- kph.body_signature.data_size = 70144;
- kph.bootloader_address = 0xbeadd008;
- kph.bootloader_size = 0x1234;
- memcpy(kernel_buffer, &kbh, sizeof(kbh));
- memcpy((kernel_buffer + kbh.key_block_size), &kph, sizeof(kph));
- hash_only_check = -1;
- }
- static void copy_kbh(void)
- {
- memcpy(kernel_buffer, &kbh, sizeof(kbh));
- }
- /* Mocks */
- int vb2_unpack_key_buffer(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 VB2_ERROR_MOCK;
- /* Use this as an opportunity to override the key block */
- memcpy((void *)block, &kbh, sizeof(kbh));
- return VB2_SUCCESS;
- }
- int vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
- uint32_t size,
- const struct vb2_workbuf *wb)
- {
- hash_only_check = 1;
- if (key_block_verify_fail)
- return VB2_ERROR_MOCK;
- /* Use this as an opportunity to override the key block */
- memcpy((void *)block, &kbh, sizeof(kbh));
- return VB2_SUCCESS;
- }
- 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 VB2_ERROR_MOCK;
- /* Use this as an opportunity to override the preamble */
- memcpy((void *)preamble, &kph, sizeof(kph));
- return VB2_SUCCESS;
- }
- 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 VB2_ERROR_MOCK;
- return VB2_SUCCESS;
- }
- VbError_t VbExNvStorageRead(uint8_t *buf)
- {
- memcpy(buf, vnc.raw, sizeof(vnc.raw));
- return VBERROR_SUCCESS;
- }
- static void VerifyMemoryBootImageTest(void)
- {
- uint32_t u;
- int kernel_body_offset;
- int kernel_body_size;
- uintptr_t kernel_body_start;
- size_t kernel_buffer_size = sizeof(kernel_buffer);
- ResetMocks();
- kernel_body_offset = kbh.key_block_size + kph.preamble_size;
- kernel_body_size = sizeof(kernel_buffer) - kernel_body_offset;
- kernel_body_start = (uintptr_t)kernel_buffer + kernel_body_offset;
- u = VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size);
- TEST_EQ(u, 0, "Image good");
- TEST_EQ(kparams.partition_number, 0, " part num");
- TEST_EQ(kparams.bootloader_address, 0xbeadd008, " bootloader addr");
- TEST_EQ(kparams.bootloader_size, 0x1234, " bootloader size");
- TEST_PTR_EQ(kparams.kernel_buffer, (void *)(kernel_body_start),
- " kernel buffer");
- TEST_EQ(kparams.kernel_buffer_size, kernel_body_size,
- " kernel buffer size");
- /* Empty image buffer. */
- ResetMocks();
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, NULL,
- kernel_buffer_size),
- VBERROR_INVALID_PARAMETER, "Empty image");
- /* Illegal image size. */
- ResetMocks();
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer, 0),
- VBERROR_INVALID_PARAMETER, "Illegal image size");
- /* Key Block Verification Failure */
- ResetMocks();
- key_block_verify_fail = 1;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Key verify failed");
- TEST_EQ(hash_only_check, 0, " hash check");
- /* Key Block Hash Failure */
- ResetMocks();
- shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- gbb.flags = GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP;
- key_block_verify_fail = 1;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Key verify failed");
- TEST_EQ(hash_only_check, 1, " hash check");
- /* Key Block Hash Failure -- VBNV */
- ResetMocks();
- shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- key_block_verify_fail = 1;
- VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 1);
- VbNvTeardown(&vnc);
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Key verify failed");
- TEST_EQ(hash_only_check, 1, " hash check -- VBNV flag");
- /* Developer flag mismatch - dev switch on */
- ResetMocks();
- kbh.key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0 |
- KEY_BLOCK_FLAG_RECOVERY_1;
- copy_kbh();
- shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND,
- "Developer flag mismatch - dev switch on");
- /* Developer flag mismatch - dev switch on with GBB override */
- ResetMocks();
- kbh.key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0 |
- KEY_BLOCK_FLAG_RECOVERY_1;
- copy_kbh();
- gbb.flags = GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP;
- shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_SUCCESS,
- "Developer flag mismatch - dev switch on(gbb override)");
- /* Recovery flag mismatch - dev switch on with GBB override */
- ResetMocks();
- kbh.key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0 |
- KEY_BLOCK_FLAG_RECOVERY_0;
- copy_kbh();
- shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- gbb.flags = GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_SUCCESS,
- "Recovery flag mismatch - dev switch on(gbb override)");
- /* Developer flag mismatch - dev switch off */
- ResetMocks();
- kbh.key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_1 |
- KEY_BLOCK_FLAG_RECOVERY_1;
- copy_kbh();
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND,
- "Developer flag mismatch - dev switch off");
- /* Recovery flag mismatch */
- ResetMocks();
- kbh.key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0 |
- KEY_BLOCK_FLAG_RECOVERY_0;
- shared->flags = 0;
- copy_kbh();
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Recovery flag mismatch");
- /* Preamble verification */
- ResetMocks();
- preamble_verify_fail = 1;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Preamble verification");
- /* Data verification */
- ResetMocks();
- verify_data_fail = 1;
- TEST_EQ(VbVerifyMemoryBootImage(&cparams, &kparams, kernel_buffer,
- kernel_buffer_size),
- VBERROR_INVALID_KERNEL_FOUND, "Data verification");
- }
- int main(void)
- {
- VerifyMemoryBootImageTest();
- return gTestSuccess ? 0 : 255;
- }
|