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