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 "2misc.h"
     13 #include "2nvstorage.h"
     14 #include "2rsa.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 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 const int mock_sig_size = 64;
     30 
     31 /* Mocked function data */
     32 
     33 static enum {
     34 	HWCRYPTO_DISABLED,
     35 	HWCRYPTO_ENABLED,
     36 	HWCRYPTO_FORBIDDEN,
     37 } hwcrypto_state;
     38 
     39 static int retval_vb2_load_fw_keyblock;
     40 static int retval_vb2_load_fw_preamble;
     41 static int retval_vb2_digest_finalize;
     42 static int retval_vb2_verify_digest;
     43 
     44 /* Type of test to reset for */
     45 enum reset_type {
     46 	FOR_MISC,
     47 	FOR_EXTEND_HASH,
     48 	FOR_CHECK_HASH,
     49 };
     50 
     51 static void reset_common_data(enum reset_type t)
     52 {
     53 	struct vb2_fw_preamble *pre;
     54 	struct vb2_packed_key *k;
     55 
     56 	memset(workbuf, 0xaa, sizeof(workbuf));
     57 
     58 	memset(&cc, 0, sizeof(cc));
     59 	cc.workbuf = workbuf;
     60 	cc.workbuf_size = sizeof(workbuf);
     61 
     62 	vb2_init_context(&cc);
     63 	sd = vb2_get_sd(&cc);
     64 
     65 	vb2_nv_init(&cc);
     66 
     67 	vb2_secdata_create(&cc);
     68 	vb2_secdata_init(&cc);
     69 
     70 	retval_vb2_load_fw_keyblock = VB2_SUCCESS;
     71 	retval_vb2_load_fw_preamble = VB2_SUCCESS;
     72 	retval_vb2_digest_finalize = VB2_SUCCESS;
     73 	retval_vb2_verify_digest = VB2_SUCCESS;
     74 
     75 	sd->workbuf_preamble_offset = cc.workbuf_used;
     76 	sd->workbuf_preamble_size = sizeof(*pre);
     77 	cc.workbuf_used = sd->workbuf_preamble_offset
     78 		+ sd->workbuf_preamble_size;
     79 	pre = (struct vb2_fw_preamble *)
     80 		(cc.workbuf + sd->workbuf_preamble_offset);
     81 	pre->body_signature.data_size = mock_body_size;
     82 	pre->body_signature.sig_size = mock_sig_size;
     83 	if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
     84 		pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
     85 	else
     86 		pre->flags = 0;
     87 
     88 	sd->workbuf_data_key_offset = cc.workbuf_used;
     89 	sd->workbuf_data_key_size = sizeof(*k) + 8;
     90 	cc.workbuf_used = sd->workbuf_data_key_offset +
     91 		sd->workbuf_data_key_size;
     92 	k = (struct vb2_packed_key *)
     93 		(cc.workbuf + sd->workbuf_data_key_offset);
     94 	k->algorithm = mock_algorithm;
     95 
     96 	if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
     97 		vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
     98 
     99 	if (t == FOR_CHECK_HASH)
    100 		vb2api_extend_hash(&cc, mock_body, mock_body_size);
    101 };
    102 
    103 /* Mocked functions */
    104 
    105 int vb2_load_fw_keyblock(struct vb2_context *ctx)
    106 {
    107 	return retval_vb2_load_fw_keyblock;
    108 }
    109 
    110 int vb2_load_fw_preamble(struct vb2_context *ctx)
    111 {
    112 	return retval_vb2_load_fw_preamble;
    113 }
    114 
    115 int vb2_unpack_key(struct vb2_public_key *key,
    116 		   const uint8_t *buf,
    117 		   uint32_t size)
    118 {
    119 	struct vb2_packed_key *k = (struct vb2_packed_key *)buf;
    120 
    121 	if (size != sizeof(*k) + 8)
    122 		return VB2_ERROR_UNPACK_KEY_SIZE;
    123 
    124 	key->sig_alg = vb2_crypto_to_signature(k->algorithm);
    125 	key->hash_alg = vb2_crypto_to_hash(k->algorithm);
    126 
    127 	return VB2_SUCCESS;
    128 }
    129 
    130 int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
    131 			       uint32_t data_size)
    132 {
    133 	switch (hwcrypto_state) {
    134 	case HWCRYPTO_DISABLED:
    135 		return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
    136 	case HWCRYPTO_ENABLED:
    137 		if (hash_alg != mock_hash_alg)
    138 			return VB2_ERROR_SHA_INIT_ALGORITHM;
    139 		else
    140 			return VB2_SUCCESS;
    141 	case HWCRYPTO_FORBIDDEN:
    142 	default:
    143 		return VB2_ERROR_UNKNOWN;
    144 	}
    145 }
    146 
    147 int vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
    148 				 uint32_t size)
    149 {
    150 	if (hwcrypto_state != HWCRYPTO_ENABLED)
    151 		return VB2_ERROR_UNKNOWN;
    152 
    153 	return VB2_SUCCESS;
    154 }
    155 
    156 int vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
    157 				   uint32_t digest_size)
    158 {
    159 	if (hwcrypto_state != HWCRYPTO_ENABLED)
    160 		return VB2_ERROR_UNKNOWN;
    161 
    162 	return retval_vb2_digest_finalize;
    163 }
    164 
    165 int vb2_digest_init(struct vb2_digest_context *dc,
    166 		    enum vb2_hash_algorithm hash_alg)
    167 {
    168 	if (hwcrypto_state == HWCRYPTO_ENABLED)
    169 		return VB2_ERROR_UNKNOWN;
    170 	if (hash_alg != mock_hash_alg)
    171 		return VB2_ERROR_SHA_INIT_ALGORITHM;
    172 
    173 	dc->hash_alg = hash_alg;
    174 	dc->using_hwcrypto = 0;
    175 
    176 	return VB2_SUCCESS;
    177 }
    178 
    179 int vb2_digest_extend(struct vb2_digest_context *dc,
    180 		      const uint8_t *buf,
    181 		      uint32_t size)
    182 {
    183 	if (hwcrypto_state == HWCRYPTO_ENABLED)
    184 		return VB2_ERROR_UNKNOWN;
    185 	if (dc->hash_alg != mock_hash_alg)
    186 		return VB2_ERROR_SHA_EXTEND_ALGORITHM;
    187 
    188 	return VB2_SUCCESS;
    189 }
    190 
    191 int vb2_digest_finalize(struct vb2_digest_context *dc,
    192 			uint8_t *digest,
    193 			uint32_t digest_size)
    194 {
    195 	if (hwcrypto_state == HWCRYPTO_ENABLED)
    196 		return VB2_ERROR_UNKNOWN;
    197 	return retval_vb2_digest_finalize;
    198 }
    199 
    200 uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
    201 {
    202 	return mock_sig_size;
    203 }
    204 
    205 int vb2_rsa_verify_digest(const struct vb2_public_key *key,
    206 			  uint8_t *sig,
    207 			  const uint8_t *digest,
    208 			  const struct vb2_workbuf *wb)
    209 {
    210 	return retval_vb2_verify_digest;
    211 }
    212 
    213 /* Tests */
    214 
    215 static void phase3_tests(void)
    216 {
    217 	reset_common_data(FOR_MISC);
    218 	TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
    219 
    220 	reset_common_data(FOR_MISC);
    221 	retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
    222 	TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
    223 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
    224 		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
    225 
    226 	reset_common_data(FOR_MISC);
    227 	retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
    228 	TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
    229 	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
    230 		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
    231 }
    232 
    233 static void init_hash_tests(void)
    234 {
    235 	struct vb2_packed_key *k;
    236 	int wb_used_before;
    237 	uint32_t size;
    238 
    239 	/* For now, all we support is body signature hash */
    240 	reset_common_data(FOR_MISC);
    241 	wb_used_before = cc.workbuf_used;
    242 	TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    243 		  "init hash good");
    244 	TEST_EQ(sd->workbuf_hash_offset,
    245 		(wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
    246 		~(VB2_WORKBUF_ALIGN - 1),
    247 		"hash context offset");
    248 	TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
    249 		"hash context size");
    250 	TEST_EQ(cc.workbuf_used,
    251 		sd->workbuf_hash_offset + sd->workbuf_hash_size,
    252 		"hash uses workbuf");
    253 	TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
    254 	TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
    255 
    256 	wb_used_before = cc.workbuf_used;
    257 	TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
    258 		  "init hash again");
    259 	TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
    260 
    261 	reset_common_data(FOR_MISC);
    262 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
    263 		VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
    264 
    265 	reset_common_data(FOR_MISC);
    266 	sd->workbuf_preamble_size = 0;
    267 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    268 		VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
    269 
    270 	reset_common_data(FOR_MISC);
    271 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
    272 		VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
    273 
    274 	reset_common_data(FOR_MISC);
    275 	cc.workbuf_used =
    276 		cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
    277 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    278 		VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
    279 
    280 	reset_common_data(FOR_MISC);
    281 	sd->workbuf_data_key_size = 0;
    282 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    283 		VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
    284 
    285 	reset_common_data(FOR_MISC);
    286 	sd->workbuf_data_key_size--;
    287 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    288 		VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
    289 
    290 	reset_common_data(FOR_MISC);
    291 	k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
    292 	k->algorithm--;
    293 	TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
    294 		VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
    295 }
    296 
    297 static void extend_hash_tests(void)
    298 {
    299 	struct vb2_digest_context *dc;
    300 
    301 	reset_common_data(FOR_EXTEND_HASH);
    302 	TEST_SUCC(vb2api_extend_hash(&cc, mock_body, 32),
    303 		"hash extend good");
    304 	TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
    305 		"hash extend remaining");
    306 	TEST_SUCC(vb2api_extend_hash(&cc, mock_body, mock_body_size - 32),
    307 		"hash extend again");
    308 	TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
    309 
    310 	reset_common_data(FOR_EXTEND_HASH);
    311 	sd->workbuf_hash_size = 0;
    312 	TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
    313 		VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
    314 
    315 	reset_common_data(FOR_EXTEND_HASH);
    316 	TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size + 1),
    317 		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
    318 
    319 	reset_common_data(FOR_EXTEND_HASH);
    320 	TEST_EQ(vb2api_extend_hash(&cc, mock_body, 0),
    321 		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
    322 
    323 	if (hwcrypto_state != HWCRYPTO_ENABLED) {
    324 		reset_common_data(FOR_EXTEND_HASH);
    325 		dc = (struct vb2_digest_context *)
    326 			(cc.workbuf + sd->workbuf_hash_offset);
    327 		dc->hash_alg = mock_hash_alg + 1;
    328 		TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
    329 			VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
    330 	}
    331 }
    332 
    333 static void check_hash_tests(void)
    334 {
    335 	struct vb2_fw_preamble *pre;
    336 
    337 	reset_common_data(FOR_CHECK_HASH);
    338 	TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
    339 
    340 	reset_common_data(FOR_CHECK_HASH);
    341 	sd->workbuf_preamble_size = 0;
    342 	TEST_EQ(vb2api_check_hash(&cc),
    343 		VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
    344 
    345 	reset_common_data(FOR_CHECK_HASH);
    346 	sd->workbuf_hash_size = 0;
    347 	TEST_EQ(vb2api_check_hash(&cc),
    348 		VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
    349 
    350 	reset_common_data(FOR_CHECK_HASH);
    351 	sd->hash_remaining_size = 1;
    352 	TEST_EQ(vb2api_check_hash(&cc),
    353 		VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
    354 
    355 	reset_common_data(FOR_CHECK_HASH);
    356 	cc.workbuf_used = cc.workbuf_size;
    357 	TEST_EQ(vb2api_check_hash(&cc),
    358 		VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
    359 
    360 	reset_common_data(FOR_CHECK_HASH);
    361 	retval_vb2_digest_finalize = VB2_ERROR_MOCK;
    362 	TEST_EQ(vb2api_check_hash(&cc),	VB2_ERROR_MOCK, "check hash finalize");
    363 
    364 	reset_common_data(FOR_CHECK_HASH);
    365 	sd->hash_tag = VB2_HASH_TAG_INVALID;
    366 	TEST_EQ(vb2api_check_hash(&cc),
    367 		VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
    368 
    369 	reset_common_data(FOR_CHECK_HASH);
    370 	sd->workbuf_data_key_size = 0;
    371 	TEST_EQ(vb2api_check_hash(&cc),
    372 		VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
    373 
    374 	reset_common_data(FOR_CHECK_HASH);
    375 	sd->workbuf_data_key_size--;
    376 	TEST_EQ(vb2api_check_hash(&cc),
    377 		VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
    378 
    379 	reset_common_data(FOR_CHECK_HASH);
    380 	pre = (struct vb2_fw_preamble *)
    381 		(cc.workbuf + sd->workbuf_preamble_offset);
    382 	pre->body_signature.sig_size++;
    383 	TEST_EQ(vb2api_check_hash(&cc),
    384 		VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");
    385 
    386 	reset_common_data(FOR_CHECK_HASH);
    387 	retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
    388 	TEST_EQ(vb2api_check_hash(&cc),
    389 		VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
    390 }
    391 
    392 int main(int argc, char* argv[])
    393 {
    394 	phase3_tests();
    395 
    396 	fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
    397 	hwcrypto_state = HWCRYPTO_DISABLED;
    398 	init_hash_tests();
    399 	extend_hash_tests();
    400 	check_hash_tests();
    401 
    402 	fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
    403 	hwcrypto_state = HWCRYPTO_ENABLED;
    404 	init_hash_tests();
    405 	extend_hash_tests();
    406 	check_hash_tests();
    407 
    408 	fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
    409 	hwcrypto_state = HWCRYPTO_FORBIDDEN;
    410 	init_hash_tests();
    411 	extend_hash_tests();
    412 	check_hash_tests();
    413 
    414 	return gTestSuccess ? 0 : 255;
    415 }
    416