vb2_nvstorage_tests.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 firmware NV storage library.
  6. */
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "2sysincludes.h"
  12. #include "test_common.h"
  13. #include "vboot_common.h"
  14. #include "2api.h"
  15. #include "2common.h"
  16. #include "2misc.h"
  17. #include "2nvstorage.h"
  18. /* Single NV storage field to test */
  19. struct nv_field {
  20. enum vb2_nv_param param; /* Parameter index */
  21. uint32_t default_value; /* Expected default value */
  22. uint32_t test_value; /* Value to test writing */
  23. uint32_t test_value2; /* Second value to test writing */
  24. char *desc; /* Field description */
  25. };
  26. /* Array of fields to test, terminated with a field with desc==NULL. */
  27. static struct nv_field nvfields[] = {
  28. {VB2_NV_DEBUG_RESET_MODE, 0, 1, 0, "debug reset mode"},
  29. {VB2_NV_TRY_NEXT, 0, 1, 0, "try next"},
  30. {VB2_NV_TRY_COUNT, 0, 6, 15, "try B count"},
  31. {VB2_NV_FW_TRIED, 0, 1, 0, "firmware tried"},
  32. {VB2_NV_FW_RESULT, 0, 1, 2, "firmware result"},
  33. {VB2_NV_FW_PREV_TRIED, 0, 1, 0, "firmware prev tried"},
  34. {VB2_NV_FW_PREV_RESULT, 0, 1, 3, "firmware prev result"},
  35. {VB2_NV_RECOVERY_REQUEST, 0, 0x42, 0xED, "recovery request"},
  36. {VB2_NV_RECOVERY_SUBCODE, 0, 0x56, 0xAC, "recovery subcode"},
  37. {VB2_NV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"},
  38. {VB2_NV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"},
  39. {VB2_NV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"},
  40. {VB2_NV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
  41. {VB2_NV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
  42. {VB2_NV_DEV_BOOT_FASTBOOT_FULL_CAP, 0, 1, 0, "dev boot fb full cap"},
  43. {VB2_NV_DEV_DEFAULT_BOOT, 0, 1, 2, "dev default boot"},
  44. {VB2_NV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
  45. {VB2_NV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
  46. {VB2_NV_CLEAR_TPM_OWNER_DONE, 0, 1, 0, "clear tpm owner done"},
  47. {VB2_NV_TPM_REQUESTED_REBOOT, 0, 1, 0, "tpm requested reboot"},
  48. {VB2_NV_OPROM_NEEDED, 0, 1, 0, "oprom needed"},
  49. {VB2_NV_BACKUP_NVRAM_REQUEST, 0, 1, 0, "backup nvram request"},
  50. {VB2_NV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in fw"},
  51. {VB2_NV_BOOT_ON_AC_DETECT, 0, 1, 0, "boot on ac detect"},
  52. {VB2_NV_TRY_RO_SYNC, 0, 1, 0, "try read only software sync"},
  53. {0, 0, 0, 0, NULL}
  54. };
  55. static void test_changed(struct vb2_context *ctx, int changed, const char *why)
  56. {
  57. if (changed)
  58. TEST_NEQ(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED, 0, why);
  59. else
  60. TEST_EQ(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED, 0, why);
  61. };
  62. static void nv_storage_test(void)
  63. {
  64. struct nv_field *vnf;
  65. uint8_t goodcrc;
  66. uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
  67. __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
  68. struct vb2_context c = {
  69. .flags = 0,
  70. .workbuf = workbuf,
  71. .workbuf_size = sizeof(workbuf),
  72. };
  73. struct vb2_shared_data *sd = vb2_get_sd(&c);
  74. memset(c.nvdata, 0xA6, sizeof(c.nvdata));
  75. vb2_init_context(&c);
  76. /* Init with invalid data should set defaults and regenerate CRC */
  77. vb2_nv_init(&c);
  78. TEST_EQ(c.nvdata[0], 0x70, "vb2_nv_init() reset header byte");
  79. TEST_NEQ(c.nvdata[15], 0, "vb2_nv_init() CRC");
  80. TEST_EQ(sd->status, VB2_SD_STATUS_NV_INIT | VB2_SD_STATUS_NV_REINIT,
  81. "vb2_nv_init() status changed");
  82. test_changed(&c, 1, "vb2_nv_init() reset changed");
  83. goodcrc = c.nvdata[15];
  84. TEST_SUCC(vb2_nv_check_crc(&c), "vb2_nv_check_crc() good");
  85. /* Another init should not cause further changes */
  86. c.flags = 0;
  87. sd->status = 0;
  88. vb2_nv_init(&c);
  89. test_changed(&c, 0, "vb2_nv_init() didn't re-reset");
  90. TEST_EQ(c.nvdata[15], goodcrc, "vb2_nv_init() CRC same");
  91. TEST_EQ(sd->status, VB2_SD_STATUS_NV_INIT, "vb2_nv_init() status same");
  92. /* Perturbing the header should force defaults */
  93. c.nvdata[0] ^= 0x40;
  94. TEST_EQ(vb2_nv_check_crc(&c),
  95. VB2_ERROR_NV_HEADER, "vb2_nv_check_crc() bad header");
  96. vb2_nv_init(&c);
  97. TEST_EQ(c.nvdata[0], 0x70, "vb2_nv_init() reset header byte again");
  98. test_changed(&c, 1, "vb2_nv_init() corrupt changed");
  99. TEST_EQ(c.nvdata[15], goodcrc, "vb2_nv_init() CRC same again");
  100. /* So should perturbing some other byte */
  101. TEST_EQ(c.nvdata[11], 0, "Kernel byte starts at 0");
  102. c.nvdata[11] = 12;
  103. TEST_EQ(vb2_nv_check_crc(&c),
  104. VB2_ERROR_NV_CRC, "vb2_nv_check_crc() bad CRC");
  105. vb2_nv_init(&c);
  106. TEST_EQ(c.nvdata[11], 0, "vb2_nv_init() reset kernel byte");
  107. test_changed(&c, 1, "vb2_nv_init() corrupt elsewhere changed");
  108. TEST_EQ(c.nvdata[15], goodcrc, "vb2_nv_init() CRC same again");
  109. /* Clear the kernel and firmware flags */
  110. vb2_nv_init(&c);
  111. TEST_EQ(vb2_nv_get(&c, VB2_NV_FIRMWARE_SETTINGS_RESET),
  112. 1, "Firmware settings are reset");
  113. vb2_nv_set(&c, VB2_NV_FIRMWARE_SETTINGS_RESET, 0);
  114. TEST_EQ(vb2_nv_get(&c, VB2_NV_FIRMWARE_SETTINGS_RESET),
  115. 0, "Firmware settings are clear");
  116. TEST_EQ(vb2_nv_get(&c, VB2_NV_KERNEL_SETTINGS_RESET),
  117. 1, "Kernel settings are reset");
  118. vb2_nv_set(&c, VB2_NV_KERNEL_SETTINGS_RESET, 0);
  119. TEST_EQ(vb2_nv_get(&c, VB2_NV_KERNEL_SETTINGS_RESET),
  120. 0, "Kernel settings are clear");
  121. TEST_EQ(c.nvdata[0], 0x40, "Header byte now just has the header bit");
  122. /* That should have changed the CRC */
  123. TEST_NEQ(c.nvdata[15], goodcrc,
  124. "vb2_nv_init() CRC changed due to flags clear");
  125. /* Test explicitly setting the reset flags again */
  126. vb2_nv_init(&c);
  127. vb2_nv_set(&c, VB2_NV_FIRMWARE_SETTINGS_RESET, 1);
  128. TEST_EQ(vb2_nv_get(&c, VB2_NV_FIRMWARE_SETTINGS_RESET),
  129. 1, "Firmware settings forced reset");
  130. vb2_nv_set(&c, VB2_NV_FIRMWARE_SETTINGS_RESET, 0);
  131. vb2_nv_set(&c, VB2_NV_KERNEL_SETTINGS_RESET, 1);
  132. TEST_EQ(vb2_nv_get(&c, VB2_NV_KERNEL_SETTINGS_RESET),
  133. 1, "Kernel settings forced reset");
  134. vb2_nv_set(&c, VB2_NV_KERNEL_SETTINGS_RESET, 0);
  135. /* Get/set an invalid field */
  136. vb2_nv_init(&c);
  137. vb2_nv_set(&c, -1, 1);
  138. TEST_EQ(vb2_nv_get(&c, -1), 0, "Get invalid setting");
  139. /* Test other fields */
  140. vb2_nv_init(&c);
  141. for (vnf = nvfields; vnf->desc; vnf++) {
  142. TEST_EQ(vb2_nv_get(&c, vnf->param), vnf->default_value,
  143. vnf->desc);
  144. vb2_nv_set(&c, vnf->param, vnf->test_value);
  145. TEST_EQ(vb2_nv_get(&c, vnf->param), vnf->test_value, vnf->desc);
  146. vb2_nv_set(&c, vnf->param, vnf->test_value2);
  147. TEST_EQ(vb2_nv_get(&c, vnf->param), vnf->test_value2,
  148. vnf->desc);
  149. }
  150. /* None of those changes should have caused a reset to defaults */
  151. vb2_nv_init(&c);
  152. TEST_EQ(vb2_nv_get(&c, VB2_NV_FIRMWARE_SETTINGS_RESET),
  153. 0, "Firmware settings are still clear");
  154. TEST_EQ(vb2_nv_get(&c, VB2_NV_KERNEL_SETTINGS_RESET),
  155. 0, "Kernel settings are still clear");
  156. /* Writing identical settings doesn't cause the CRC to regenerate */
  157. c.flags = 0;
  158. vb2_nv_init(&c);
  159. test_changed(&c, 0, "No regen CRC on open");
  160. for (vnf = nvfields; vnf->desc; vnf++)
  161. vb2_nv_set(&c, vnf->param, vnf->test_value2);
  162. test_changed(&c, 0, "No regen CRC if data not changed");
  163. /* Test out-of-range fields mapping to defaults or failing */
  164. vb2_nv_init(&c);
  165. vb2_nv_set(&c, VB2_NV_TRY_COUNT, 16);
  166. TEST_EQ(vb2_nv_get(&c, VB2_NV_TRY_COUNT),
  167. 15, "Try b count out of range");
  168. vb2_nv_set(&c, VB2_NV_RECOVERY_REQUEST, 0x101);
  169. TEST_EQ(vb2_nv_get(&c, VB2_NV_RECOVERY_REQUEST),
  170. VB2_RECOVERY_LEGACY, "Recovery request out of range");
  171. vb2_nv_set(&c, VB2_NV_LOCALIZATION_INDEX, 0x102);
  172. TEST_EQ(vb2_nv_get(&c, VB2_NV_LOCALIZATION_INDEX),
  173. 0, "Localization index out of range");
  174. vb2_nv_set(&c, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN + 1);
  175. vb2_nv_set(&c, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN + 100);
  176. TEST_EQ(vb2_nv_get(&c, VB2_NV_FW_RESULT),
  177. VB2_FW_RESULT_UNKNOWN, "Firmware result out of range");
  178. vb2_nv_set(&c, VB2_NV_DEV_DEFAULT_BOOT, VB2_DEV_DEFAULT_BOOT_DISK + 100);
  179. TEST_EQ(vb2_nv_get(&c, VB2_NV_DEV_DEFAULT_BOOT),
  180. VB2_DEV_DEFAULT_BOOT_DISK, "default to booting from disk");
  181. }
  182. int main(int argc, char* argv[])
  183. {
  184. nv_storage_test();
  185. return gTestSuccess ? 0 : 255;
  186. }