123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /** @file
- This driver produces an EFI_RNG_PROTOCOL instance for the AMD Seattle CCP
- Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- **/
- #include <Library/BaseMemoryLib.h>
- #include <Library/PcdLib.h>
- #include <Library/IoLib.h>
- #include <Protocol/Rng.h>
- #define CCP_TRNG_OFFSET 0xc
- #define CCP_TNRG_RETRIES 5
- STATIC EFI_PHYSICAL_ADDRESS mCcpRngOutputReg;
- STATIC EFI_HANDLE mHandle;
- /**
- Returns information about the random number generation implementation.
- @param[in] This A pointer to the EFI_RNG_PROTOCOL
- instance.
- @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
- RNGAlgorithmList.
- On output with a return code of
- EFI_SUCCESS, the size in bytes of the
- data returned in RNGAlgorithmList. On
- output with a return code of
- EFI_BUFFER_TOO_SMALL, the size of
- RNGAlgorithmList required to obtain the
- list.
- @param[out] RNGAlgorithmList A caller-allocated memory buffer filled
- by the driver with one EFI_RNG_ALGORITHM
- element for each supported RNG algorithm.
- The list must not change across multiple
- calls to the same driver. The first
- algorithm in the list is the default
- algorithm for the driver.
- @retval EFI_SUCCESS The RNG algorithm list was returned
- successfully.
- @retval EFI_UNSUPPORTED The services is not supported by this
- driver.
- @retval EFI_DEVICE_ERROR The list of algorithms could not be
- retrieved due to a hardware or firmware
- error.
- @retval EFI_INVALID_PARAMETER One or more of the parameters are
- incorrect.
- @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small
- to hold the result.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- StyxRngGetInfo (
- IN EFI_RNG_PROTOCOL *This,
- IN OUT UINTN *RNGAlgorithmListSize,
- OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
- )
- {
- if (This == NULL || RNGAlgorithmListSize == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
- *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
- return EFI_BUFFER_TOO_SMALL;
- }
- if (RNGAlgorithmList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
- CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
- return EFI_SUCCESS;
- }
- /**
- Produces and returns an RNG value using either the default or specified RNG
- algorithm.
- @param[in] This A pointer to the EFI_RNG_PROTOCOL
- instance.
- @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that
- identifies the RNG algorithm to use. May
- be NULL in which case the function will
- use its default RNG algorithm.
- @param[in] RNGValueLength The length in bytes of the memory buffer
- pointed to by RNGValue. The driver shall
- return exactly this numbers of bytes.
- @param[out] RNGValue A caller-allocated memory buffer filled
- by the driver with the resulting RNG
- value.
- @retval EFI_SUCCESS The RNG value was returned successfully.
- @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm
- is not supported by this driver.
- @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due
- to a hardware or firmware error.
- @retval EFI_NOT_READY There is not enough random data available
- to satisfy the length requested by
- RNGValueLength.
- @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is
- zero.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- StyxRngGetRNG (
- IN EFI_RNG_PROTOCOL *This,
- IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
- IN UINTN RNGValueLength,
- OUT UINT8 *RNGValue
- )
- {
- UINT32 Val;
- UINT32 Retries;
- UINT32 Loop;
- if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // We only support the raw algorithm, so reject requests for anything else
- //
- if (RNGAlgorithm != NULL &&
- !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
- return EFI_UNSUPPORTED;
- }
- do {
- Retries = CCP_TNRG_RETRIES;
- do {
- Val = MmioRead32 (mCcpRngOutputReg);
- } while (!Val && Retries-- > 0);
- if (!Val) {
- return EFI_DEVICE_ERROR;
- }
- for (Loop = 0; Loop < 4 && RNGValueLength > 0; Loop++, RNGValueLength--) {
- *RNGValue++ = (UINT8)Val;
- Val >>= 8;
- }
- } while (RNGValueLength > 0);
- return EFI_SUCCESS;
- }
- STATIC EFI_RNG_PROTOCOL mStyxRngProtocol = {
- StyxRngGetInfo,
- StyxRngGetRNG
- };
- //
- // Entry point of this driver.
- //
- EFI_STATUS
- EFIAPI
- StyxRngEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- mCcpRngOutputReg = PcdGet64 (PcdCCPBase) + CCP_TRNG_OFFSET;
- return SystemTable->BootServices->InstallMultipleProtocolInterfaces (
- &mHandle,
- &gEfiRngProtocolGuid, &mStyxRngProtocol,
- NULL
- );
- }
|