vb20_api_tests.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. #include <stdio.h>
  8. #include "2sysincludes.h"
  9. #include "2api.h"
  10. #include "2misc.h"
  11. #include "2nvstorage.h"
  12. #include "2rsa.h"
  13. #include "2secdata.h"
  14. #include "vb2_common.h"
  15. #include "test_common.h"
  16. /* Common context for tests */
  17. static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
  18. __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
  19. static struct vb2_context cc;
  20. static struct vb2_shared_data *sd;
  21. const char mock_body[320] = "Mock body";
  22. const int mock_body_size = sizeof(mock_body);
  23. const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
  24. const int mock_hash_alg = VB2_HASH_SHA256;
  25. const int mock_sig_size = 64;
  26. static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE];
  27. static const uint32_t digest_result_size = sizeof(digest_result);
  28. /* Mocked function data */
  29. static enum {
  30. HWCRYPTO_DISABLED,
  31. HWCRYPTO_ENABLED,
  32. HWCRYPTO_FORBIDDEN,
  33. } hwcrypto_state;
  34. static int retval_vb2_load_fw_keyblock;
  35. static int retval_vb2_load_fw_preamble;
  36. static int retval_vb2_digest_finalize;
  37. static int retval_vb2_verify_digest;
  38. /* Type of test to reset for */
  39. enum reset_type {
  40. FOR_MISC,
  41. FOR_EXTEND_HASH,
  42. FOR_CHECK_HASH,
  43. };
  44. static void reset_common_data(enum reset_type t)
  45. {
  46. struct vb2_fw_preamble *pre;
  47. struct vb2_packed_key *k;
  48. memset(workbuf, 0xaa, sizeof(workbuf));
  49. memset(&cc, 0, sizeof(cc));
  50. cc.workbuf = workbuf;
  51. cc.workbuf_size = sizeof(workbuf);
  52. vb2_init_context(&cc);
  53. sd = vb2_get_sd(&cc);
  54. vb2_nv_init(&cc);
  55. vb2_secdata_create(&cc);
  56. vb2_secdata_init(&cc);
  57. retval_vb2_load_fw_keyblock = VB2_SUCCESS;
  58. retval_vb2_load_fw_preamble = VB2_SUCCESS;
  59. retval_vb2_digest_finalize = VB2_SUCCESS;
  60. retval_vb2_verify_digest = VB2_SUCCESS;
  61. sd->workbuf_preamble_offset = cc.workbuf_used;
  62. sd->workbuf_preamble_size = sizeof(*pre);
  63. cc.workbuf_used = sd->workbuf_preamble_offset
  64. + sd->workbuf_preamble_size;
  65. pre = (struct vb2_fw_preamble *)
  66. (cc.workbuf + sd->workbuf_preamble_offset);
  67. pre->body_signature.data_size = mock_body_size;
  68. pre->body_signature.sig_size = mock_sig_size;
  69. if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
  70. pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
  71. else
  72. pre->flags = 0;
  73. sd->workbuf_data_key_offset = cc.workbuf_used;
  74. sd->workbuf_data_key_size = sizeof(*k) + 8;
  75. cc.workbuf_used = sd->workbuf_data_key_offset +
  76. sd->workbuf_data_key_size;
  77. k = (struct vb2_packed_key *)
  78. (cc.workbuf + sd->workbuf_data_key_offset);
  79. k->algorithm = mock_algorithm;
  80. if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
  81. vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
  82. if (t == FOR_CHECK_HASH)
  83. vb2api_extend_hash(&cc, mock_body, mock_body_size);
  84. /* Always clear out the digest result. */
  85. memset(digest_result, 0, digest_result_size);
  86. };
  87. /* Mocked functions */
  88. int vb2_load_fw_keyblock(struct vb2_context *ctx)
  89. {
  90. return retval_vb2_load_fw_keyblock;
  91. }
  92. int vb2_load_fw_preamble(struct vb2_context *ctx)
  93. {
  94. return retval_vb2_load_fw_preamble;
  95. }
  96. int vb2_unpack_key_buffer(struct vb2_public_key *key,
  97. const uint8_t *buf,
  98. uint32_t size)
  99. {
  100. struct vb2_packed_key *k = (struct vb2_packed_key *)buf;
  101. if (size != sizeof(*k) + 8)
  102. return VB2_ERROR_UNPACK_KEY_SIZE;
  103. key->sig_alg = vb2_crypto_to_signature(k->algorithm);
  104. key->hash_alg = vb2_crypto_to_hash(k->algorithm);
  105. return VB2_SUCCESS;
  106. }
  107. int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
  108. uint32_t data_size)
  109. {
  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 VB2_SUCCESS;
  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. if (hwcrypto_state != HWCRYPTO_ENABLED)
  127. return VB2_ERROR_UNKNOWN;
  128. return VB2_SUCCESS;
  129. }
  130. static void fill_digest(uint8_t *digest, uint32_t digest_size)
  131. {
  132. /* Set the result to a known value. */
  133. memset(digest, 0x0a, digest_size);
  134. }
  135. int vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
  136. uint32_t digest_size)
  137. {
  138. if (hwcrypto_state != HWCRYPTO_ENABLED)
  139. return VB2_ERROR_UNKNOWN;
  140. if (retval_vb2_digest_finalize == VB2_SUCCESS)
  141. fill_digest(digest, digest_size);
  142. return retval_vb2_digest_finalize;
  143. }
  144. int vb2_digest_init(struct vb2_digest_context *dc,
  145. enum vb2_hash_algorithm hash_alg)
  146. {
  147. if (hwcrypto_state == HWCRYPTO_ENABLED)
  148. return VB2_ERROR_UNKNOWN;
  149. if (hash_alg != mock_hash_alg)
  150. return VB2_ERROR_SHA_INIT_ALGORITHM;
  151. dc->hash_alg = hash_alg;
  152. dc->using_hwcrypto = 0;
  153. return VB2_SUCCESS;
  154. }
  155. int vb2_digest_extend(struct vb2_digest_context *dc,
  156. const uint8_t *buf,
  157. uint32_t size)
  158. {
  159. if (hwcrypto_state == HWCRYPTO_ENABLED)
  160. return VB2_ERROR_UNKNOWN;
  161. if (dc->hash_alg != mock_hash_alg)
  162. return VB2_ERROR_SHA_EXTEND_ALGORITHM;
  163. return VB2_SUCCESS;
  164. }
  165. int vb2_digest_finalize(struct vb2_digest_context *dc,
  166. uint8_t *digest,
  167. uint32_t digest_size)
  168. {
  169. if (hwcrypto_state == HWCRYPTO_ENABLED)
  170. return VB2_ERROR_UNKNOWN;
  171. if (retval_vb2_digest_finalize == VB2_SUCCESS)
  172. fill_digest(digest, digest_size);
  173. return retval_vb2_digest_finalize;
  174. }
  175. uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
  176. {
  177. return mock_sig_size;
  178. }
  179. int vb2_rsa_verify_digest(const struct vb2_public_key *key,
  180. uint8_t *sig,
  181. const uint8_t *digest,
  182. const struct vb2_workbuf *wb)
  183. {
  184. return retval_vb2_verify_digest;
  185. }
  186. /* Tests */
  187. static void phase3_tests(void)
  188. {
  189. reset_common_data(FOR_MISC);
  190. TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
  191. reset_common_data(FOR_MISC);
  192. retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
  193. TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
  194. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  195. VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
  196. reset_common_data(FOR_MISC);
  197. retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
  198. TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
  199. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  200. VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
  201. }
  202. static void init_hash_tests(void)
  203. {
  204. struct vb2_packed_key *k;
  205. int wb_used_before;
  206. uint32_t size;
  207. /* For now, all we support is body signature hash */
  208. reset_common_data(FOR_MISC);
  209. wb_used_before = cc.workbuf_used;
  210. TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  211. "init hash good");
  212. TEST_EQ(sd->workbuf_hash_offset,
  213. (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
  214. ~(VB2_WORKBUF_ALIGN - 1),
  215. "hash context offset");
  216. TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
  217. "hash context size");
  218. TEST_EQ(cc.workbuf_used,
  219. sd->workbuf_hash_offset + sd->workbuf_hash_size,
  220. "hash uses workbuf");
  221. TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
  222. TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
  223. wb_used_before = cc.workbuf_used;
  224. TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
  225. "init hash again");
  226. TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
  227. reset_common_data(FOR_MISC);
  228. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
  229. VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
  230. reset_common_data(FOR_MISC);
  231. sd->workbuf_preamble_size = 0;
  232. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  233. VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
  234. reset_common_data(FOR_MISC);
  235. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
  236. VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
  237. reset_common_data(FOR_MISC);
  238. cc.workbuf_used =
  239. cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
  240. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  241. VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
  242. reset_common_data(FOR_MISC);
  243. sd->workbuf_data_key_size = 0;
  244. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  245. VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
  246. reset_common_data(FOR_MISC);
  247. sd->workbuf_data_key_size--;
  248. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  249. VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
  250. reset_common_data(FOR_MISC);
  251. k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
  252. k->algorithm--;
  253. TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
  254. VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
  255. }
  256. static void extend_hash_tests(void)
  257. {
  258. struct vb2_digest_context *dc;
  259. reset_common_data(FOR_EXTEND_HASH);
  260. TEST_SUCC(vb2api_extend_hash(&cc, mock_body, 32),
  261. "hash extend good");
  262. TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
  263. "hash extend remaining");
  264. TEST_SUCC(vb2api_extend_hash(&cc, mock_body, mock_body_size - 32),
  265. "hash extend again");
  266. TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
  267. reset_common_data(FOR_EXTEND_HASH);
  268. sd->workbuf_hash_size = 0;
  269. TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
  270. VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
  271. reset_common_data(FOR_EXTEND_HASH);
  272. TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size + 1),
  273. VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
  274. reset_common_data(FOR_EXTEND_HASH);
  275. TEST_EQ(vb2api_extend_hash(&cc, mock_body, 0),
  276. VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
  277. if (hwcrypto_state != HWCRYPTO_ENABLED) {
  278. reset_common_data(FOR_EXTEND_HASH);
  279. dc = (struct vb2_digest_context *)
  280. (cc.workbuf + sd->workbuf_hash_offset);
  281. dc->hash_alg = mock_hash_alg + 1;
  282. TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
  283. VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
  284. }
  285. }
  286. static void check_hash_tests(void)
  287. {
  288. struct vb2_fw_preamble *pre;
  289. const uint32_t digest_value = 0x0a0a0a0a;
  290. reset_common_data(FOR_CHECK_HASH);
  291. TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
  292. reset_common_data(FOR_CHECK_HASH);
  293. TEST_SUCC(vb2api_check_hash_get_digest(&cc, digest_result,
  294. digest_result_size), "check hash good with result");
  295. /* Check the first 4 bytes to ensure it was copied over. */
  296. TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)),
  297. "check digest value");
  298. reset_common_data(FOR_CHECK_HASH);
  299. TEST_EQ(vb2api_check_hash_get_digest(&cc, digest_result,
  300. digest_result_size - 1),
  301. VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size");
  302. TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0,
  303. "check digest wrong size");
  304. reset_common_data(FOR_CHECK_HASH);
  305. sd->workbuf_preamble_size = 0;
  306. TEST_EQ(vb2api_check_hash(&cc),
  307. VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
  308. reset_common_data(FOR_CHECK_HASH);
  309. sd->workbuf_hash_size = 0;
  310. TEST_EQ(vb2api_check_hash(&cc),
  311. VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
  312. reset_common_data(FOR_CHECK_HASH);
  313. sd->hash_remaining_size = 1;
  314. TEST_EQ(vb2api_check_hash(&cc),
  315. VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
  316. reset_common_data(FOR_CHECK_HASH);
  317. cc.workbuf_used = cc.workbuf_size;
  318. TEST_EQ(vb2api_check_hash(&cc),
  319. VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
  320. reset_common_data(FOR_CHECK_HASH);
  321. retval_vb2_digest_finalize = VB2_ERROR_MOCK;
  322. TEST_EQ(vb2api_check_hash(&cc), VB2_ERROR_MOCK, "check hash finalize");
  323. reset_common_data(FOR_CHECK_HASH);
  324. sd->hash_tag = VB2_HASH_TAG_INVALID;
  325. TEST_EQ(vb2api_check_hash(&cc),
  326. VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
  327. reset_common_data(FOR_CHECK_HASH);
  328. sd->workbuf_data_key_size = 0;
  329. TEST_EQ(vb2api_check_hash(&cc),
  330. VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
  331. reset_common_data(FOR_CHECK_HASH);
  332. sd->workbuf_data_key_size--;
  333. TEST_EQ(vb2api_check_hash(&cc),
  334. VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
  335. reset_common_data(FOR_CHECK_HASH);
  336. pre = (struct vb2_fw_preamble *)
  337. (cc.workbuf + sd->workbuf_preamble_offset);
  338. pre->body_signature.sig_size++;
  339. TEST_EQ(vb2api_check_hash(&cc),
  340. VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");
  341. reset_common_data(FOR_CHECK_HASH);
  342. retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
  343. TEST_EQ(vb2api_check_hash(&cc),
  344. VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
  345. }
  346. int main(int argc, char* argv[])
  347. {
  348. phase3_tests();
  349. fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
  350. hwcrypto_state = HWCRYPTO_DISABLED;
  351. init_hash_tests();
  352. extend_hash_tests();
  353. check_hash_tests();
  354. fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
  355. hwcrypto_state = HWCRYPTO_ENABLED;
  356. init_hash_tests();
  357. extend_hash_tests();
  358. check_hash_tests();
  359. fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
  360. hwcrypto_state = HWCRYPTO_FORBIDDEN;
  361. init_hash_tests();
  362. extend_hash_tests();
  363. check_hash_tests();
  364. return gTestSuccess ? 0 : 255;
  365. }