efi_selftest_crc32.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * efi_selftest_crc32
  4. *
  5. * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6. *
  7. * This unit test checks the CalculateCrc32 bootservice and checks the
  8. * headers of the system table, the boot services tablle, and the runtime
  9. * services table before and after ExitBootServices().
  10. */
  11. #include <efi_selftest.h>
  12. const struct efi_system_table *st;
  13. efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size,
  14. u32 *crc32);
  15. static int check_table(const void *table)
  16. {
  17. efi_status_t ret;
  18. u32 crc32, res;
  19. /* Casting from const to not const */
  20. struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
  21. if (!hdr->signature) {
  22. efi_st_error("Missing header signature\n");
  23. return EFI_ST_FAILURE;
  24. }
  25. if (!hdr->revision) {
  26. efi_st_error("Missing header revision\n");
  27. return EFI_ST_FAILURE;
  28. }
  29. if (hdr->headersize <= sizeof(struct efi_table_hdr)) {
  30. efi_st_error("Incorrect headersize value\n");
  31. return EFI_ST_FAILURE;
  32. }
  33. if (hdr->reserved) {
  34. efi_st_error("Reserved header field is not zero\n");
  35. return EFI_ST_FAILURE;
  36. }
  37. crc32 = hdr->crc32;
  38. /*
  39. * Setting the crc32 of the 'const' table to zero is easier than
  40. * copying
  41. */
  42. hdr->crc32 = 0;
  43. ret = bs_crc32(table, hdr->headersize, &res);
  44. /* Reset table crc32 so it stays constant */
  45. hdr->crc32 = crc32;
  46. if (ret != EFI_ST_SUCCESS) {
  47. efi_st_error("CalculateCrc32 failed\n");
  48. return EFI_ST_FAILURE;
  49. }
  50. if (res != crc32) {
  51. efi_st_error("Incorrect CRC32\n");
  52. // return EFI_ST_FAILURE;
  53. }
  54. return EFI_ST_SUCCESS;
  55. }
  56. /*
  57. * Setup unit test.
  58. *
  59. * Check that CalculateCrc32 is working correctly.
  60. * Check tables before ExitBootServices().
  61. *
  62. * @handle: handle of the loaded image
  63. * @systable: system table
  64. * @return: EFI_ST_SUCCESS for success
  65. */
  66. static int setup(const efi_handle_t handle,
  67. const struct efi_system_table *systable)
  68. {
  69. efi_status_t ret;
  70. u32 res;
  71. st = systable;
  72. bs_crc32 = systable->boottime->calculate_crc32;
  73. /* Check that CalculateCrc32 is working */
  74. ret = bs_crc32("U-Boot", 6, &res);
  75. if (ret != EFI_ST_SUCCESS) {
  76. efi_st_error("CalculateCrc32 failed\n");
  77. return EFI_ST_FAILURE;
  78. }
  79. if (res != 0x134b0db4) {
  80. efi_st_error("Incorrect CRC32\n");
  81. return EFI_ST_FAILURE;
  82. }
  83. /* Check tables before ExitBootServices() */
  84. if (check_table(st) != EFI_ST_SUCCESS) {
  85. efi_st_error("Checking system table\n");
  86. return EFI_ST_FAILURE;
  87. }
  88. if (check_table(st->boottime) != EFI_ST_SUCCESS) {
  89. efi_st_error("Checking boottime table\n");
  90. return EFI_ST_FAILURE;
  91. }
  92. if (check_table(st->runtime) != EFI_ST_SUCCESS) {
  93. efi_st_error("Checking runtime table\n");
  94. return EFI_ST_FAILURE;
  95. }
  96. return EFI_ST_SUCCESS;
  97. }
  98. /*
  99. * Execute unit test
  100. *
  101. * Check tables after ExitBootServices()
  102. *
  103. * @return: EFI_ST_SUCCESS for success
  104. */
  105. static int execute(void)
  106. {
  107. if (check_table(st) != EFI_ST_SUCCESS) {
  108. efi_st_error("Checking system table\n");
  109. return EFI_ST_FAILURE;
  110. }
  111. if (check_table(st->runtime) != EFI_ST_SUCCESS) {
  112. efi_st_error("Checking runtime table\n");
  113. return EFI_ST_FAILURE;
  114. }
  115. /*
  116. * We cannot call SetVirtualAddressMap() and recheck the runtime
  117. * table afterwards because this would invalidate the addresses of the
  118. * unit tests.
  119. */
  120. return EFI_ST_SUCCESS;
  121. }
  122. EFI_UNIT_TEST(crc32) = {
  123. .name = "crc32",
  124. .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
  125. .setup = setup,
  126. .execute = execute,
  127. };