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 */ 20static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE] 21 __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); 22static struct vb2_context cc; 23static struct vb2_shared_data *sd; 24 25const char mock_body[320] = "Mock body"; 26const int mock_body_size = sizeof(mock_body); 27const int mock_algorithm = VB2_ALG_RSA2048_SHA256; 28const int mock_hash_alg = VB2_HASH_SHA256; 29const int mock_sig_size = 64; 30 31/* Mocked function data */ 32 33static enum { 34 HWCRYPTO_DISABLED, 35 HWCRYPTO_ENABLED, 36 HWCRYPTO_FORBIDDEN, 37} hwcrypto_state; 38 39static int retval_vb2_load_fw_keyblock; 40static int retval_vb2_load_fw_preamble; 41static int retval_vb2_digest_finalize; 42static int retval_vb2_verify_digest; 43 44/* Type of test to reset for */ 45enum reset_type { 46 FOR_MISC, 47 FOR_EXTEND_HASH, 48 FOR_CHECK_HASH, 49}; 50 51static 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 105int vb2_load_fw_keyblock(struct vb2_context *ctx) 106{ 107 return retval_vb2_load_fw_keyblock; 108} 109 110int vb2_load_fw_preamble(struct vb2_context *ctx) 111{ 112 return retval_vb2_load_fw_preamble; 113} 114 115int 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 130int 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 147int 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 156int 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 165int 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 179int 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 191int 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 200uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg) 201{ 202 return mock_sig_size; 203} 204 205int 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 215static 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 233static 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 297static 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 333static 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 392int 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