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