vb21_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 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 */ 26static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE] 27 __attribute__ ((aligned (16))); 28static struct vb2_context ctx; 29static struct vb2_shared_data *sd; 30 31static const uint8_t mock_body[320] = "Mock body"; 32static const int mock_body_size = sizeof(mock_body); 33static const int mock_hash_alg = VB2_HASH_SHA256; 34static int mock_sig_size; 35 36static 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 */ 44static int retval_vb2_load_fw_keyblock; 45static int retval_vb2_load_fw_preamble; 46 47/* Type of test to reset for */ 48enum reset_type { 49 FOR_MISC, 50 FOR_EXTEND_HASH, 51 FOR_CHECK_HASH, 52}; 53 54static void reset_common_data(enum reset_type t) 55{ 56 const struct vb2_private_key *hash_key; 57 struct vb2_fw_preamble2 *pre; 58 struct vb2_signature2 *sig; 59 uint32_t sig_offset; 60 61 int i; 62 63 memset(workbuf, 0xaa, sizeof(workbuf)); 64 65 memset(&ctx, 0, sizeof(ctx)); 66 ctx.workbuf = workbuf; 67 ctx.workbuf_size = sizeof(workbuf); 68 69 vb2_init_context(&ctx); 70 sd = vb2_get_sd(&ctx); 71 72 vb2_nv_init(&ctx); 73 74 vb2_secdata_create(&ctx); 75 vb2_secdata_init(&ctx); 76 77 retval_vb2_load_fw_keyblock = VB2_SUCCESS; 78 retval_vb2_load_fw_preamble = VB2_SUCCESS; 79 80 vb2_private_key_hash(&hash_key, mock_hash_alg); 81 82 sd->workbuf_preamble_offset = ctx.workbuf_used; 83 pre = (struct vb2_fw_preamble2 *) 84 (ctx.workbuf + sd->workbuf_preamble_offset); 85 pre->hash_count = 3; 86 pre->hash_offset = sig_offset = sizeof(*pre); 87 88 for (i = 0; i < 3; i++) { 89 vb2_sign_data(&sig, mock_body, mock_body_size - 16 * i, 90 hash_key, NULL); 91 memcpy(&sig->guid, test_guid + i, sizeof(sig->guid)); 92 memcpy((uint8_t *)pre + sig_offset, sig, sig->c.total_size); 93 sig_offset += sig->c.total_size; 94 mock_sig_size = sig->c.total_size; 95 free(sig); 96 } 97 98 sd->workbuf_preamble_size = sig_offset; 99 ctx.workbuf_used = sd->workbuf_preamble_offset 100 + sd->workbuf_preamble_size; 101 102 if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH) 103 vb2api_init_hash2(&ctx, test_guid, NULL); 104 105 if (t == FOR_CHECK_HASH) 106 vb2api_extend_hash(&ctx, mock_body, mock_body_size); 107}; 108 109/* Mocked functions */ 110 111int vb2_load_fw_keyblock2(struct vb2_context *ctx) 112{ 113 return retval_vb2_load_fw_keyblock; 114} 115 116int vb2_load_fw_preamble2(struct vb2_context *ctx) 117{ 118 return retval_vb2_load_fw_preamble; 119} 120 121/* Tests */ 122 123static void phase3_tests(void) 124{ 125 reset_common_data(FOR_MISC); 126 TEST_SUCC(vb2api_fw_phase3_2(&ctx), "phase3 good"); 127 128 reset_common_data(FOR_MISC); 129 retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK; 130 TEST_EQ(vb2api_fw_phase3_2(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); 131 TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), 132 VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); 133 134 reset_common_data(FOR_MISC); 135 retval_vb2_load_fw_preamble = VB2_ERROR_MOCK; 136 TEST_EQ(vb2api_fw_phase3_2(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); 137 TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), 138 VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); 139} 140 141static void init_hash_tests(void) 142{ 143 struct vb2_fw_preamble2 *pre; 144 struct vb2_signature2 *sig; 145 int wb_used_before; 146 uint32_t size; 147 148 reset_common_data(FOR_MISC); 149 pre = (struct vb2_fw_preamble2 *) 150 (ctx.workbuf + sd->workbuf_preamble_offset); 151 sig = (struct vb2_signature2 *)((uint8_t *)pre + pre->hash_offset); 152 153 wb_used_before = ctx.workbuf_used; 154 TEST_SUCC(vb2api_init_hash2(&ctx, test_guid, &size), 155 "init hash good"); 156 TEST_EQ(sd->workbuf_hash_offset, 157 (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) & 158 ~(VB2_WORKBUF_ALIGN - 1), 159 "hash context offset"); 160 TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context), 161 "hash context size"); 162 TEST_EQ(ctx.workbuf_used, 163 sd->workbuf_hash_offset + sd->workbuf_hash_size, 164 "hash uses workbuf"); 165 TEST_EQ(sd->hash_tag, 166 sd->workbuf_preamble_offset + pre->hash_offset, 167 "hash signature offset"); 168 TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining"); 169 170 wb_used_before = ctx.workbuf_used; 171 TEST_SUCC(vb2api_init_hash2(&ctx, test_guid + 2, NULL), 172 "init hash again"); 173 TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context"); 174 TEST_EQ(sd->hash_tag, 175 sd->workbuf_preamble_offset + pre->hash_offset + 176 2 * mock_sig_size, 177 "hash signature offset 2"); 178 179 reset_common_data(FOR_MISC); 180 TEST_EQ(vb2api_init_hash2(&ctx, test_guid + 3, &size), 181 VB2_ERROR_API_INIT_HASH_GUID, "init hash invalid guid"); 182 183 reset_common_data(FOR_MISC); 184 sd->workbuf_preamble_size = 0; 185 TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size), 186 VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble"); 187 188 reset_common_data(FOR_MISC); 189 ctx.workbuf_used = 190 ctx.workbuf_size - sizeof(struct vb2_digest_context) + 8; 191 TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size), 192 VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf"); 193 194 reset_common_data(FOR_MISC); 195 sig->hash_alg = VB2_HASH_INVALID; 196 TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size), 197 VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm"); 198} 199 200static void extend_hash_tests(void) 201{ 202 struct vb2_digest_context *dc; 203 204 reset_common_data(FOR_EXTEND_HASH); 205 TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32), 206 "hash extend good"); 207 TEST_EQ(sd->hash_remaining_size, mock_body_size - 32, 208 "hash extend remaining"); 209 TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32), 210 "hash extend again"); 211 TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2"); 212 213 reset_common_data(FOR_EXTEND_HASH); 214 sd->workbuf_hash_size = 0; 215 TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size), 216 VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf"); 217 218 reset_common_data(FOR_EXTEND_HASH); 219 TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1), 220 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much"); 221 222 reset_common_data(FOR_EXTEND_HASH); 223 TEST_EQ(vb2api_extend_hash(&ctx, mock_body, 0), 224 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty"); 225 226 reset_common_data(FOR_EXTEND_HASH); 227 dc = (struct vb2_digest_context *) 228 (ctx.workbuf + sd->workbuf_hash_offset); 229 dc->hash_alg = VB2_HASH_INVALID; 230 TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size), 231 VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail"); 232} 233 234static void check_hash_tests(void) 235{ 236 struct vb2_fw_preamble2 *pre; 237 struct vb2_signature2 *sig; 238 struct vb2_digest_context *dc; 239 240 reset_common_data(FOR_CHECK_HASH); 241 pre = (struct vb2_fw_preamble2 *) 242 (ctx.workbuf + sd->workbuf_preamble_offset); 243 sig = (struct vb2_signature2 *)((uint8_t *)pre + pre->hash_offset); 244 dc = (struct vb2_digest_context *) 245 (ctx.workbuf + sd->workbuf_hash_offset); 246 247 TEST_SUCC(vb2api_check_hash2(&ctx), "check hash good"); 248 249 reset_common_data(FOR_CHECK_HASH); 250 sd->hash_tag = 0; 251 TEST_EQ(vb2api_check_hash2(&ctx), 252 VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag"); 253 254 reset_common_data(FOR_CHECK_HASH); 255 sd->workbuf_hash_size = 0; 256 TEST_EQ(vb2api_check_hash2(&ctx), 257 VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf"); 258 259 reset_common_data(FOR_CHECK_HASH); 260 sd->hash_remaining_size = 1; 261 TEST_EQ(vb2api_check_hash2(&ctx), 262 VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size"); 263 264 reset_common_data(FOR_CHECK_HASH); 265 ctx.workbuf_used = ctx.workbuf_size; 266 TEST_EQ(vb2api_check_hash2(&ctx), 267 VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf"); 268 269 reset_common_data(FOR_CHECK_HASH); 270 dc->hash_alg = VB2_HASH_INVALID; 271 *((uint8_t *)sig + sig->sig_offset) ^= 0x55; 272 TEST_EQ(vb2api_check_hash2(&ctx), 273 VB2_ERROR_SHA_FINALIZE_ALGORITHM, "check hash finalize"); 274 275 reset_common_data(FOR_CHECK_HASH); 276 *((uint8_t *)sig + sig->sig_offset) ^= 0x55; 277 TEST_EQ(vb2api_check_hash2(&ctx), 278 VB2_ERROR_API_CHECK_HASH_SIG, "check hash sig"); 279} 280 281int main(int argc, char* argv[]) 282{ 283 phase3_tests(); 284 init_hash_tests(); 285 extend_hash_tests(); 286 check_hash_tests(); 287 288 return gTestSuccess ? 0 : 255; 289} 290