| /* |
| * Copyright (c) 2026 The Fuchsia Authors |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| /* |
| * WARNING: This is a software-based pseudo-random number generator (PRNG) |
| * intended ONLY for development and debugging. It uses U-Boot's native |
| * rand() which is NOT cryptographically secure. |
| * |
| * DO NOT use this implementation in production environments or for security- |
| * sensitive applications (e.g. key generation, cryptography). |
| */ |
| |
| #include <common.h> |
| #include <efi_loader.h> |
| #include <efi_rng.h> |
| |
| static const efi_guid_t rng_raw_guid = EFI_RNG_ALGORITHM_RAW; |
| |
| static efi_status_t EFIAPI rng_getinfo(struct efi_rng_protocol *this, |
| efi_uintn_t *rng_algorithm_list_size, |
| efi_guid_t *rng_algorithm_list) |
| { |
| EFI_ENTRY("%p, %p, %p", this, rng_algorithm_list_size, |
| rng_algorithm_list); |
| |
| if (!this || !rng_algorithm_list_size) |
| return EFI_EXIT(EFI_INVALID_PARAMETER); |
| |
| if (!rng_algorithm_list || |
| *rng_algorithm_list_size < sizeof(*rng_algorithm_list)) { |
| *rng_algorithm_list_size = sizeof(*rng_algorithm_list); |
| return EFI_EXIT(EFI_BUFFER_TOO_SMALL); |
| } |
| |
| *rng_algorithm_list_size = sizeof(*rng_algorithm_list); |
| guidcpy(rng_algorithm_list, &rng_raw_guid); |
| |
| return EFI_EXIT(EFI_SUCCESS); |
| } |
| |
| /* |
| * WARNING: U-Boot's rand() is a simple LCG and is NOT cryptographically |
| * secure. This is strictly for development and debugging. |
| * |
| * DO NOT use this implementation in production environments or for security- |
| * sensitive applications. |
| */ |
| static efi_status_t EFIAPI getrng(struct efi_rng_protocol *this, |
| efi_guid_t *rng_algorithm, |
| efi_uintn_t rng_value_length, |
| uint8_t *rng_value) |
| { |
| EFI_ENTRY("%p, %p, %zu, %p", this, rng_algorithm, rng_value_length, |
| rng_value); |
| |
| if (!this || !rng_value || !rng_value_length) |
| return EFI_EXIT(EFI_INVALID_PARAMETER); |
| |
| if (rng_algorithm) { |
| if (guidcmp(rng_algorithm, &rng_raw_guid)) |
| return EFI_EXIT(EFI_UNSUPPORTED); |
| } |
| |
| for (efi_uintn_t i = 0; i < rng_value_length; i++) { |
| rng_value[i] = rand() & 0xff; |
| } |
| |
| return EFI_EXIT(EFI_SUCCESS); |
| } |
| |
| static const struct efi_rng_protocol efi_rng_protocol = { |
| .get_info = rng_getinfo, |
| .get_rng = getrng, |
| }; |
| |
| const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID; |
| |
| efi_status_t efi_rng_sw_register(void) |
| { |
| efi_status_t ret; |
| |
| printf("\n*****************************************************************\n"); |
| printf("WARNING: Registering a SOFTWARE-BASED (INSECURE) EFI RNG Protocol!\n"); |
| printf("This is ONLY for development and debugging. DO NOT use in production!\n"); |
| printf("*****************************************************************\n\n"); |
| |
| srand(timer_get_us()); |
| |
| ret = efi_add_protocol(efi_root, &efi_guid_rng_protocol, |
| (void *)&efi_rng_protocol); |
| if (ret != EFI_SUCCESS) |
| printf("Cannot install software EFI_RNG_PROTOCOL\n"); |
| |
| return ret; |
| } |