summaryrefslogtreecommitdiff
path: root/tests/vboot_api_kernel5_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/vboot_api_kernel5_tests.c')
-rw-r--r--tests/vboot_api_kernel5_tests.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/tests/vboot_api_kernel5_tests.c b/tests/vboot_api_kernel5_tests.c
new file mode 100644
index 00000000..8c59622f
--- /dev/null
+++ b/tests/vboot_api_kernel5_tests.c
@@ -0,0 +1,281 @@
+/* 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 "gbb_header.h"
+#include "host_common.h"
+#include "load_kernel_fw.h"
+#include "test_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 RSAPublicKey *mock_data_key;
+static int mock_data_key_allocated;
+
+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;
+
+ 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;
+ 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 KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
+ const VbPublicKey *key, int hash_only) {
+ hash_only_check = hash_only;
+
+ if (key_block_verify_fail)
+ return VBERROR_SIMULATED;
+
+ /* Use this as an opportunity to override the key block */
+ memcpy((void *)block, &kbh, sizeof(kbh));
+ return VBERROR_SUCCESS;
+}
+
+RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
+{
+ TEST_EQ(mock_data_key_allocated, 0, " mock data key not allocated");
+
+ if (mock_data_key)
+ mock_data_key_allocated++;
+
+ return mock_data_key;
+}
+
+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--;
+}
+
+int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
+ uint64_t size, const RSAPublicKey *key)
+{
+ if (preamble_verify_fail)
+ return VBERROR_SIMULATED;
+
+ /* Use this as an opportunity to override the preamble */
+ memcpy((void *)preamble, &kph, sizeof(kph));
+ return VBERROR_SUCCESS;
+}
+
+int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
+ const RSAPublicKey *key)
+{
+ if (verify_data_fail)
+ return VBERROR_SIMULATED;
+
+ 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");
+
+ /* 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();
+
+ if (vboot_api_stub_check_memory())
+ return 255;
+
+ return gTestSuccess ? 0 : 255;
+}