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