Home | History | Annotate | Download | only in tests
      1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  *
      5  * Tests for misc library
      6  */
      7 
      8 #include <stdio.h>
      9 
     10 #include "2sysincludes.h"
     11 #include "2api.h"
     12 #include "2common.h"
     13 #include "2misc.h"
     14 #include "2nvstorage.h"
     15 #include "2rsa.h"
     16 #include "2secdata.h"
     17 #include "test_common.h"
     18 
     19 /* Common context for tests */
     20 static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
     21 	__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
     22 static struct vb2_context cc;
     23 static struct vb2_shared_data *sd;
     24 
     25 const char mock_body[320] = "Mock body";
     26 const int mock_body_size = sizeof(mock_body);
     27 const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
     28 const int mock_hash_alg = VB2_HASH_SHA256;
     29 static const uint8_t mock_hwid_digest[VB2_GBB_HWID_DIGEST_SIZE] = {
     30 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     31 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     32 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     33 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
     34 };
     35 
     36 /* Mocked function data */
     37 
     38 static int retval_vb2_fw_parse_gbb;
     39 static int retval_vb2_check_dev_switch;
     40 static int retval_vb2_check_tpm_clear;
     41 static int retval_vb2_select_fw_slot;
     42 
     43 /* Type of test to reset for */
     44 enum reset_type {
     45 	FOR_MISC,
     46 };
     47 
     48 static void reset_common_data(enum reset_type t)
     49 {
     50 	memset(workbuf, 0xaa, sizeof(workbuf));
     51 
     52 	memset(&cc, 0, sizeof(cc));
     53 	cc.workbuf = workbuf;
     54 	cc.workbuf_size = sizeof(workbuf);
     55 
     56 	vb2_init_context(&cc);
     57 	sd = vb2_get_sd(&cc);
     58 
     59 	vb2_nv_init(&cc);
     60 
     61 	vb2_secdata_create(&cc);
     62 	vb2_secdata_init(&cc);
     63 
     64 	retval_vb2_fw_parse_gbb = VB2_SUCCESS;
     65 	retval_vb2_check_dev_switch = VB2_SUCCESS;
     66 	retval_vb2_check_tpm_clear = VB2_SUCCESS;
     67 	retval_vb2_select_fw_slot = VB2_SUCCESS;
     68 
     69 	memcpy(sd->gbb_hwid_digest, mock_hwid_digest,
     70 	       sizeof(sd->gbb_hwid_digest));
     71 };
     72 
     73 /* Mocked functions */
     74 
     75 int vb2_fw_parse_gbb(struct vb2_context *ctx)
     76 {
     77 	return retval_vb2_fw_parse_gbb;
     78 }
     79 
     80 int vb2_check_dev_switch(struct vb2_context *ctx)
     81 {
     82 	return retval_vb2_check_dev_switch;
     83 }
     84 
     85 int vb2_check_tpm_clear(struct vb2_context *ctx)
     86 {
     87 	return retval_vb2_check_tpm_clear;
     88 }
     89 
     90 int vb2_select_fw_slot(struct vb2_context *ctx)
     91 {
     92 	return retval_vb2_select_fw_slot;
     93 }
     94 
     95 /* Tests */
     96 
     97 static void misc_tests(void)
     98 {
     99 	/* Test secdata passthru functions */
    100 	reset_common_data(FOR_MISC);
    101 	/* Corrupt secdata so initial check will fail */
    102 	cc.secdata[0] ^= 0x42;
    103 	TEST_EQ(vb2api_secdata_check(&cc), VB2_ERROR_SECDATA_CRC,
    104 		"secdata check");
    105 	TEST_SUCC(vb2api_secdata_create(&cc), "secdata create");
    106 	TEST_SUCC(vb2api_secdata_check(&cc), "secdata check 2");
    107 
    108 	/* Test fail passthru */
    109 	reset_common_data(FOR_MISC);
    110 	vb2api_fail(&cc, 12, 34);
    111 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
    112 		12, "vb2api_fail request");
    113 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
    114 		34, "vb2api_fail subcode");
    115 }
    116 
    117 static void phase1_tests(void)
    118 {
    119 	reset_common_data(FOR_MISC);
    120 	TEST_SUCC(vb2api_fw_phase1(&cc), "phase1 good");
    121 	TEST_EQ(sd->recovery_reason, 0, "  not recovery");
    122 	TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, "  recovery flag");
    123 	TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    124 
    125 	reset_common_data(FOR_MISC);
    126 	retval_vb2_fw_parse_gbb = VB2_ERROR_GBB_MAGIC;
    127 	TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
    128 		"phase1 gbb");
    129 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_GBB_HEADER,
    130 		"  recovery reason");
    131 	TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, "  recovery flag");
    132 	TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    133 
    134 
    135 	reset_common_data(FOR_MISC);
    136 	retval_vb2_check_dev_switch = VB2_ERROR_MOCK;
    137 	TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
    138 		"phase1 dev switch");
    139 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_DEV_SWITCH,
    140 		"  recovery reason");
    141 	TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, "  recovery flag");
    142 	TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    143 
    144 	reset_common_data(FOR_MISC);
    145 	cc.secdata[0] ^= 0x42;
    146 	TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
    147 		"phase1 secdata");
    148 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_SECDATA_INIT,
    149 		"  recovery reason");
    150 	TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, "  recovery flag");
    151 	TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    152 }
    153 
    154 static void phase2_tests(void)
    155 {
    156 	reset_common_data(FOR_MISC);
    157 	TEST_SUCC(vb2api_fw_phase2(&cc), "phase2 good");
    158 	TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    159 
    160 	reset_common_data(FOR_MISC);
    161 	cc.flags |= VB2_CONTEXT_DEVELOPER_MODE;
    162 	TEST_SUCC(vb2api_fw_phase2(&cc), "phase1 dev");
    163 	TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, "  clear ram flag");
    164 
    165 	reset_common_data(FOR_MISC);
    166 	retval_vb2_check_tpm_clear = VB2_ERROR_MOCK;
    167 	TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 tpm clear");
    168 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
    169 		VB2_RECOVERY_TPM_CLEAR_OWNER, "  recovery reason");
    170 
    171 	reset_common_data(FOR_MISC);
    172 	retval_vb2_select_fw_slot = VB2_ERROR_MOCK;
    173 	TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 slot");
    174 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
    175 		VB2_RECOVERY_FW_SLOT, "  recovery reason");
    176 }
    177 
    178 static void get_pcr_digest_tests(void)
    179 {
    180 	uint8_t digest[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
    181 	uint8_t digest_org[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
    182 	uint32_t digest_size;
    183 
    184 	reset_common_data(FOR_MISC);
    185 	memset(digest_org, 0, sizeof(digest_org));
    186 
    187 	digest_size = sizeof(digest);
    188 	memset(digest, 0, sizeof(digest));
    189 	TEST_SUCC(vb2api_get_pcr_digest(
    190 			&cc, BOOT_MODE_PCR, digest, &digest_size),
    191 		  "BOOT_MODE_PCR");
    192 	TEST_EQ(digest_size, VB2_SHA1_DIGEST_SIZE, "BOOT_MODE_PCR digest size");
    193 	TEST_TRUE(memcmp(digest, digest_org, digest_size),
    194 		  "BOOT_MODE_PCR digest");
    195 
    196 	digest_size = sizeof(digest);
    197 	memset(digest, 0, sizeof(digest));
    198 	TEST_SUCC(vb2api_get_pcr_digest(
    199 			&cc, HWID_DIGEST_PCR, digest, &digest_size),
    200 		  "HWID_DIGEST_PCR");
    201 	TEST_EQ(digest_size, VB2_GBB_HWID_DIGEST_SIZE,
    202 		"HWID_DIGEST_PCR digest size");
    203 	TEST_FALSE(memcmp(digest, mock_hwid_digest, digest_size),
    204 		   "HWID_DIGEST_PCR digest");
    205 
    206 	digest_size = 1;
    207 	TEST_EQ(vb2api_get_pcr_digest(&cc, BOOT_MODE_PCR, digest, &digest_size),
    208 		VB2_ERROR_API_PCR_DIGEST_BUF,
    209 		"BOOT_MODE_PCR buffer too small");
    210 
    211 	TEST_EQ(vb2api_get_pcr_digest(
    212 			&cc, HWID_DIGEST_PCR + 1, digest, &digest_size),
    213 		VB2_ERROR_API_PCR_DIGEST,
    214 		"invalid enum vb2_pcr_digest");
    215 }
    216 
    217 int main(int argc, char* argv[])
    218 {
    219 	misc_tests();
    220 	phase1_tests();
    221 	phase2_tests();
    222 
    223 	get_pcr_digest_tests();
    224 
    225 	return gTestSuccess ? 0 : 255;
    226 }
    227