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 "2secdata.h"
     16 #include "vb2_common.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 /* Mocked function data */
     26 
     27 static struct {
     28 	struct vb2_gbb_header h;
     29 	struct vb2_packed_key rootkey;
     30 	char rootkey_data[32];
     31 } mock_gbb;
     32 
     33 static struct {
     34 	/* Keyblock */
     35 	struct {
     36 		struct vb2_keyblock kb;
     37 		char data_key_data[16];
     38 		uint8_t kbdata[128];
     39 	} k;
     40 	/* Preamble follows keyblock */
     41 	struct {
     42 		struct vb2_fw_preamble pre;
     43 		uint8_t predata[128];
     44 	} p;
     45 
     46 } mock_vblock;
     47 
     48 static int mock_read_res_fail_on_call;
     49 static int mock_unpack_key_retval;
     50 static int mock_verify_keyblock_retval;
     51 static int mock_verify_preamble_retval;
     52 
     53 /* Type of test to reset for */
     54 enum reset_type {
     55 	FOR_KEYBLOCK,
     56 	FOR_PREAMBLE
     57 };
     58 
     59 static void reset_common_data(enum reset_type t)
     60 {
     61 	struct vb2_keyblock *kb = &mock_vblock.k.kb;
     62 	struct vb2_fw_preamble *pre = &mock_vblock.p.pre;
     63 
     64 	memset(workbuf, 0xaa, sizeof(workbuf));
     65 
     66 	memset(&cc, 0, sizeof(cc));
     67 	cc.workbuf = workbuf;
     68 	cc.workbuf_size = sizeof(workbuf);
     69 
     70 	vb2_init_context(&cc);
     71 	sd = vb2_get_sd(&cc);
     72 
     73 	vb2_nv_init(&cc);
     74 
     75 	vb2_secdata_create(&cc);
     76 	vb2_secdata_init(&cc);
     77 
     78 	mock_read_res_fail_on_call = 0;
     79 	mock_unpack_key_retval = VB2_SUCCESS;
     80 	mock_verify_keyblock_retval = VB2_SUCCESS;
     81 	mock_verify_preamble_retval = VB2_SUCCESS;
     82 
     83 	/* Set up mock data for verifying keyblock */
     84 	sd->fw_version_secdata = 0x20002;
     85 	vb2_secdata_set(&cc, VB2_SECDATA_VERSIONS, sd->fw_version_secdata);
     86 
     87 	sd->gbb_rootkey_offset = vb2_offset_of(&mock_gbb, &mock_gbb.rootkey);
     88 	sd->gbb_rootkey_size = sizeof(mock_gbb.rootkey_data);
     89 	sd->last_fw_result = VB2_FW_RESULT_SUCCESS;
     90 
     91 	mock_gbb.rootkey.algorithm = 11;
     92 	mock_gbb.rootkey.key_offset =
     93 		vb2_offset_of(&mock_gbb.rootkey,
     94 			      &mock_gbb.rootkey_data);
     95 	mock_gbb.rootkey.key_size = sizeof(mock_gbb.rootkey_data);
     96 
     97 	kb->keyblock_size = sizeof(mock_vblock.k);
     98 	kb->data_key.algorithm = 7;
     99 	kb->data_key.key_version = 2;
    100 	kb->data_key.key_offset =
    101 		vb2_offset_of(&mock_vblock.k, &mock_vblock.k.data_key_data) -
    102 		vb2_offset_of(&mock_vblock.k, &kb->data_key);
    103 	kb->data_key.key_size = sizeof(mock_vblock.k.data_key_data);
    104 	strcpy(mock_vblock.k.data_key_data, "data key data!!");
    105 
    106 	pre->preamble_size = sizeof(mock_vblock.p);
    107 	pre->firmware_version = 2;
    108 
    109 	/* If verifying preamble, verify keyblock first to set up data key */
    110 	if (t == FOR_PREAMBLE)
    111 		vb2_load_fw_keyblock(&cc);
    112 };
    113 
    114 /* Mocked functions */
    115 
    116 int vb2ex_read_resource(struct vb2_context *ctx,
    117 			enum vb2_resource_index index,
    118 			uint32_t offset,
    119 			void *buf,
    120 			uint32_t size)
    121 {
    122 	uint8_t *rptr;
    123 	uint32_t rsize;
    124 
    125 	if (--mock_read_res_fail_on_call == 0)
    126 		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
    127 
    128 	switch(index) {
    129 	case VB2_RES_GBB:
    130 		rptr = (uint8_t *)&mock_gbb;
    131 		rsize = sizeof(mock_gbb);
    132 		break;
    133 	case VB2_RES_FW_VBLOCK:
    134 		rptr = (uint8_t *)&mock_vblock;
    135 		rsize = sizeof(mock_vblock);
    136 		break;
    137 	default:
    138 		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
    139 	}
    140 
    141 	if (offset > rsize || offset + size > rsize)
    142 		return VB2_ERROR_EX_READ_RESOURCE_SIZE;
    143 
    144 	memcpy(buf, rptr + offset, size);
    145 	return VB2_SUCCESS;
    146 }
    147 
    148 int vb2_unpack_key(struct vb2_public_key *key,
    149 		   const uint8_t *buf,
    150 		   uint32_t size)
    151 {
    152 	return mock_unpack_key_retval;
    153 }
    154 
    155 int vb2_verify_keyblock(struct vb2_keyblock *block,
    156 			uint32_t size,
    157 			const struct vb2_public_key *key,
    158 			const struct vb2_workbuf *wb)
    159 {
    160 	return mock_verify_keyblock_retval;
    161 }
    162 
    163 int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
    164 			   uint32_t size,
    165 			   const struct vb2_public_key *key,
    166 			   const struct vb2_workbuf *wb)
    167 {
    168 	return mock_verify_preamble_retval;
    169 }
    170 
    171 /* Tests */
    172 
    173 static void verify_keyblock_tests(void)
    174 {
    175 	struct vb2_keyblock *kb = &mock_vblock.k.kb;
    176 	struct vb2_packed_key *k;
    177 	int wb_used_before;
    178 
    179 	/* Test successful call */
    180 	reset_common_data(FOR_KEYBLOCK);
    181 	wb_used_before = cc.workbuf_used;
    182 	TEST_SUCC(vb2_load_fw_keyblock(&cc), "keyblock verify");
    183 	TEST_EQ(sd->fw_version, 0x20000, "keyblock version");
    184 	TEST_EQ(sd->vblock_preamble_offset, sizeof(mock_vblock.k),
    185 		"preamble offset");
    186 	TEST_EQ(sd->workbuf_data_key_offset,
    187 		(wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
    188 		~(VB2_WORKBUF_ALIGN - 1),
    189 		"keyblock data key offset");
    190 	TEST_EQ(cc.workbuf_used,
    191 		sd->workbuf_data_key_offset + sd->workbuf_data_key_size,
    192 		"workbuf used");
    193 
    194 	/* Make sure data key was properly saved */
    195 	k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
    196 	TEST_EQ(k->algorithm, 7, "data key algorithm");
    197 	TEST_EQ(k->key_version, 2, "data key version");
    198 	TEST_EQ(k->key_size, sizeof(mock_vblock.k.data_key_data),
    199 		"data key size");
    200 	TEST_EQ(memcmp(cc.workbuf + sd->workbuf_data_key_offset +
    201 		       k->key_offset, mock_vblock.k.data_key_data,
    202 		       sizeof(mock_vblock.k.data_key_data)),
    203 		0, "data key data");
    204 	TEST_EQ(cc.workbuf_used,
    205 		sd->workbuf_data_key_offset + sd->workbuf_data_key_size,
    206 		"workbuf used after");
    207 
    208 	/* Test failures */
    209 	reset_common_data(FOR_KEYBLOCK);
    210 	cc.workbuf_used = cc.workbuf_size - sd->gbb_rootkey_size + 8;
    211 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    212 		VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY,
    213 		"keyblock not enough workbuf for root key");
    214 
    215 	reset_common_data(FOR_KEYBLOCK);
    216 	sd->gbb_rootkey_size = sizeof(mock_gbb);
    217 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    218 		VB2_ERROR_EX_READ_RESOURCE_SIZE,
    219 		"keyblock read root key");
    220 
    221 	reset_common_data(FOR_KEYBLOCK);
    222 	mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
    223 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    224 		VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM,
    225 		"keyblock unpack root key");
    226 
    227 	reset_common_data(FOR_KEYBLOCK);
    228 	cc.workbuf_used = cc.workbuf_size - sd->gbb_rootkey_size - 8;
    229 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    230 		VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER,
    231 		"keyblock not enough workbuf for header");
    232 
    233 	reset_common_data(FOR_KEYBLOCK);
    234 	mock_read_res_fail_on_call = 2;
    235 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    236 		VB2_ERROR_EX_READ_RESOURCE_INDEX,
    237 		"keyblock read keyblock header");
    238 
    239 	reset_common_data(FOR_KEYBLOCK);
    240 	cc.workbuf_used = cc.workbuf_size - sd->gbb_rootkey_size
    241 		- sizeof(struct vb2_keyblock);
    242 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    243 		VB2_ERROR_FW_KEYBLOCK_WORKBUF,
    244 		"keyblock not enough workbuf for entire keyblock");
    245 
    246 	reset_common_data(FOR_KEYBLOCK);
    247 	kb->keyblock_size = sizeof(mock_vblock) + 1;
    248 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    249 		VB2_ERROR_EX_READ_RESOURCE_SIZE,
    250 		"keyblock read keyblock");
    251 
    252 	reset_common_data(FOR_KEYBLOCK);
    253 	mock_verify_keyblock_retval = VB2_ERROR_KEYBLOCK_MAGIC;
    254 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    255 		VB2_ERROR_KEYBLOCK_MAGIC,
    256 		"keyblock verify keyblock");
    257 
    258 	reset_common_data(FOR_KEYBLOCK);
    259 	kb->data_key.key_version = 0x10000;
    260 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    261 		VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE,
    262 		"keyblock version range");
    263 
    264 	reset_common_data(FOR_KEYBLOCK);
    265 	kb->data_key.key_version = 1;
    266 	TEST_EQ(vb2_load_fw_keyblock(&cc),
    267 		VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK,
    268 		"keyblock rollback");
    269 }
    270 
    271 static void verify_preamble_tests(void)
    272 {
    273 	struct vb2_fw_preamble *pre = &mock_vblock.p.pre;
    274 	int wb_used_before;
    275 	uint32_t v;
    276 
    277 	/* Test successful call */
    278 	reset_common_data(FOR_PREAMBLE);
    279 	wb_used_before = cc.workbuf_used;
    280 	TEST_SUCC(vb2_load_fw_preamble(&cc), "preamble good");
    281 	TEST_EQ(sd->fw_version, 0x20002, "combined version");
    282 	TEST_EQ(sd->workbuf_preamble_offset,
    283 		(wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
    284 		~(VB2_WORKBUF_ALIGN - 1),
    285 		"preamble offset");
    286 	TEST_EQ(sd->workbuf_preamble_size, pre->preamble_size, "preamble size");
    287 	TEST_EQ(cc.workbuf_used,
    288 		sd->workbuf_preamble_offset + sd->workbuf_preamble_size,
    289 		"workbuf used");
    290 
    291 	/* Expected failures */
    292 	reset_common_data(FOR_PREAMBLE);
    293 	sd->workbuf_data_key_size = 0;
    294 	TEST_EQ(vb2_load_fw_preamble(&cc),
    295 		VB2_ERROR_FW_PREAMBLE2_DATA_KEY,
    296 		"preamble no data key");
    297 
    298 	reset_common_data(FOR_PREAMBLE);
    299 	mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM;
    300 	TEST_EQ(vb2_load_fw_preamble(&cc),
    301 		VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM,
    302 		"preamble unpack data key");
    303 
    304 	reset_common_data(FOR_PREAMBLE);
    305 	cc.workbuf_used = cc.workbuf_size - sizeof(struct vb2_fw_preamble) + 8;
    306 	TEST_EQ(vb2_load_fw_preamble(&cc),
    307 		VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER,
    308 		"preamble not enough workbuf for header");
    309 
    310 	reset_common_data(FOR_PREAMBLE);
    311 	sd->vblock_preamble_offset = sizeof(mock_vblock);
    312 	TEST_EQ(vb2_load_fw_preamble(&cc),
    313 		VB2_ERROR_EX_READ_RESOURCE_SIZE,
    314 		"preamble read header");
    315 
    316 	reset_common_data(FOR_PREAMBLE);
    317 	cc.workbuf_used = cc.workbuf_size - sizeof(mock_vblock.p) + 8;
    318 	TEST_EQ(vb2_load_fw_preamble(&cc),
    319 		VB2_ERROR_FW_PREAMBLE2_WORKBUF,
    320 		"preamble not enough workbuf");
    321 
    322 	reset_common_data(FOR_PREAMBLE);
    323 	pre->preamble_size = sizeof(mock_vblock);
    324 	TEST_EQ(vb2_load_fw_preamble(&cc),
    325 		VB2_ERROR_EX_READ_RESOURCE_SIZE,
    326 		"preamble read full");
    327 
    328 	reset_common_data(FOR_PREAMBLE);
    329 	mock_verify_preamble_retval = VB2_ERROR_PREAMBLE_SIG_INVALID;
    330 	TEST_EQ(vb2_load_fw_preamble(&cc),
    331 		VB2_ERROR_PREAMBLE_SIG_INVALID,
    332 		"preamble verify");
    333 
    334 	reset_common_data(FOR_PREAMBLE);
    335 	pre->firmware_version = 0x10000;
    336 	TEST_EQ(vb2_load_fw_preamble(&cc),
    337 		VB2_ERROR_FW_PREAMBLE_VERSION_RANGE,
    338 		"preamble version range");
    339 
    340 	reset_common_data(FOR_PREAMBLE);
    341 	pre->firmware_version = 1;
    342 	TEST_EQ(vb2_load_fw_preamble(&cc),
    343 		VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK,
    344 		"preamble version rollback");
    345 
    346 	reset_common_data(FOR_PREAMBLE);
    347 	pre->firmware_version = 3;
    348 	TEST_SUCC(vb2_load_fw_preamble(&cc),
    349 		  "preamble version roll forward");
    350 	vb2_secdata_get(&cc, VB2_SECDATA_VERSIONS, &v);
    351 	TEST_EQ(v, 0x20003, "roll forward");
    352 
    353 	/* Newer version without result success doesn't roll forward */
    354 	reset_common_data(FOR_PREAMBLE);
    355 	pre->firmware_version = 3;
    356 	sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
    357 	TEST_SUCC(vb2_load_fw_preamble(&cc),
    358 		  "preamble version no roll forward 1");
    359 	vb2_secdata_get(&cc, VB2_SECDATA_VERSIONS, &v);
    360 	TEST_EQ(v, 0x20002, "no roll forward");
    361 
    362 	/* Newer version with success but for other slot doesn't roll forward */
    363 	reset_common_data(FOR_PREAMBLE);
    364 	pre->firmware_version = 3;
    365 	sd->last_fw_slot = 1;
    366 	TEST_SUCC(vb2_load_fw_preamble(&cc),
    367 		  "preamble version no roll forward 2");
    368 	vb2_secdata_get(&cc, VB2_SECDATA_VERSIONS, &v);
    369 	TEST_EQ(v, 0x20002, "no roll forward");
    370 }
    371 
    372 int main(int argc, char* argv[])
    373 {
    374 	verify_keyblock_tests();
    375 	verify_preamble_tests();
    376 
    377 	return gTestSuccess ? 0 : 255;
    378 }
    379