vb2_misc_tests.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  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 "2sysincludes.h"
  8. #include "2api.h"
  9. #include "2common.h"
  10. #include "2misc.h"
  11. #include "2nvstorage.h"
  12. #include "2secdata.h"
  13. #include "test_common.h"
  14. /* Common context for tests */
  15. static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
  16. __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
  17. static struct vb2_context cc;
  18. static struct vb2_shared_data *sd;
  19. /* Mocked function data */
  20. enum vb2_resource_index mock_resource_index;
  21. void *mock_resource_ptr;
  22. uint32_t mock_resource_size;
  23. int mock_tpm_clear_called;
  24. int mock_tpm_clear_retval;
  25. static void reset_common_data(void)
  26. {
  27. memset(workbuf, 0xaa, sizeof(workbuf));
  28. memset(&cc, 0, sizeof(cc));
  29. cc.workbuf = workbuf;
  30. cc.workbuf_size = sizeof(workbuf);
  31. vb2_init_context(&cc);
  32. sd = vb2_get_sd(&cc);
  33. vb2_nv_init(&cc);
  34. vb2_secdata_create(&cc);
  35. vb2_secdata_init(&cc);
  36. mock_tpm_clear_called = 0;
  37. mock_tpm_clear_retval = VB2_SUCCESS;
  38. };
  39. /* Mocked functions */
  40. int vb2ex_read_resource(struct vb2_context *ctx,
  41. enum vb2_resource_index index,
  42. uint32_t offset,
  43. void *buf,
  44. uint32_t size)
  45. {
  46. if (index != mock_resource_index)
  47. return VB2_ERROR_EX_READ_RESOURCE_INDEX;
  48. if (offset > mock_resource_size || offset + size > mock_resource_size)
  49. return VB2_ERROR_EX_READ_RESOURCE_SIZE;
  50. memcpy(buf, (uint8_t *)mock_resource_ptr + offset, size);
  51. return VB2_SUCCESS;
  52. }
  53. int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
  54. {
  55. mock_tpm_clear_called++;
  56. return mock_tpm_clear_retval;
  57. }
  58. /* Tests */
  59. static void init_context_tests(void)
  60. {
  61. /* Use our own context struct so we can re-init it */
  62. struct vb2_context c = {
  63. .workbuf = workbuf,
  64. .workbuf_size = sizeof(workbuf),
  65. };
  66. reset_common_data();
  67. TEST_SUCC(vb2_init_context(&c), "Init context good");
  68. TEST_EQ(c.workbuf_used, sizeof(struct vb2_shared_data),
  69. "Init vbsd");
  70. /* Don't re-init if used is non-zero */
  71. c.workbuf_used = 200;
  72. TEST_SUCC(vb2_init_context(&c), "Re-init context good");
  73. TEST_EQ(c.workbuf_used, 200, "Didn't re-init");
  74. /* Handle workbuf errors */
  75. c.workbuf_used = 0;
  76. c.workbuf_size = sizeof(struct vb2_shared_data) - 1;
  77. TEST_EQ(vb2_init_context(&c),
  78. VB2_ERROR_INITCTX_WORKBUF_SMALL, "Init too small");
  79. c.workbuf_size = sizeof(workbuf);
  80. /* Handle workbuf unaligned */
  81. c.workbuf++;
  82. TEST_EQ(vb2_init_context(&c),
  83. VB2_ERROR_INITCTX_WORKBUF_ALIGN, "Init unaligned");
  84. }
  85. static void misc_tests(void)
  86. {
  87. struct vb2_workbuf wb;
  88. reset_common_data();
  89. cc.workbuf_used = 16;
  90. vb2_workbuf_from_ctx(&cc, &wb);
  91. TEST_PTR_EQ(wb.buf, workbuf + 16, "vb_workbuf_from_ctx() buf");
  92. TEST_EQ(wb.size, cc.workbuf_size - 16, "vb_workbuf_from_ctx() size");
  93. }
  94. static void gbb_tests(void)
  95. {
  96. struct vb2_gbb_header gbb = {
  97. .signature = {'$', 'G', 'B', 'B'},
  98. .major_version = VB2_GBB_MAJOR_VER,
  99. .minor_version = VB2_GBB_MINOR_VER,
  100. .header_size = sizeof(struct vb2_gbb_header),
  101. .flags = 0x1234,
  102. .rootkey_offset = 240,
  103. .rootkey_size = 1040,
  104. };
  105. struct vb2_gbb_header gbbdest;
  106. TEST_EQ(sizeof(struct vb2_gbb_header),
  107. EXPECTED_VB2_GBB_HEADER_SIZE,
  108. "sizeof(struct vb2_gbb_header)");
  109. reset_common_data();
  110. /* Good contents */
  111. mock_resource_index = VB2_RES_GBB;
  112. mock_resource_ptr = &gbb;
  113. mock_resource_size = sizeof(gbb);
  114. TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest), "read gbb header good");
  115. TEST_SUCC(memcmp(&gbb, &gbbdest, sizeof(gbb)), "read gbb contents");
  116. mock_resource_index = VB2_RES_GBB + 1;
  117. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  118. VB2_ERROR_EX_READ_RESOURCE_INDEX, "read gbb header missing");
  119. mock_resource_index = VB2_RES_GBB;
  120. gbb.signature[0]++;
  121. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  122. VB2_ERROR_GBB_MAGIC, "read gbb header bad magic");
  123. gbb.signature[0]--;
  124. gbb.major_version = VB2_GBB_MAJOR_VER + 1;
  125. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  126. VB2_ERROR_GBB_VERSION, "read gbb header major version");
  127. gbb.major_version = VB2_GBB_MAJOR_VER;
  128. gbb.minor_version = VB2_GBB_MINOR_VER + 1;
  129. TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest),
  130. "read gbb header minor++");
  131. gbb.minor_version = 1;
  132. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  133. VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.1 fails");
  134. gbb.minor_version = 0;
  135. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  136. VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.0 fails");
  137. gbb.minor_version = VB2_GBB_MINOR_VER;
  138. gbb.header_size--;
  139. TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
  140. VB2_ERROR_GBB_HEADER_SIZE, "read gbb header size");
  141. TEST_EQ(vb2_fw_parse_gbb(&cc),
  142. VB2_ERROR_GBB_HEADER_SIZE, "parse gbb failure");
  143. gbb.header_size++;
  144. /* Parse GBB */
  145. TEST_SUCC(vb2_fw_parse_gbb(&cc), "parse gbb");
  146. TEST_EQ(sd->gbb_flags, gbb.flags, "gbb flags");
  147. TEST_EQ(sd->gbb_rootkey_offset, gbb.rootkey_offset, "rootkey offset");
  148. TEST_EQ(sd->gbb_rootkey_size, gbb.rootkey_size, "rootkey size");
  149. /* Workbuf failure */
  150. reset_common_data();
  151. cc.workbuf_used = cc.workbuf_size - 4;
  152. TEST_EQ(vb2_fw_parse_gbb(&cc),
  153. VB2_ERROR_GBB_WORKBUF, "parse gbb no workbuf");
  154. }
  155. static void fail_tests(void)
  156. {
  157. /* Early fail (before even NV init) */
  158. reset_common_data();
  159. sd->status &= ~VB2_SD_STATUS_NV_INIT;
  160. vb2_fail(&cc, 1, 2);
  161. TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT, 0, "vb2_fail inits NV");
  162. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  163. 1, "vb2_fail request");
  164. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
  165. 2, "vb2_fail subcode");
  166. /* Repeated fail doesn't overwrite the error code */
  167. vb2_fail(&cc, 3, 4);
  168. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  169. 1, "vb2_fail repeat");
  170. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
  171. 2, "vb2_fail repeat2");
  172. /* Fail with other slot good doesn't trigger recovery */
  173. reset_common_data();
  174. vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
  175. vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
  176. sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
  177. sd->fw_slot = 0;
  178. sd->last_fw_slot = 1;
  179. sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
  180. vb2_fail(&cc, 5, 6);
  181. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
  182. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  183. VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
  184. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 0, "vb2_fail use up tries");
  185. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "vb2_fail try other slot");
  186. /* Fail with other slot already failing triggers recovery */
  187. reset_common_data();
  188. sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
  189. sd->fw_slot = 1;
  190. sd->last_fw_slot = 0;
  191. sd->last_fw_result = VB2_FW_RESULT_FAILURE;
  192. vb2_fail(&cc, 7, 8);
  193. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 7,
  194. "vb2_fail both slots bad");
  195. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  196. VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
  197. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 0, "vb2_fail try other slot");
  198. }
  199. static void recovery_tests(void)
  200. {
  201. /* No recovery */
  202. reset_common_data();
  203. vb2_check_recovery(&cc);
  204. TEST_EQ(sd->recovery_reason, 0, "No recovery reason");
  205. TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
  206. 0, "Not manual recovery");
  207. TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
  208. 0, "Not recovery mode");
  209. /* From request */
  210. reset_common_data();
  211. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 3);
  212. vb2_check_recovery(&cc);
  213. TEST_EQ(sd->recovery_reason, 3, "Recovery reason from request");
  214. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "NV cleared");
  215. TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
  216. 0, "Not manual recovery");
  217. TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
  218. 0, "Recovery mode");
  219. /* From request, but already failed */
  220. reset_common_data();
  221. vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 4);
  222. sd->recovery_reason = 5;
  223. vb2_check_recovery(&cc);
  224. TEST_EQ(sd->recovery_reason, 5, "Recovery reason already failed");
  225. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  226. 0, "NV still cleared");
  227. /* Override */
  228. reset_common_data();
  229. sd->recovery_reason = 6;
  230. cc.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
  231. vb2_check_recovery(&cc);
  232. TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_MANUAL,
  233. "Recovery reason forced");
  234. TEST_NEQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
  235. 0, "SD flag set");
  236. }
  237. static void dev_switch_tests(void)
  238. {
  239. uint32_t v;
  240. /* Normal mode */
  241. reset_common_data();
  242. TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
  243. TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd not in dev");
  244. TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx not in dev");
  245. TEST_EQ(mock_tpm_clear_called, 0, " no tpm clear");
  246. /* Dev mode */
  247. reset_common_data();
  248. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
  249. (VB2_SECDATA_FLAG_DEV_MODE |
  250. VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
  251. TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode on");
  252. TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd in dev");
  253. TEST_NEQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx in dev");
  254. TEST_EQ(mock_tpm_clear_called, 0, " no tpm clear");
  255. /* Any normal mode boot clears dev boot flags */
  256. reset_common_data();
  257. vb2_nv_set(&cc, VB2_NV_DEV_BOOT_USB, 1);
  258. vb2_nv_set(&cc, VB2_NV_DEV_BOOT_LEGACY, 1);
  259. vb2_nv_set(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
  260. vb2_nv_set(&cc, VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP, 1);
  261. vb2_nv_set(&cc, VB2_NV_DEV_DEFAULT_BOOT, 1);
  262. vb2_nv_set(&cc, VB2_NV_FASTBOOT_UNLOCK_IN_FW, 1);
  263. TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
  264. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_USB),
  265. 0, " cleared dev boot usb");
  266. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_LEGACY),
  267. 0, " cleared dev boot legacy");
  268. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY),
  269. 0, " cleared dev boot signed only");
  270. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP),
  271. 0, " cleared dev boot fastboot full cap");
  272. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_DEFAULT_BOOT),
  273. 0, " cleared dev default boot");
  274. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FASTBOOT_UNLOCK_IN_FW),
  275. 0, " cleared dev boot fastboot unlock in fw");
  276. /* Normal-dev transition clears TPM */
  277. reset_common_data();
  278. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS, VB2_SECDATA_FLAG_DEV_MODE);
  279. TEST_SUCC(vb2_check_dev_switch(&cc), "to dev mode");
  280. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  281. vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
  282. TEST_EQ(v, (VB2_SECDATA_FLAG_DEV_MODE |
  283. VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER),
  284. " last boot developer now");
  285. /* Dev-normal transition clears TPM too */
  286. reset_common_data();
  287. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
  288. VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
  289. TEST_SUCC(vb2_check_dev_switch(&cc), "from dev mode");
  290. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  291. vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
  292. TEST_EQ(v, 0, " last boot not developer now");
  293. /* Disable dev mode */
  294. reset_common_data();
  295. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
  296. (VB2_SECDATA_FLAG_DEV_MODE |
  297. VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
  298. vb2_nv_set(&cc, VB2_NV_DISABLE_DEV_REQUEST, 1);
  299. TEST_SUCC(vb2_check_dev_switch(&cc), "disable dev request");
  300. TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd not in dev");
  301. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DISABLE_DEV_REQUEST),
  302. 0, " request cleared");
  303. /* Force enabled by GBB */
  304. reset_common_data();
  305. sd->gbb_flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
  306. TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via gbb");
  307. TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd in dev");
  308. vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
  309. TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
  310. " doesn't set dev on in secdata but does set last boot dev");
  311. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  312. /* Force enabled by ctx flag */
  313. reset_common_data();
  314. cc.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
  315. TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via ctx flag");
  316. TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd in dev");
  317. vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
  318. TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
  319. " doesn't set dev on in secdata but does set last boot dev");
  320. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  321. /* Simulate clear owner failure */
  322. reset_common_data();
  323. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
  324. VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
  325. mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
  326. TEST_EQ(vb2_check_dev_switch(&cc),
  327. VB2_ERROR_EX_TPM_CLEAR_OWNER, "tpm clear fail");
  328. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  329. vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
  330. TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
  331. " last boot still developer");
  332. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
  333. VB2_RECOVERY_TPM_CLEAR_OWNER, " requests recovery");
  334. TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
  335. (uint8_t)VB2_ERROR_EX_TPM_CLEAR_OWNER, " recovery subcode");
  336. /*
  337. * Secdata failure in normal mode fails and shows dev=0 even if dev
  338. * mode was on in the (inaccessible) secdata.
  339. */
  340. reset_common_data();
  341. vb2_secdata_set(&cc, VB2_SECDATA_FLAGS, VB2_SECDATA_FLAG_DEV_MODE);
  342. sd->status &= ~VB2_SD_STATUS_SECDATA_INIT;
  343. TEST_EQ(vb2_check_dev_switch(&cc), VB2_ERROR_SECDATA_GET_UNINITIALIZED,
  344. "secdata fail normal");
  345. TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd not in dev");
  346. TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx not in dev");
  347. /* Secdata failure in recovery mode continues */
  348. reset_common_data();
  349. cc.flags |= VB2_CONTEXT_RECOVERY_MODE;
  350. sd->status &= ~VB2_SD_STATUS_SECDATA_INIT;
  351. TEST_SUCC(vb2_check_dev_switch(&cc), "secdata fail recovery");
  352. TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd not in dev");
  353. TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx not in dev");
  354. /* And doesn't check or clear dev disable request */
  355. reset_common_data();
  356. cc.flags |= VB2_CONTEXT_RECOVERY_MODE;
  357. sd->status &= ~VB2_SD_STATUS_SECDATA_INIT;
  358. vb2_nv_set(&cc, VB2_NV_DISABLE_DEV_REQUEST, 1);
  359. TEST_SUCC(vb2_check_dev_switch(&cc), "secdata fail recovery disable");
  360. TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd not in dev");
  361. TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx not in dev");
  362. TEST_EQ(vb2_nv_get(&cc, VB2_NV_DISABLE_DEV_REQUEST),
  363. 1, " request not cleared");
  364. /* Can still override with GBB flag */
  365. reset_common_data();
  366. cc.flags |= VB2_CONTEXT_RECOVERY_MODE;
  367. sd->status &= ~VB2_SD_STATUS_SECDATA_INIT;
  368. sd->gbb_flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
  369. TEST_SUCC(vb2_check_dev_switch(&cc), "secdata fail recovery gbb");
  370. TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd in dev");
  371. TEST_NEQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx in dev");
  372. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  373. /* Can still override with context flag */
  374. reset_common_data();
  375. cc.flags |= VB2_CONTEXT_RECOVERY_MODE;
  376. cc.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
  377. sd->status &= ~VB2_SD_STATUS_SECDATA_INIT;
  378. TEST_SUCC(vb2_check_dev_switch(&cc), "secdata fail recovery ctx");
  379. TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, " sd in dev");
  380. TEST_NEQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, " ctx in dev");
  381. TEST_EQ(mock_tpm_clear_called, 1, " tpm clear");
  382. }
  383. static void tpm_clear_tests(void)
  384. {
  385. /* No clear request */
  386. reset_common_data();
  387. TEST_SUCC(vb2_check_tpm_clear(&cc), "no clear request");
  388. TEST_EQ(mock_tpm_clear_called, 0, "tpm not cleared");
  389. /* Successful request */
  390. reset_common_data();
  391. vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
  392. TEST_SUCC(vb2_check_tpm_clear(&cc), "clear request");
  393. TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
  394. 0, "request cleared");
  395. TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
  396. 1, "done set");
  397. TEST_EQ(mock_tpm_clear_called, 1, "tpm cleared");
  398. /* Failed request */
  399. reset_common_data();
  400. mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
  401. vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
  402. TEST_EQ(vb2_check_tpm_clear(&cc),
  403. VB2_ERROR_EX_TPM_CLEAR_OWNER, "clear failure");
  404. TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
  405. 0, "request cleared");
  406. TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
  407. 0, "done not set");
  408. }
  409. static void select_slot_tests(void)
  410. {
  411. /* Slot A */
  412. reset_common_data();
  413. TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A");
  414. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  415. VB2_FW_RESULT_UNKNOWN, "result unknown");
  416. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  417. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
  418. TEST_EQ(sd->fw_slot, 0, "selected A");
  419. TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
  420. /* Slot B */
  421. reset_common_data();
  422. vb2_nv_set(&cc, VB2_NV_TRY_NEXT, 1);
  423. TEST_SUCC(vb2_select_fw_slot(&cc), "select slot B");
  424. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  425. VB2_FW_RESULT_UNKNOWN, "result unknown");
  426. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  427. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
  428. TEST_EQ(sd->fw_slot, 1, "selected B");
  429. TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
  430. /* Slot A ran out of tries */
  431. reset_common_data();
  432. vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
  433. TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A out of tries");
  434. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "try B next");
  435. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  436. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
  437. TEST_EQ(sd->fw_slot, 1, "selected B");
  438. TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
  439. /* Slot A ran out of tries, even with nofail active */
  440. reset_common_data();
  441. cc.flags |= VB2_CONTEXT_NOFAIL_BOOT;
  442. vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
  443. TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A out of tries");
  444. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "try B next");
  445. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  446. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
  447. TEST_EQ(sd->fw_slot, 1, "selected B");
  448. TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
  449. /* Slot A used up a try */
  450. reset_common_data();
  451. vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
  452. TEST_SUCC(vb2_select_fw_slot(&cc), "try slot A");
  453. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  454. VB2_FW_RESULT_TRYING, "result trying");
  455. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  456. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
  457. TEST_EQ(sd->fw_slot, 0, "selected A");
  458. TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
  459. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 2, "tries decremented");
  460. /* Slot A failed, but nofail active */
  461. reset_common_data();
  462. cc.flags |= VB2_CONTEXT_NOFAIL_BOOT;
  463. vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
  464. TEST_SUCC(vb2_select_fw_slot(&cc), "try slot A");
  465. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
  466. VB2_FW_RESULT_TRYING, "result trying");
  467. TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
  468. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
  469. TEST_EQ(sd->fw_slot, 0, "selected A");
  470. TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
  471. TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 3, "tries not decremented");
  472. /* Tried/result get copied to the previous fields */
  473. reset_common_data();
  474. vb2_nv_set(&cc, VB2_NV_FW_TRIED, 0);
  475. vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_SUCCESS);
  476. vb2_select_fw_slot(&cc);
  477. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 0, "prev A");
  478. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT), VB2_FW_RESULT_SUCCESS,
  479. "prev success");
  480. reset_common_data();
  481. vb2_nv_set(&cc, VB2_NV_FW_TRIED, 1);
  482. vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
  483. vb2_select_fw_slot(&cc);
  484. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 1, "prev B");
  485. TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT), VB2_FW_RESULT_FAILURE,
  486. "prev failure");
  487. }
  488. int main(int argc, char* argv[])
  489. {
  490. init_context_tests();
  491. misc_tests();
  492. gbb_tests();
  493. fail_tests();
  494. recovery_tests();
  495. dev_switch_tests();
  496. tpm_clear_tests();
  497. select_slot_tests();
  498. return gTestSuccess ? 0 : 255;
  499. }