vb21_api_tests.c 10 KB

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