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 api 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 "2rsa.h"
     16 #include "2secdata.h"
     17 
     18 #include "vb2_common.h"
     19 
     20 #include "host_key2.h"
     21 #include "host_signature2.h"
     22 
     23 #include "test_common.h"
     24 
     25 /* Common context for tests */
     26 static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
     27 	__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
     28 static struct vb2_context ctx;
     29 static struct vb2_shared_data *sd;
     30 
     31 static const uint8_t mock_body[320] = "Mock body";
     32 static const int mock_body_size = sizeof(mock_body);
     33 static const int mock_hash_alg = VB2_HASH_SHA256;
     34 static int mock_sig_size;
     35 
     36 static const struct vb2_guid test_guid[4] = {
     37 	{.raw = {0x11}},
     38 	{.raw = {0x22}},
     39 	{.raw = {0x33}},
     40 	{.raw = {0x44}},
     41 };
     42 
     43 /* Mocked function data */
     44 
     45 static enum {
     46 	HWCRYPTO_DISABLED,
     47 	HWCRYPTO_ENABLED,
     48 	HWCRYPTO_FORBIDDEN,
     49 } hwcrypto_state;
     50 
     51 static struct vb2_digest_context hwcrypto_emulation_dc;
     52 
     53 static int retval_hwcrypto;
     54 static int retval_vb2_load_fw_keyblock;
     55 static int retval_vb2_load_fw_preamble;
     56 
     57 /* Type of test to reset for */
     58 enum reset_type {
     59 	FOR_MISC,
     60 	FOR_EXTEND_HASH,
     61 	FOR_CHECK_HASH,
     62 };
     63 
     64 static void reset_common_data(enum reset_type t)
     65 {
     66 	const struct vb2_private_key *hash_key;
     67 	struct vb2_fw_preamble *pre;
     68 	struct vb2_signature *sig;
     69 	uint32_t sig_offset;
     70 
     71 	int i;
     72 
     73 	memset(workbuf, 0xaa, sizeof(workbuf));
     74 
     75 	memset(&ctx, 0, sizeof(ctx));
     76 	ctx.workbuf = workbuf;
     77 	ctx.workbuf_size = sizeof(workbuf);
     78 
     79 	vb2_init_context(&ctx);
     80 	sd = vb2_get_sd(&ctx);
     81 
     82 	vb2_nv_init(&ctx);
     83 
     84 	vb2_secdata_create(&ctx);
     85 	vb2_secdata_init(&ctx);
     86 
     87 	memset(&hwcrypto_emulation_dc, 0, sizeof(hwcrypto_emulation_dc));
     88 	retval_hwcrypto = VB2_SUCCESS;
     89 	retval_vb2_load_fw_keyblock = VB2_SUCCESS;
     90 	retval_vb2_load_fw_preamble = VB2_SUCCESS;
     91 
     92 	vb2_private_key_hash(&hash_key, mock_hash_alg);
     93 
     94 	sd->workbuf_preamble_offset = ctx.workbuf_used;
     95 	pre = (struct vb2_fw_preamble *)
     96 		(ctx.workbuf + sd->workbuf_preamble_offset);
     97 	pre->hash_count = 3;
     98 	pre->hash_offset = sig_offset = sizeof(*pre);
     99 	if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
    100 		pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
    101 	else
    102 		pre->flags = 0;
    103 
    104 	for (i = 0; i < 3; i++) {
    105 		vb2_sign_data(&sig, mock_body, mock_body_size - 16 * i,
    106 			      hash_key, NULL);
    107 		memcpy(&sig->guid, test_guid + i, sizeof(sig->guid));
    108 		memcpy((uint8_t *)pre + sig_offset, sig, sig->c.total_size);
    109 		sig_offset += sig->c.total_size;
    110 		mock_sig_size = sig->c.total_size;
    111 		free(sig);
    112 	}
    113 
    114 	sd->workbuf_preamble_size = sig_offset;
    115 	ctx.workbuf_used = sd->workbuf_preamble_offset
    116 		+ sd->workbuf_preamble_size;
    117 
    118 	if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
    119 		vb2api_init_hash2(&ctx, test_guid, NULL);
    120 
    121 	if (t == FOR_CHECK_HASH)
    122 		vb2api_extend_hash(&ctx, mock_body, mock_body_size);
    123 };
    124 
    125 /* Mocked functions */
    126 
    127 int vb2_load_fw_keyblock(struct vb2_context *ctx)
    128 {
    129 	return retval_vb2_load_fw_keyblock;
    130 }
    131 
    132 int vb2_load_fw_preamble(struct vb2_context *ctx)
    133 {
    134 	return retval_vb2_load_fw_preamble;
    135 }
    136 
    137 int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
    138 			       uint32_t data_size)
    139 {
    140 	vb2_digest_init(&hwcrypto_emulation_dc, hash_alg);
    141 
    142 	switch (hwcrypto_state) {
    143 	case HWCRYPTO_DISABLED:
    144 		return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
    145 	case HWCRYPTO_ENABLED:
    146 		if (hash_alg != mock_hash_alg)
    147 			return VB2_ERROR_SHA_INIT_ALGORITHM;
    148 		else
    149 			return retval_hwcrypto;
    150 	case HWCRYPTO_FORBIDDEN:
    151 	default:
    152 		return VB2_ERROR_UNKNOWN;
    153 	}
    154 }
    155 
    156 int vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
    157 				 uint32_t size)
    158 {
    159 	vb2_digest_extend(&hwcrypto_emulation_dc, buf, size);
    160 
    161 	if (hwcrypto_state != HWCRYPTO_ENABLED)
    162 		return VB2_ERROR_UNKNOWN;
    163 
    164 	return retval_hwcrypto;
    165 }
    166 
    167 int vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
    168 				   uint32_t digest_size)
    169 {
    170 	vb2_digest_finalize(&hwcrypto_emulation_dc, digest, digest_size);
    171 
    172 	if (hwcrypto_state != HWCRYPTO_ENABLED)
    173 		return VB2_ERROR_UNKNOWN;
    174 
    175 	return retval_hwcrypto;
    176 }
    177 
    178 /* Tests */
    179 
    180 static void phase3_tests(void)
    181 {
    182 	reset_common_data(FOR_MISC);
    183 	TEST_SUCC(vb2api_fw_phase3(&ctx), "phase3 good");
    184 
    185 	reset_common_data(FOR_MISC);
    186 	retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
    187 	TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
    188 	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
    189 		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
    190 
    191 	reset_common_data(FOR_MISC);
    192 	retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
    193 	TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
    194 	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
    195 		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
    196 }
    197 
    198 static void init_hash_tests(void)
    199 {
    200 	struct vb2_fw_preamble *pre;
    201 	struct vb2_signature *sig;
    202 	int wb_used_before;
    203 	uint32_t size;
    204 
    205 	reset_common_data(FOR_MISC);
    206 	pre = (struct vb2_fw_preamble *)
    207 		(ctx.workbuf + sd->workbuf_preamble_offset);
    208 	sig = (struct vb2_signature *)((uint8_t *)pre + pre->hash_offset);
    209 
    210 	wb_used_before = ctx.workbuf_used;
    211 	TEST_SUCC(vb2api_init_hash2(&ctx, test_guid, &size),
    212 		  "init hash good");
    213 	TEST_EQ(sd->workbuf_hash_offset,
    214 		(wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
    215 		~(VB2_WORKBUF_ALIGN - 1),
    216 		"hash context offset");
    217 	TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
    218 		"hash context size");
    219 	TEST_EQ(ctx.workbuf_used,
    220 		sd->workbuf_hash_offset + sd->workbuf_hash_size,
    221 		"hash uses workbuf");
    222 	TEST_EQ(sd->hash_tag,
    223 		sd->workbuf_preamble_offset + pre->hash_offset,
    224 		"hash signature offset");
    225 	TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
    226 
    227 	wb_used_before = ctx.workbuf_used;
    228 	TEST_SUCC(vb2api_init_hash2(&ctx, test_guid + 2, NULL),
    229 		  "init hash again");
    230 	TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context");
    231 	TEST_EQ(sd->hash_tag,
    232 		sd->workbuf_preamble_offset + pre->hash_offset +
    233 		2 * mock_sig_size,
    234 		"hash signature offset 2");
    235 
    236 	reset_common_data(FOR_MISC);
    237 	TEST_EQ(vb2api_init_hash2(&ctx, test_guid + 3, &size),
    238 		VB2_ERROR_API_INIT_HASH_GUID, "init hash invalid guid");
    239 
    240 	reset_common_data(FOR_MISC);
    241 	sd->workbuf_preamble_size = 0;
    242 	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
    243 		VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
    244 
    245 	reset_common_data(FOR_MISC);
    246 	ctx.workbuf_used =
    247 		ctx.workbuf_size - sizeof(struct vb2_digest_context) + 8;
    248 	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
    249 		VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
    250 
    251 	reset_common_data(FOR_MISC);
    252 	sig->hash_alg = VB2_HASH_INVALID;
    253 	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
    254 		VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
    255 
    256 	if (hwcrypto_state == HWCRYPTO_ENABLED) {
    257 		reset_common_data(FOR_MISC);
    258 		retval_hwcrypto = VB2_ERROR_MOCK;
    259 		TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
    260 			VB2_ERROR_MOCK, "init hash use hwcrypto");
    261 	}
    262 }
    263 
    264 static void extend_hash_tests(void)
    265 {
    266 	struct vb2_digest_context *dc;
    267 
    268 	reset_common_data(FOR_EXTEND_HASH);
    269 	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32),
    270 		"hash extend good");
    271 	TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
    272 		"hash extend remaining");
    273 	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32),
    274 		"hash extend again");
    275 	TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
    276 
    277 	reset_common_data(FOR_EXTEND_HASH);
    278 	sd->workbuf_hash_size = 0;
    279 	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
    280 		VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
    281 
    282 	reset_common_data(FOR_EXTEND_HASH);
    283 	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1),
    284 		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
    285 
    286 	reset_common_data(FOR_EXTEND_HASH);
    287 	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, 0),
    288 		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
    289 
    290 	if (hwcrypto_state == HWCRYPTO_ENABLED) {
    291 		reset_common_data(FOR_EXTEND_HASH);
    292 		retval_hwcrypto = VB2_ERROR_MOCK;
    293 		TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
    294 			VB2_ERROR_MOCK, "hash extend use hwcrypto");
    295 	} else {
    296 		reset_common_data(FOR_EXTEND_HASH);
    297 		dc = (struct vb2_digest_context *)
    298 			(ctx.workbuf + sd->workbuf_hash_offset);
    299 		dc->hash_alg = VB2_HASH_INVALID;
    300 		TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
    301 			VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
    302 	}
    303 }
    304 
    305 static void check_hash_tests(void)
    306 {
    307 	struct vb2_fw_preamble *pre;
    308 	struct vb2_signature *sig;
    309 	struct vb2_digest_context *dc;
    310 
    311 	reset_common_data(FOR_CHECK_HASH);
    312 	pre = (struct vb2_fw_preamble *)
    313 		(ctx.workbuf + sd->workbuf_preamble_offset);
    314 	sig = (struct vb2_signature *)((uint8_t *)pre + pre->hash_offset);
    315 	dc = (struct vb2_digest_context *)
    316 		(ctx.workbuf + sd->workbuf_hash_offset);
    317 
    318 	TEST_SUCC(vb2api_check_hash(&ctx), "check hash good");
    319 
    320 	reset_common_data(FOR_CHECK_HASH);
    321 	sd->hash_tag = 0;
    322 	TEST_EQ(vb2api_check_hash(&ctx),
    323 		VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
    324 
    325 	reset_common_data(FOR_CHECK_HASH);
    326 	sd->workbuf_hash_size = 0;
    327 	TEST_EQ(vb2api_check_hash(&ctx),
    328 		VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
    329 
    330 	reset_common_data(FOR_CHECK_HASH);
    331 	sd->hash_remaining_size = 1;
    332 	TEST_EQ(vb2api_check_hash(&ctx),
    333 		VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
    334 
    335 	reset_common_data(FOR_CHECK_HASH);
    336 	ctx.workbuf_used = ctx.workbuf_size;
    337 	TEST_EQ(vb2api_check_hash(&ctx),
    338 		VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
    339 
    340 	reset_common_data(FOR_CHECK_HASH);
    341 	*((uint8_t *)sig + sig->sig_offset) ^= 0x55;
    342 	TEST_EQ(vb2api_check_hash(&ctx),
    343 		VB2_ERROR_API_CHECK_HASH_SIG, "check hash sig");
    344 
    345 	if (hwcrypto_state == HWCRYPTO_ENABLED) {
    346 		reset_common_data(FOR_CHECK_HASH);
    347 		retval_hwcrypto = VB2_ERROR_MOCK;
    348 		TEST_EQ(vb2api_check_hash(&ctx),
    349 			VB2_ERROR_MOCK, "check hash use hwcrypto");
    350 	} else {
    351 		reset_common_data(FOR_CHECK_HASH);
    352 		dc->hash_alg = VB2_HASH_INVALID;
    353 		*((uint8_t *)sig + sig->sig_offset) ^= 0x55;
    354 		TEST_EQ(vb2api_check_hash(&ctx),
    355 			VB2_ERROR_SHA_FINALIZE_ALGORITHM, "check hash finaliz");
    356 	}
    357 }
    358 
    359 int main(int argc, char* argv[])
    360 {
    361 	phase3_tests();
    362 
    363 	fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
    364 	hwcrypto_state = HWCRYPTO_DISABLED;
    365 	init_hash_tests();
    366 	extend_hash_tests();
    367 	check_hash_tests();
    368 
    369 	fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
    370 	hwcrypto_state = HWCRYPTO_ENABLED;
    371 	init_hash_tests();
    372 	extend_hash_tests();
    373 	check_hash_tests();
    374 
    375 	fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
    376 	hwcrypto_state = HWCRYPTO_FORBIDDEN;
    377 	init_hash_tests();
    378 	extend_hash_tests();
    379 	check_hash_tests();
    380 
    381 	return gTestSuccess ? 0 : 255;
    382 }
    383