bdb_sprw_test.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /* Copyright 2015 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. * Unit tests
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <openssl/aes.h>
  11. #include "2sha.h"
  12. #include "2hmac.h"
  13. #include "bdb.h"
  14. #include "bdb_api.h"
  15. #include "bdb_struct.h"
  16. #include "host.h"
  17. #include "test_common.h"
  18. #include "vboot_register.h"
  19. #include "secrets.h"
  20. static struct bdb_header *bdb, *bdb0, *bdb1;
  21. static uint32_t vboot_register;
  22. static uint32_t vboot_register_persist;
  23. static char slot_selected;
  24. static uint8_t aprw_digest[BDB_SHA256_DIGEST_SIZE];
  25. static uint8_t reset_count;
  26. /* NVM-RW image in storage (e.g. EEPROM) */
  27. static uint8_t nvmrw1[NVM_RW_MAX_STRUCT_SIZE];
  28. static uint8_t nvmrw2[NVM_RW_MAX_STRUCT_SIZE];
  29. static struct bdb_secrets secrets = {
  30. .nvm_wp = {0x00, },
  31. .nvm_rw = {0x00, },
  32. .bdb = {0x00, },
  33. .boot_verified = {0x00, },
  34. .boot_path = {0x00, },
  35. .buc = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  36. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  37. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  38. 0xff, 0xff},
  39. };
  40. static int vbe_write_nvm_failure = 0;
  41. static struct bdb_header *create_bdb(const char *key_dir,
  42. struct bdb_hash *hash, int num_hashes)
  43. {
  44. struct bdb_header *b;
  45. uint8_t oem_area_0[32] = "Some OEM area.";
  46. uint8_t oem_area_1[64] = "Some other OEM area.";
  47. char filename[1024];
  48. struct bdb_create_params p = {
  49. .bdb_load_address = 0x11223344,
  50. .oem_area_0 = oem_area_0,
  51. .oem_area_0_size = sizeof(oem_area_0),
  52. .oem_area_1 = oem_area_1,
  53. .oem_area_1_size = sizeof(oem_area_1),
  54. .header_sig_description = "The header sig",
  55. .data_sig_description = "The data sig",
  56. .data_description = "Test BDB data",
  57. .data_version = 3,
  58. .hash = hash,
  59. .num_hashes = num_hashes,
  60. };
  61. uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE];
  62. /* Load keys */
  63. snprintf(filename, sizeof(filename), "%s/bdbkey.keyb", key_dir);
  64. p.bdbkey = bdb_create_key(filename, 100, "BDB key");
  65. snprintf(filename, sizeof(filename), "%s/datakey.keyb", key_dir);
  66. p.datakey = bdb_create_key(filename, 200, "datakey");
  67. snprintf(filename, sizeof(filename), "%s/bdbkey.pem", key_dir);
  68. p.private_bdbkey = read_pem(filename);
  69. snprintf(filename, sizeof(filename), "%s/datakey.pem", key_dir);
  70. p.private_datakey = read_pem(filename);
  71. if (!p.bdbkey || !p.datakey || !p.private_bdbkey || !p.private_datakey) {
  72. fprintf(stderr, "Unable to load test keys\n");
  73. exit(2);
  74. }
  75. vb2_digest_buffer((uint8_t *)p.bdbkey, p.bdbkey->struct_size,
  76. VB2_HASH_SHA256,
  77. bdbkey_digest, BDB_SHA256_DIGEST_SIZE);
  78. b = bdb_create(&p);
  79. if (!b) {
  80. fprintf(stderr, "Unable to create test BDB\n");
  81. exit(2);
  82. }
  83. /* Free keys and buffers */
  84. free(p.bdbkey);
  85. free(p.datakey);
  86. RSA_free(p.private_bdbkey);
  87. RSA_free(p.private_datakey);
  88. return b;
  89. }
  90. static void calculate_aprw_digest(const struct bdb_hash *hash, uint8_t *digest)
  91. {
  92. /* Locate AP-RW */
  93. /* Calculate digest as loading AP-RW */
  94. memcpy(digest, aprw_digest, sizeof(aprw_digest));
  95. }
  96. static void verstage_main(void)
  97. {
  98. struct vba_context ctx;
  99. const struct bdb_hash *hash;
  100. uint8_t digest[BDB_SHA256_DIGEST_SIZE];
  101. int rv;
  102. rv = vba_bdb_init(&ctx);
  103. if (rv) {
  104. fprintf(stderr, "Initializing context failed for (%d)\n", rv);
  105. vba_bdb_fail(&ctx);
  106. /* This return is needed for unit test. vba_bdb_fail calls
  107. * vbe_reset, which calls verstage_main. If verstage_main
  108. * successfully returns, we return here as well. */
  109. return;
  110. }
  111. fprintf(stderr, "Initialized context. Trying slot %c\n",
  112. ctx.slot ? 'B' : 'A');
  113. /* 1. Locate BDB */
  114. /* 2. Get bdb_hash structure for AP-RW */
  115. hash = bdb_get_hash_by_type(bdb, BDB_DATA_AP_RW);
  116. fprintf(stderr, "Got hash of AP-RW\n");
  117. /* 3. Load & calculate digest of AP-RW */
  118. calculate_aprw_digest(hash, digest);
  119. fprintf(stderr, "Calculated digest\n");
  120. /* 4. Compare digests */
  121. if (memcmp(hash->digest, digest, BDB_SHA256_DIGEST_SIZE)) {
  122. fprintf(stderr, "Digests do not match\n");
  123. vba_bdb_fail(&ctx);
  124. /* This return is needed for unit test. vba_bdb_fail calls
  125. * vbe_reset, which calls verstage_main. If verstage_main
  126. * successfully returns, we return here as well. */
  127. return;
  128. }
  129. /* 5. Record selected slot. This depends on the firmware */
  130. slot_selected = ctx.slot ? 'B' : 'A';
  131. fprintf(stderr, "Selected AP-RW in slot %c\n", slot_selected);
  132. /* X. This should be done upon AP-RW's request after everything is
  133. * successful. We do it here for the unit test. */
  134. vba_bdb_finalize(&ctx);
  135. }
  136. uint32_t vbe_get_vboot_register(enum vboot_register type)
  137. {
  138. switch (type) {
  139. case VBOOT_REGISTER:
  140. return vboot_register;
  141. case VBOOT_REGISTER_PERSIST:
  142. return vboot_register_persist;
  143. default:
  144. fprintf(stderr, "Invalid vboot register type (%d)\n", type);
  145. exit(2);
  146. }
  147. }
  148. void vbe_set_vboot_register(enum vboot_register type, uint32_t val)
  149. {
  150. switch (type) {
  151. case VBOOT_REGISTER:
  152. vboot_register = val;
  153. break;
  154. case VBOOT_REGISTER_PERSIST:
  155. vboot_register_persist = val;
  156. break;
  157. default:
  158. fprintf(stderr, "Invalid vboot register type (%d)\n", type);
  159. exit(2);
  160. }
  161. }
  162. void vbe_reset(void)
  163. {
  164. uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
  165. fprintf(stderr, "Booting ...\n");
  166. if (++reset_count > 5) {
  167. fprintf(stderr, "Reset counter exceeded maximum value\n");
  168. exit(2);
  169. }
  170. /* Emulate warm reset */
  171. vboot_register = 0;
  172. if (val & VBOOT_REGISTER_RECOVERY_REQUEST) {
  173. fprintf(stderr, "Recovery requested\n");
  174. return;
  175. }
  176. /* Selected by SP-RO */
  177. bdb = (val & VBOOT_REGISTER_TRY_SECONDARY_BDB) ? bdb1 : bdb0;
  178. verstage_main();
  179. }
  180. static void test_verify_aprw(const char *key_dir)
  181. {
  182. struct bdb_hash hash0 = {
  183. .offset = 0x28000,
  184. .size = 0x20000,
  185. .partition = 1,
  186. .type = BDB_DATA_AP_RW,
  187. .load_address = 0x200000,
  188. .digest = {0x11, 0x11, 0x11, 0x11},
  189. };
  190. struct bdb_hash hash1 = {
  191. .offset = 0x28000,
  192. .size = 0x20000,
  193. .partition = 1,
  194. .type = BDB_DATA_AP_RW,
  195. .load_address = 0x200000,
  196. .digest = {0x22, 0x22, 0x22, 0x22},
  197. };
  198. bdb0 = create_bdb(key_dir, &hash0, 1);
  199. bdb1 = create_bdb(key_dir, &hash1, 1);
  200. memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE);
  201. /* (slotA, slotB) = (good, bad) */
  202. reset_count = 0;
  203. vboot_register_persist = 0;
  204. slot_selected = 'X';
  205. memcpy(aprw_digest, hash0.digest, 4);
  206. vbe_reset();
  207. TEST_EQ(reset_count, 1, NULL);
  208. TEST_EQ(slot_selected, 'A', NULL);
  209. TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
  210. NULL);
  211. TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
  212. NULL);
  213. /* (slotA, slotB) = (bad, good) */
  214. reset_count = 0;
  215. vboot_register_persist = 0;
  216. slot_selected = 'X';
  217. memcpy(aprw_digest, hash1.digest, 4);
  218. vbe_reset();
  219. TEST_EQ(reset_count, 3, NULL);
  220. TEST_EQ(slot_selected, 'B', NULL);
  221. TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
  222. NULL);
  223. TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
  224. NULL);
  225. /* (slotA, slotB) = (bad, bad) */
  226. reset_count = 0;
  227. vboot_register_persist = 0;
  228. slot_selected = 'X';
  229. memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE);
  230. vbe_reset();
  231. TEST_EQ(reset_count, 5, NULL);
  232. TEST_EQ(slot_selected, 'X', NULL);
  233. TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY,
  234. NULL);
  235. TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY,
  236. NULL);
  237. TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_RECOVERY_REQUEST,
  238. NULL);
  239. /* Clean up */
  240. free(bdb0);
  241. free(bdb1);
  242. }
  243. int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size)
  244. {
  245. /* Read NVM-RW contents (from EEPROM for example) */
  246. switch (type) {
  247. case NVM_TYPE_RW_PRIMARY:
  248. if (sizeof(nvmrw1) < size)
  249. return -1;
  250. memcpy(buf, nvmrw1, size);
  251. break;
  252. case NVM_TYPE_RW_SECONDARY:
  253. if (sizeof(nvmrw2) < size)
  254. return -1;
  255. memcpy(buf, nvmrw2, size);
  256. break;
  257. default:
  258. return -1;
  259. }
  260. return 0;
  261. }
  262. int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size)
  263. {
  264. if (vbe_write_nvm_failure > 0) {
  265. fprintf(stderr, "Failed to write NVM (type=%d failure=%d)\n",
  266. type, vbe_write_nvm_failure);
  267. vbe_write_nvm_failure--;
  268. return -1;
  269. }
  270. /* Write NVM-RW contents (to EEPROM for example) */
  271. switch (type) {
  272. case NVM_TYPE_RW_PRIMARY:
  273. memcpy(nvmrw1, buf, size);
  274. break;
  275. case NVM_TYPE_RW_SECONDARY:
  276. memcpy(nvmrw2, buf, size);
  277. break;
  278. default:
  279. return -1;
  280. }
  281. return 0;
  282. }
  283. static void install_nvm(enum nvm_type type,
  284. uint32_t min_kernel_data_key_version,
  285. uint32_t min_kernel_version,
  286. uint32_t update_count)
  287. {
  288. struct nvmrw nvm = {
  289. .struct_magic = NVM_RW_MAGIC,
  290. .struct_major_version = NVM_HEADER_VERSION_MAJOR,
  291. .struct_minor_version = NVM_HEADER_VERSION_MINOR,
  292. .struct_size = sizeof(struct nvmrw),
  293. .min_kernel_data_key_version = min_kernel_data_key_version,
  294. .min_kernel_version = min_kernel_version,
  295. .update_count = update_count,
  296. };
  297. /* Compute HMAC */
  298. hmac(VB2_HASH_SHA256, secrets.nvm_rw, BDB_SECRET_SIZE,
  299. &nvm, nvm.struct_size - sizeof(nvm.hmac),
  300. nvm.hmac, sizeof(nvm.hmac));
  301. /* Install NVM-RWs (in EEPROM for example) */
  302. switch (type) {
  303. case NVM_TYPE_RW_PRIMARY:
  304. memset(nvmrw1, 0, sizeof(nvmrw1));
  305. memcpy(nvmrw1, &nvm, sizeof(nvm));
  306. break;
  307. case NVM_TYPE_RW_SECONDARY:
  308. memset(nvmrw2, 0, sizeof(nvmrw2));
  309. memcpy(nvmrw2, &nvm, sizeof(nvm));
  310. break;
  311. default:
  312. fprintf(stderr, "Unsupported NVM type (%d)\n", type);
  313. exit(2);
  314. return;
  315. }
  316. }
  317. static void test_nvm_read(void)
  318. {
  319. struct vba_context ctx = {
  320. .bdb = NULL,
  321. .secrets = &secrets,
  322. };
  323. struct nvmrw *nvm;
  324. uint8_t nvmrw1_copy[NVM_RW_MAX_STRUCT_SIZE];
  325. uint8_t nvmrw2_copy[NVM_RW_MAX_STRUCT_SIZE];
  326. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  327. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
  328. memcpy(nvmrw1_copy, nvmrw1, sizeof(nvmrw1));
  329. memcpy(nvmrw2_copy, nvmrw2, sizeof(nvmrw2));
  330. /* Test nvm_read: both good -> pick primary, no sync */
  331. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  332. TEST_SUCC(nvmrw_read(&ctx), NULL);
  333. TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL);
  334. TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL);
  335. TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);
  336. /* Test nvm_read: primary bad -> pick secondary */
  337. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  338. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
  339. memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm));
  340. nvm = (struct nvmrw *)nvmrw1;
  341. nvm->hmac[0] ^= 0xff;
  342. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  343. TEST_SUCC(nvmrw_read(&ctx), NULL);
  344. TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL);
  345. TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw2)), NULL);
  346. TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);
  347. /* Test nvm_read: secondary bad -> pick primary */
  348. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  349. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
  350. memcpy(nvmrw1_copy, nvmrw1, sizeof(*nvm));
  351. nvm = (struct nvmrw *)nvmrw2;
  352. nvm->hmac[0] ^= 0xff;
  353. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  354. TEST_SUCC(nvmrw_read(&ctx), NULL);
  355. TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL);
  356. TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL);
  357. TEST_SUCC(memcmp(nvmrw2, nvmrw1_copy, sizeof(nvmrw1)), NULL);
  358. /* Test nvm_read: both bad */
  359. nvm = (struct nvmrw *)nvmrw1;
  360. nvm->hmac[0] ^= 0xff;
  361. nvm = (struct nvmrw *)nvmrw2;
  362. nvm->hmac[0] ^= 0xff;
  363. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  364. TEST_EQ(nvmrw_read(&ctx), BDB_ERROR_NVM_RW_INVALID_HMAC, NULL);
  365. /* Test update count: secondary new -> pick secondary */
  366. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  367. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1);
  368. memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm));
  369. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  370. TEST_SUCC(nvmrw_read(&ctx), NULL);
  371. TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL);
  372. TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw1)), NULL);
  373. TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL);
  374. /* Test old reader -> minor version downgrade */
  375. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  376. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1);
  377. memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw));
  378. nvm = (struct nvmrw *)nvmrw1;
  379. nvm->struct_minor_version++;
  380. nvm->struct_size++;
  381. TEST_SUCC(nvmrw_read(&ctx), NULL);
  382. TEST_EQ(ctx.nvmrw.struct_minor_version, NVM_HEADER_VERSION_MINOR, NULL);
  383. TEST_EQ(ctx.nvmrw.struct_size, sizeof(*nvm), NULL);
  384. }
  385. static void verify_nvm_write(struct vba_context *ctx,
  386. int expected_result)
  387. {
  388. struct nvmrw *nvmrw;
  389. struct nvmrw *nvm = &ctx->nvmrw;
  390. TEST_EQ(nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY), expected_result, NULL);
  391. if (expected_result != BDB_SUCCESS)
  392. return;
  393. nvmrw = (struct nvmrw *)nvmrw1;
  394. TEST_EQ(nvmrw->min_kernel_data_key_version,
  395. nvm->min_kernel_data_key_version, NULL);
  396. TEST_EQ(nvmrw->min_kernel_version, nvm->min_kernel_version, NULL);
  397. TEST_EQ(nvmrw->update_count, nvm->update_count, NULL);
  398. }
  399. static void test_nvm_write(void)
  400. {
  401. struct vba_context ctx = {
  402. .bdb = NULL,
  403. .secrets = &secrets,
  404. };
  405. struct nvmrw nvm = {
  406. .struct_magic = NVM_RW_MAGIC,
  407. .struct_major_version = NVM_HEADER_VERSION_MAJOR,
  408. .struct_minor_version = NVM_HEADER_VERSION_MINOR,
  409. .struct_size = sizeof(struct nvmrw),
  410. .min_kernel_data_key_version = 1,
  411. .min_kernel_version = 2,
  412. .update_count = 3,
  413. };
  414. /* Test normal case */
  415. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  416. vbe_write_nvm_failure = 0;
  417. verify_nvm_write(&ctx, BDB_SUCCESS);
  418. /* Test write failure: once */
  419. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  420. vbe_write_nvm_failure = 1;
  421. verify_nvm_write(&ctx, BDB_SUCCESS);
  422. /* Test write failure: twice */
  423. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  424. vbe_write_nvm_failure = 2;
  425. verify_nvm_write(&ctx, BDB_ERROR_NVM_WRITE);
  426. /* Test invalid struct magic */
  427. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  428. ctx.nvmrw.struct_magic ^= 0xff;
  429. verify_nvm_write(&ctx, BDB_ERROR_NVM_RW_MAGIC);
  430. /* Test struct size too small */
  431. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  432. ctx.nvmrw.struct_size = NVM_RW_MIN_STRUCT_SIZE - 1;
  433. verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE);
  434. /* Test struct size too large */
  435. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  436. ctx.nvmrw.struct_size = NVM_RW_MAX_STRUCT_SIZE + 1;
  437. verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE);
  438. /* Test invalid struct version */
  439. memcpy(&ctx.nvmrw, &nvm, sizeof(nvm));
  440. ctx.nvmrw.struct_major_version = NVM_HEADER_VERSION_MAJOR - 1;
  441. verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_VERSION);
  442. vbe_write_nvm_failure = 0;
  443. }
  444. static void verify_kernel_version(uint32_t min_kernel_data_key_version,
  445. uint32_t new_kernel_data_key_version,
  446. uint32_t min_kernel_version,
  447. uint32_t new_kernel_version,
  448. int expected_result)
  449. {
  450. struct vba_context ctx = {
  451. .bdb = NULL,
  452. .secrets = &secrets,
  453. };
  454. struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
  455. uint32_t expected_kernel_data_key_version = min_kernel_data_key_version;
  456. uint32_t expected_kernel_version = min_kernel_version;
  457. int should_update = 0;
  458. if (min_kernel_data_key_version < new_kernel_data_key_version) {
  459. expected_kernel_data_key_version = new_kernel_data_key_version;
  460. should_update = 1;
  461. }
  462. if (min_kernel_version < new_kernel_version) {
  463. expected_kernel_version = new_kernel_version;
  464. should_update = 1;
  465. }
  466. install_nvm(NVM_TYPE_RW_PRIMARY, min_kernel_data_key_version,
  467. min_kernel_version, 0);
  468. install_nvm(NVM_TYPE_RW_SECONDARY, 0, 0, 0);
  469. TEST_EQ(vba_update_kernel_version(&ctx, new_kernel_data_key_version,
  470. new_kernel_version),
  471. expected_result, NULL);
  472. if (expected_result != BDB_SUCCESS)
  473. return;
  474. /* Check data key version */
  475. TEST_EQ(nvm->min_kernel_data_key_version,
  476. expected_kernel_data_key_version, NULL);
  477. /* Check kernel version */
  478. TEST_EQ(nvm->min_kernel_version, expected_kernel_version, NULL);
  479. /* Check update_count */
  480. TEST_EQ(nvm->update_count, 0 + should_update, NULL);
  481. /* Check sync if update is expected */
  482. if (should_update)
  483. TEST_SUCC(memcmp(nvmrw2, nvmrw1, sizeof(nvmrw1)), NULL);
  484. }
  485. static void test_update_kernel_version(void)
  486. {
  487. /* Test update: data key version */
  488. verify_kernel_version(0, 1, 0, 0, BDB_SUCCESS);
  489. /* Test update: kernel version */
  490. verify_kernel_version(0, 0, 0, 1, BDB_SUCCESS);
  491. /* Test no update: data key version */
  492. verify_kernel_version(1, 0, 0, 0, BDB_SUCCESS);
  493. /* Test no update: kernel version */
  494. verify_kernel_version(0, 0, 1, 0, BDB_SUCCESS);
  495. }
  496. int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
  497. uint8_t *out)
  498. {
  499. int i;
  500. for (i = 0; i < len; i++)
  501. out[i] = msg[i] ^ key[i % 256/8];
  502. return BDB_SUCCESS;
  503. }
  504. int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key,
  505. uint8_t *out)
  506. {
  507. int i;
  508. for (i = 0; i < len; i++)
  509. out[i] = msg[i] ^ key[i % 256/8];
  510. return BDB_SUCCESS;
  511. }
  512. static void test_update_buc(void)
  513. {
  514. uint8_t new_buc[BUC_ENC_DIGEST_SIZE];
  515. uint8_t enc_buc[BUC_ENC_DIGEST_SIZE];
  516. struct nvmrw *nvm = (struct nvmrw *)nvmrw1;
  517. struct vba_context ctx = {
  518. .bdb = NULL,
  519. .secrets = &secrets,
  520. };
  521. install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0);
  522. install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0);
  523. TEST_SUCC(vba_update_buc(&ctx, new_buc), NULL);
  524. vbe_aes256_encrypt(new_buc, sizeof(new_buc), ctx.secrets->buc,
  525. enc_buc);
  526. TEST_SUCC(memcmp(nvm->buc_enc_digest, enc_buc, sizeof(new_buc)), NULL);
  527. }
  528. static void test_derive_secrets(void)
  529. {
  530. uint8_t test_key[sizeof(struct bdb_key) + BDB_RSA4096_KEY_DATA_SIZE];
  531. struct bdb_key *key = (struct bdb_key *)test_key;
  532. struct vba_context ctx = {
  533. .bdb = NULL,
  534. .secrets = &secrets,
  535. };
  536. const struct bdb_secrets expected = {
  537. .bdb = {
  538. 0x75, 0xb6, 0x24, 0xaa, 0x72, 0x50, 0xf9, 0x33,
  539. 0x59, 0x45, 0x8d, 0xbf, 0xfa, 0x42, 0xc4, 0xb7,
  540. 0x1b, 0xff, 0xc6, 0x02, 0x02, 0x35, 0xc5, 0x1a,
  541. 0x6c, 0xdc, 0x3a, 0x63, 0xfb, 0x8b, 0xac, 0x53},
  542. .boot_verified = {
  543. 0x40, 0xf3, 0x9b, 0xdc, 0xf6, 0xb4, 0xe8, 0xdf,
  544. 0x48, 0xc4, 0xfe, 0x02, 0xdd, 0x34, 0x06, 0xd9,
  545. 0xed, 0xd9, 0x55, 0x79, 0xf4, 0x48, 0x58, 0xbf,
  546. 0x32, 0x55, 0xba, 0x21, 0xca, 0xcc, 0x8c, 0xd1},
  547. .boot_path = {
  548. 0xfb, 0x58, 0x89, 0x58, 0x2f, 0x54, 0xa2, 0xf7,
  549. 0x96, 0x5b, 0x69, 0x77, 0x9b, 0x67, 0x80, 0x39,
  550. 0x7a, 0xd4, 0xc5, 0x3b, 0xcf, 0x95, 0x3f, 0xec,
  551. 0x28, 0x49, 0x55, 0x49, 0x38, 0x27, 0x5d, 0x3c},
  552. .buc = {
  553. 0x63, 0xa5, 0x30, 0xd7, 0xca, 0xe1, 0x3e, 0x2e,
  554. 0x72, 0x7e, 0x29, 0xc9, 0x37, 0x66, 0x6a, 0x63,
  555. 0x91, 0xd4, 0x8e, 0x8b, 0xbc, 0x1a, 0x7a, 0xcf,
  556. 0xc3, 0x19, 0xa0, 0x87, 0xfc, 0x4d, 0xe1, 0xe8},
  557. };
  558. memset(test_key, 0, sizeof(test_key));
  559. key->struct_magic = BDB_KEY_MAGIC;
  560. key->struct_major_version = BDB_KEY_VERSION_MAJOR;
  561. key->struct_minor_version = BDB_KEY_VERSION_MINOR;
  562. key->struct_size = sizeof(test_key);
  563. key->hash_alg = BDB_HASH_ALG_SHA256;
  564. key->sig_alg = BDB_SIG_ALG_RSA4096;
  565. key->key_version = 1;
  566. TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BDB, NULL,
  567. test_key, sizeof(test_key)), NULL);
  568. TEST_SUCC(memcmp(ctx.secrets->bdb, expected.bdb, BDB_SECRET_SIZE),
  569. NULL);
  570. TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, NULL,
  571. NULL, 0), NULL);
  572. TEST_SUCC(memcmp(ctx.secrets->boot_verified, expected.boot_verified,
  573. BDB_SECRET_SIZE), NULL);
  574. TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_PATH, NULL,
  575. test_key, sizeof(test_key)), NULL);
  576. TEST_SUCC(memcmp(ctx.secrets->boot_path, expected.boot_path,
  577. BDB_SECRET_SIZE), NULL);
  578. TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BUC, NULL, NULL, 0),
  579. NULL);
  580. TEST_SUCC(memcmp(ctx.secrets->buc, expected.buc,
  581. BDB_SECRET_SIZE), NULL);
  582. }
  583. int main(int argc, char *argv[])
  584. {
  585. if (argc != 2) {
  586. fprintf(stderr, "Usage: %s <keys_dir>", argv[0]);
  587. return -1;
  588. }
  589. printf("Running BDB SP-RW tests...\n");
  590. test_verify_aprw(argv[1]);
  591. test_nvm_read();
  592. test_nvm_write();
  593. test_update_kernel_version();
  594. test_update_buc();
  595. test_derive_secrets();
  596. return gTestSuccess ? 0 : 255;
  597. }