efi_selftest_crc32.c 3.3 KB

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