uboot/lib/efi_selftest/efi_selftest_rng.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * efi_selftest_rng
   4 *
   5 * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
   6 *
   7 * Test the random number generator service.
   8 */
   9
  10#include <efi_selftest.h>
  11#include <efi_rng.h>
  12
  13#define RNG_LEN 9
  14
  15static struct efi_boot_services *boottime;
  16static efi_guid_t efi_rng_guid = EFI_RNG_PROTOCOL_GUID;
  17
  18/*
  19 * Setup unit test.
  20 *
  21 * @handle:     handle of the loaded image
  22 * @systable:   system table
  23 * @return:     EFI_ST_SUCCESS for success
  24 */
  25static int setup(const efi_handle_t handle,
  26                 const struct efi_system_table *systable)
  27{
  28        boottime = systable->boottime;
  29        return EFI_ST_SUCCESS;
  30}
  31
  32/*
  33 * Execute unit test.
  34 *
  35 * Retrieve available RNG algorithms.
  36 * Retrieve two random values and compare them.
  37 *
  38 * @return:     EFI_ST_SUCCESS for success
  39 */
  40static int execute(void)
  41{
  42        efi_status_t ret;
  43        efi_uintn_t size;
  44        struct efi_rng_protocol *rng;
  45        efi_guid_t *algo_list;
  46        u8 rnd1[RNG_LEN] __aligned(4), rnd2[RNG_LEN] __aligned(4);
  47        int r;
  48
  49        /* Get random number generator protocol */
  50        ret = boottime->locate_protocol(&efi_rng_guid, NULL, (void **)&rng);
  51        if (ret != EFI_SUCCESS) {
  52                efi_st_error(
  53                        "Random number generator protocol not available\n");
  54                return EFI_ST_FAILURE;
  55        }
  56
  57        ret = rng->get_info(rng, &size, NULL);
  58        if (ret != EFI_BUFFER_TOO_SMALL) {
  59                efi_st_error("Could not retrieve alorithm list size\n");
  60                return EFI_ST_FAILURE;
  61        }
  62        if (size < sizeof(efi_guid_t)) {
  63                efi_st_error("Empty alorithm list\n");
  64                return EFI_ST_FAILURE;
  65        }
  66
  67        ret = boottime->allocate_pool(EFI_LOADER_DATA, size,
  68                                      (void **)&algo_list);
  69        if (ret != EFI_SUCCESS) {
  70                efi_st_error("Could not allocate pool memory\n");
  71                return EFI_ST_FAILURE;
  72        }
  73
  74        ret = rng->get_info(rng, &size, algo_list);
  75        if (ret != EFI_SUCCESS) {
  76                efi_st_error("Could not get info\n");
  77                return EFI_ST_FAILURE;
  78        }
  79        if (size < sizeof(efi_guid_t)) {
  80                efi_st_error("Empty alorithm list\n");
  81                return EFI_ST_FAILURE;
  82        }
  83
  84        memset(rnd1, 0, RNG_LEN);
  85        memset(rnd2, 0, RNG_LEN);
  86
  87        ret = rng->get_rng(rng, NULL, RNG_LEN - 1, &rnd1[1]);
  88        if (ret != EFI_SUCCESS) {
  89                efi_st_error("Could not get random value\n");
  90                return EFI_ST_FAILURE;
  91        }
  92        ret = rng->get_rng(rng, algo_list, RNG_LEN - 1, &rnd2[1]);
  93        if (ret != EFI_SUCCESS) {
  94                efi_st_error("Could not get random value\n");
  95                return EFI_ST_FAILURE;
  96        }
  97        r = memcmp(rnd1, rnd2, RNG_LEN);
  98        if (!r) {
  99                efi_st_error("Two equal consecutive random numbers\n");
 100                return EFI_ST_FAILURE;
 101        }
 102
 103        ret = boottime->free_pool(algo_list);
 104        if (ret != EFI_SUCCESS) {
 105                efi_st_error("Could not free pool memory\n");
 106                return EFI_ST_FAILURE;
 107        }
 108
 109        return EFI_ST_SUCCESS;
 110}
 111
 112EFI_UNIT_TEST(rng) = {
 113        .name = "random number generator",
 114        .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 115        .setup = setup,
 116        .execute = execute,
 117};
 118