vb2_api_tests.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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 "2common.h"
  11. #include "2misc.h"
  12. #include "2nvstorage.h"
  13. #include "2rsa.h"
  14. #include "2secdata.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. static const uint8_t mock_hwid_digest[VB2_GBB_HWID_DIGEST_SIZE] = {
  26. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  27. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  28. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  29. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  30. };
  31. /* Mocked function data */
  32. static int retval_vb2_fw_parse_gbb;
  33. static int retval_vb2_check_dev_switch;
  34. static int retval_vb2_check_tpm_clear;
  35. static int retval_vb2_select_fw_slot;
  36. /* Type of test to reset for */
  37. enum reset_type {
  38. FOR_MISC,
  39. };
  40. static void reset_common_data(enum reset_type t)
  41. {
  42. memset(workbuf, 0xaa, sizeof(workbuf));
  43. memset(&cc, 0, sizeof(cc));
  44. cc.workbuf = workbuf;
  45. cc.workbuf_size = sizeof(workbuf);
  46. vb2_init_context(&cc);
  47. sd = vb2_get_sd(&cc);
  48. vb2_nv_init(&cc);
  49. vb2_secdata_create(&cc);
  50. vb2_secdata_init(&cc);
  51. retval_vb2_fw_parse_gbb = VB2_SUCCESS;
  52. retval_vb2_check_dev_switch = VB2_SUCCESS;
  53. retval_vb2_check_tpm_clear = VB2_SUCCESS;
  54. retval_vb2_select_fw_slot = VB2_SUCCESS;
  55. memcpy(sd->gbb_hwid_digest, mock_hwid_digest,
  56. sizeof(sd->gbb_hwid_digest));
  57. };
  58. /* Mocked functions */
  59. int vb2_fw_parse_gbb(struct vb2_context *ctx)
  60. {
  61. return retval_vb2_fw_parse_gbb;
  62. }
  63. int vb2_check_dev_switch(struct vb2_context *ctx)
  64. {
  65. return retval_vb2_check_dev_switch;
  66. }
  67. int vb2_check_tpm_clear(struct vb2_context *ctx)
  68. {
  69. return retval_vb2_check_tpm_clear;
  70. }
  71. int vb2_select_fw_slot(struct vb2_context *ctx)
  72. {
  73. return retval_vb2_select_fw_slot;
  74. }
  75. /* Tests */
  76. static void misc_tests(void)
  77. {
  78. /* Test secdata passthru functions */
  79. reset_common_data(FOR_MISC);
  80. /* Corrupt secdata so initial check will fail */
  81. cc.secdata[0] ^= 0x42;
  82. TEST_EQ(vb2api_secdata_check(&cc), VB2_ERROR_SECDATA_CRC,
  83. "secdata check");
  84. TEST_SUCC(vb2api_secdata_create(&cc), "secdata create");
  85. TEST_SUCC(vb2api_secdata_check(&cc), "secdata check 2");
  86. /* Test fail passthru */
  87. reset_common_data(FOR_MISC);
  88. vb2api_fail(&cc, 12, 34);
  89. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  90. 12, "vb2api_fail request");
  91. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
  92. 34, "vb2api_fail subcode");
  93. }
  94. static void phase1_tests(void)
  95. {
  96. reset_common_data(FOR_MISC);
  97. TEST_SUCC(vb2api_fw_phase1(&cc), "phase1 good");
  98. TEST_EQ(sd->recovery_reason, 0, " not recovery");
  99. TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
  100. TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
  101. reset_common_data(FOR_MISC);
  102. retval_vb2_fw_parse_gbb = VB2_ERROR_GBB_MAGIC;
  103. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  104. "phase1 gbb");
  105. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_GBB_HEADER,
  106. " recovery reason");
  107. TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
  108. TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
  109. /* Dev switch error in normal mode reboots to recovery */
  110. reset_common_data(FOR_MISC);
  111. retval_vb2_check_dev_switch = VB2_ERROR_MOCK;
  112. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_MOCK, "phase1 dev switch");
  113. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  114. VB2_RECOVERY_DEV_SWITCH, " recovery request");
  115. /* Dev switch error already in recovery mode just proceeds */
  116. reset_common_data(FOR_MISC);
  117. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
  118. retval_vb2_check_dev_switch = VB2_ERROR_MOCK;
  119. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  120. "phase1 dev switch error in recovery");
  121. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_UNSPECIFIED,
  122. " recovery reason");
  123. reset_common_data(FOR_MISC);
  124. cc.secdata[0] ^= 0x42;
  125. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  126. "phase1 secdata");
  127. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_SECDATA_INIT,
  128. " recovery reason");
  129. TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
  130. TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
  131. /* Test secdata-requested reboot */
  132. reset_common_data(FOR_MISC);
  133. cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
  134. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
  135. "phase1 secdata reboot normal");
  136. TEST_EQ(sd->recovery_reason, 0, " recovery reason");
  137. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  138. 1, " tpm reboot request");
  139. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  140. 0, " recovery request");
  141. reset_common_data(FOR_MISC);
  142. vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
  143. TEST_SUCC(vb2api_fw_phase1(&cc), "phase1 secdata reboot back normal");
  144. TEST_EQ(sd->recovery_reason, 0, " recovery reason");
  145. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  146. 0, " tpm reboot request");
  147. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  148. 0, " recovery request");
  149. reset_common_data(FOR_MISC);
  150. cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
  151. memset(cc.secdata, 0, sizeof(cc.secdata));
  152. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
  153. "phase1 secdata reboot normal, secdata blank");
  154. TEST_EQ(sd->recovery_reason, 0, " recovery reason");
  155. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  156. 1, " tpm reboot request");
  157. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  158. 0, " recovery request");
  159. reset_common_data(FOR_MISC);
  160. cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
  161. vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
  162. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  163. "phase1 secdata reboot normal again");
  164. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_TPM_REBOOT,
  165. " recovery reason");
  166. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  167. 1, " tpm reboot request");
  168. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  169. 0, " recovery request");
  170. reset_common_data(FOR_MISC);
  171. cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
  172. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
  173. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
  174. "phase1 secdata reboot recovery");
  175. /* Recovery reason isn't set this boot because we're rebooting first */
  176. TEST_EQ(sd->recovery_reason, 0, " recovery reason not set THIS boot");
  177. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  178. 1, " tpm reboot request");
  179. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  180. VB2_RECOVERY_RO_UNSPECIFIED, " recovery request not cleared");
  181. reset_common_data(FOR_MISC);
  182. vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
  183. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
  184. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  185. "phase1 secdata reboot back recovery");
  186. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_UNSPECIFIED,
  187. " recovery reason");
  188. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  189. 0, " tpm reboot request");
  190. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0,
  191. " recovery request cleared");
  192. reset_common_data(FOR_MISC);
  193. cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
  194. vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
  195. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
  196. TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
  197. "phase1 secdata reboot recovery again");
  198. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_UNSPECIFIED,
  199. " recovery reason");
  200. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
  201. 1, " tpm reboot request");
  202. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0,
  203. " recovery request cleared");
  204. }
  205. static void phase2_tests(void)
  206. {
  207. reset_common_data(FOR_MISC);
  208. TEST_SUCC(vb2api_fw_phase2(&cc), "phase2 good");
  209. TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
  210. reset_common_data(FOR_MISC);
  211. cc.flags |= VB2_CONTEXT_DEVELOPER_MODE;
  212. TEST_SUCC(vb2api_fw_phase2(&cc), "phase1 dev");
  213. TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
  214. reset_common_data(FOR_MISC);
  215. retval_vb2_check_tpm_clear = VB2_ERROR_MOCK;
  216. TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 tpm clear");
  217. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  218. VB2_RECOVERY_TPM_CLEAR_OWNER, " recovery reason");
  219. reset_common_data(FOR_MISC);
  220. retval_vb2_select_fw_slot = VB2_ERROR_MOCK;
  221. TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 slot");
  222. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  223. VB2_RECOVERY_FW_SLOT, " recovery reason");
  224. }
  225. static void get_pcr_digest_tests(void)
  226. {
  227. uint8_t digest[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
  228. uint8_t digest_org[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
  229. uint32_t digest_size;
  230. reset_common_data(FOR_MISC);
  231. memset(digest_org, 0, sizeof(digest_org));
  232. digest_size = sizeof(digest);
  233. memset(digest, 0, sizeof(digest));
  234. TEST_SUCC(vb2api_get_pcr_digest(
  235. &cc, BOOT_MODE_PCR, digest, &digest_size),
  236. "BOOT_MODE_PCR");
  237. TEST_EQ(digest_size, VB2_SHA1_DIGEST_SIZE, "BOOT_MODE_PCR digest size");
  238. TEST_TRUE(memcmp(digest, digest_org, digest_size),
  239. "BOOT_MODE_PCR digest");
  240. digest_size = sizeof(digest);
  241. memset(digest, 0, sizeof(digest));
  242. TEST_SUCC(vb2api_get_pcr_digest(
  243. &cc, HWID_DIGEST_PCR, digest, &digest_size),
  244. "HWID_DIGEST_PCR");
  245. TEST_EQ(digest_size, VB2_GBB_HWID_DIGEST_SIZE,
  246. "HWID_DIGEST_PCR digest size");
  247. TEST_FALSE(memcmp(digest, mock_hwid_digest, digest_size),
  248. "HWID_DIGEST_PCR digest");
  249. digest_size = 1;
  250. TEST_EQ(vb2api_get_pcr_digest(&cc, BOOT_MODE_PCR, digest, &digest_size),
  251. VB2_ERROR_API_PCR_DIGEST_BUF,
  252. "BOOT_MODE_PCR buffer too small");
  253. TEST_EQ(vb2api_get_pcr_digest(
  254. &cc, HWID_DIGEST_PCR + 1, digest, &digest_size),
  255. VB2_ERROR_API_PCR_DIGEST,
  256. "invalid enum vb2_pcr_digest");
  257. }
  258. int main(int argc, char* argv[])
  259. {
  260. misc_tests();
  261. phase1_tests();
  262. phase2_tests();
  263. get_pcr_digest_tests();
  264. return gTestSuccess ? 0 : 255;
  265. }