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