From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4001:c06::234; helo=mail-io0-x234.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-io0-x234.google.com (mail-io0-x234.google.com [IPv6:2607:f8b0:4001:c06::234]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3D62D21F7D4E6 for ; Wed, 11 Oct 2017 11:11:34 -0700 (PDT) Received: by mail-io0-x234.google.com with SMTP id 97so2733673iok.7 for ; Wed, 11 Oct 2017 11:15:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=HLvSkWkUlhhAfYZyl+vXhC8fXXVZsK//w1n7o6X+rPA=; b=h3JCFY7yOGJdAZ57uRK1guEpIAe7hppJs0yOPVNwunJazxykt6Kig4nL7qzk/9McqI wjdJBHHqNSdCrGMqNGNR6wM+BIe6vBNdtZNqXeJqj5uhEGNTXapi/6ZWJQSLpUgYO/zf ZwRdk8HhZyinHbF6qGrr16y1VIOKwspD6jrI4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=HLvSkWkUlhhAfYZyl+vXhC8fXXVZsK//w1n7o6X+rPA=; b=Bii19vVslKa2tanbd560VAzBop4pK0NLCv9WfLrUoIYK2/Hoha2tSnTMEJuoB7beC7 etF8XOJIk7jOFtTeNkGGBShR+PNUMOrWpzlLJ8gAEna4CthqEOAIn8+cAV00mnvYBN/A rpPVDKiBuTusdqqiqy9jGKrhgd3GAQ8hsk3vLx8KovzbHfpil+Efqszr3e12H6Z01Kt8 nmoNsC/MwpiJeBEe2MxQmaUVoWbrOxcX692DKSjRsrINbzlVuUfNOf8WKuy2bBKCtwTE H11y4h2PF50SXPCUtUkDwJCA4c7Hi5ha0fZQKIoIFucNGIrOwTg194xS9u+9bv1PY4W/ //pg== X-Gm-Message-State: AMCzsaXPYBo4GGB2ajKumWxv/LrIebx7f1eJP1HBm8QjHJIDC6UMo1mx XoeosQ3Sl4+uvMnz24zMthLVuhxCPQygfBZI5TDwPQ== X-Google-Smtp-Source: AOwi7QADDv+7vONsgqB4l0n6vFJ1wcpz9gQjgjwO1LXX6sRcKEQPbKVRKmbjSm1RaUmor41bKRMNWKfiPEU2yDaSH3E= X-Received: by 10.107.15.170 with SMTP id 42mr167872iop.141.1507745702803; Wed, 11 Oct 2017 11:15:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.131.167 with HTTP; Wed, 11 Oct 2017 11:15:01 -0700 (PDT) In-Reply-To: <20171011164713.qgkiekieolvjiyk5@bivouac.eciton.net> References: <1507736449-6073-1-git-send-email-mw@semihalf.com> <1507736449-6073-2-git-send-email-mw@semihalf.com> <20171011164713.qgkiekieolvjiyk5@bivouac.eciton.net> From: Ard Biesheuvel Date: Wed, 11 Oct 2017 19:15:01 +0100 Message-ID: To: Leif Lindholm Cc: Marcin Wojtas , "edk2-devel@lists.01.org" , Nadav Haklai , Neta Zur Hershkovits , Kostya Porotchkin , Hua Jing , =?UTF-8?B?SmFuIETEhWJyb8Wb?= Subject: Re: [platforms: PATCH 1/8] Marvell/Armada: Implement EFI_RNG_PROTOCOL driver for EIP76 TRNG X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Oct 2017 18:11:34 -0000 Content-Type: text/plain; charset="UTF-8" On 11 October 2017 at 17:47, Leif Lindholm wrote: > On Wed, Oct 11, 2017 at 05:40:42PM +0200, Marcin Wojtas wrote: >> From: Ard Biesheuvel >> >> Add an implementation of EFI_RNG_PROTOCOL so that the OS loader has >> access to entropy for KASLR and other purposes (i.e., seeding the OS's >> entropy pool very early on). >> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Ard Biesheuvel >> Signed-off-by: Marcin Wojtas >> --- >> Platform/Marvell/Armada/Armada.dsc.inc | 4 + >> Platform/Marvell/Armada/Armada70x0.fdf | 1 + >> Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c | 254 ++++++++++++++++++++ >> Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf | 47 ++++ >> Platform/Marvell/Marvell.dec | 3 + >> 5 files changed, 309 insertions(+) >> >> diff --git a/Platform/Marvell/Armada/Armada.dsc.inc b/Platform/Marvell/Armada/Armada.dsc.inc >> index 1aa485c..ec24d76 100644 >> --- a/Platform/Marvell/Armada/Armada.dsc.inc >> +++ b/Platform/Marvell/Armada/Armada.dsc.inc >> @@ -364,6 +364,9 @@ >> gArmTokenSpaceGuid.PcdSystemMemorySize|0x40000000 >> gArmTokenSpaceGuid.PcdArmScr|0x531 >> >> + # TRNG >> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress|0xF2760000 >> + >> ################################################################################ >> # >> # Components Section - list of all EDK II Modules needed by this Platform >> @@ -400,6 +403,7 @@ >> Platform/Marvell/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf >> Platform/Marvell/Drivers/Spi/MvSpiDxe.inf >> Platform/Marvell/Drivers/Spi/Devices/MvSpiFlash.inf >> + Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf >> >> # Network support >> MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf >> diff --git a/Platform/Marvell/Armada/Armada70x0.fdf b/Platform/Marvell/Armada/Armada70x0.fdf >> index 933c3ed..a94a9ff 100644 >> --- a/Platform/Marvell/Armada/Armada70x0.fdf >> +++ b/Platform/Marvell/Armada/Armada70x0.fdf >> @@ -113,6 +113,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c >> INF Platform/Marvell/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf >> INF Platform/Marvell/Drivers/Spi/MvSpiDxe.inf >> INF Platform/Marvell/Drivers/Spi/Devices/MvSpiFlash.inf >> + INF Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf >> >> # Network support >> INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf >> diff --git a/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c >> new file mode 100644 >> index 0000000..dca6dcc >> --- /dev/null >> +++ b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c >> @@ -0,0 +1,254 @@ >> +/** @file >> + >> + This driver produces an EFI_RNG_PROTOCOL instance for the Armada 70x0 TRNG >> + >> + Copyright (C) 2017, Linaro Ltd. All rights reserved.
>> + >> + 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 >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#define TRNG_OUTPUT_REG mTrngBaseAddress >> +#define TRNG_OUTPUT_SIZE 0x10 >> + >> +#define TRNG_STATUS_REG (mTrngBaseAddress + 0x10) >> +#define TRNG_STATUS_READY BIT0 >> + >> +#define TRNG_INTACK_REG (mTrngBaseAddress + 0x10) >> +#define TRNG_INTACK_READY BIT0 >> + >> +#define TRNG_CONTROL_REG (mTrngBaseAddress + 0x14) >> +#define TRNG_CONTROL_REG_ENABLE BIT10 >> + >> +#define TRNG_CONFIG_REG (mTrngBaseAddress + 0x18) >> +#define __MIN_REFILL_SHIFT 0 >> +#define __MAX_REFILL_SHIFT 16 >> +#define TRNG_CONFIG_MIN_REFILL_CYCLES (0x05 << __MIN_REFILL_SHIFT) >> +#define TRNG_CONFIG_MAX_REFILL_CYCLES (0x22 << __MAX_REFILL_SHIFT) >> + >> +#define TRNG_FRODETUNE_REG (mTrngBaseAddress + 0x24) >> +#define TRNG_FRODETUNE_MASK 0x0 >> + >> +#define TRNG_FROENABLE_REG (mTrngBaseAddress + 0x20) >> +#define TRNG_FROENABLE_MASK 0xffffff >> + >> +#define TRNG_MAX_RETRIES 20 >> + >> +STATIC EFI_PHYSICAL_ADDRESS mTrngBaseAddress; >> + >> +/** >> + 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 >> +Armada70x0RngGetInfo ( >> + 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; >> +} >> + >> +STATIC >> +EFI_STATUS >> +GetTrngData ( >> + IN UINTN Length, >> + OUT UINT8 *Bits >> + ) >> +{ >> + UINTN Tries; >> + UINT32 Buf[TRNG_OUTPUT_SIZE / sizeof (UINT32)]; >> + UINTN Index; >> + >> + for (Tries = 0; Tries < TRNG_MAX_RETRIES; Tries++) { >> + if (MmioRead32 (TRNG_STATUS_REG) & TRNG_STATUS_READY) { >> + for (Index = 0; Index < ARRAY_SIZE (Buf); Index++) { >> + Buf[Index] = MmioRead32 (TRNG_OUTPUT_REG + Index * sizeof (UINT32)); >> + } >> + CopyMem (Bits, Buf, Length); >> + MmioWrite32 (TRNG_INTACK_REG, TRNG_INTACK_READY); >> + >> + return EFI_SUCCESS; >> + } >> + gBS->Stall (10); > > Why? Why 10? Please add a comment. > > No other comments on this patch. > I don't remember the details, and I think the 1 ms delay was chosen arbitrarily, but the purpose of the delay is to allow the hardware to assume the 'ready' state. >> + } >> + return EFI_DEVICE_ERROR; >> +} >> + >> +/** >> + 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 >> +Armada70x0RngGetRNG ( >> + IN EFI_RNG_PROTOCOL *This, >> + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL >> + IN UINTN RNGValueLength, >> + OUT UINT8 *RNGValue >> + ) >> +{ >> + UINTN Length; >> + EFI_STATUS Status; >> + >> + 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 { >> + Length = MIN (RNGValueLength, TRNG_OUTPUT_SIZE); >> + Status = GetTrngData (Length, RNGValue); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + RNGValue += Length; >> + RNGValueLength -= Length; >> + } while (RNGValueLength > 0); >> + >> + return EFI_SUCCESS; >> +} >> + >> +STATIC EFI_RNG_PROTOCOL mArmada70x0RngProtocol = { >> + Armada70x0RngGetInfo, >> + Armada70x0RngGetRNG >> +}; >> + >> +// >> +// Entry point of this driver. >> +// >> +EFI_STATUS >> +EFIAPI >> +Armada70x0RngDxeEntryPoint ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + mTrngBaseAddress = PcdGet64 (PcdEip76TrngBaseAddress); >> + >> + // >> + // Disable the TRNG before updating its configuration >> + // >> + MmioAnd32 (TRNG_CONTROL_REG, ~TRNG_CONTROL_REG_ENABLE); >> + >> + // >> + // Configure the internal conditioning parameters of the TRNG >> + // >> + MmioWrite32 (TRNG_CONFIG_REG, TRNG_CONFIG_MIN_REFILL_CYCLES | >> + TRNG_CONFIG_MAX_REFILL_CYCLES); >> + >> + // >> + // Configure the FROs >> + // >> + MmioWrite32 (TRNG_FRODETUNE_REG, TRNG_FRODETUNE_MASK); >> + MmioWrite32 (TRNG_FROENABLE_REG, TRNG_FROENABLE_MASK); >> + >> + // >> + // Enable the TRNG >> + // >> + MmioOr32 (TRNG_CONTROL_REG, TRNG_CONTROL_REG_ENABLE); >> + >> + return SystemTable->BootServices->InstallMultipleProtocolInterfaces ( >> + &ImageHandle, >> + &gEfiRngProtocolGuid, >> + &mArmada70x0RngProtocol, >> + NULL >> + ); >> +} >> diff --git a/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf >> new file mode 100644 >> index 0000000..189ffc5 >> --- /dev/null >> +++ b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf >> @@ -0,0 +1,47 @@ >> +## @file >> +# This driver produces an EFI_RNG_PROTOCOL instance for the Armada 70x0 TRNG >> +# >> +# Copyright (C) 2017, Linaro Ltd. All rights reserved.
>> +# >> +# 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. >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x00010019 >> + BASE_NAME = Armada70x0RngDxe >> + FILE_GUID = dd87096a-cae5-4328-bec1-2ddb755f2e08 >> + MODULE_TYPE = DXE_DRIVER >> + VERSION_STRING = 1.0 >> + ENTRY_POINT = Armada70x0RngDxeEntryPoint >> + >> +[Sources] >> + Armada70x0RngDxe.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + Platform/Marvell/Marvell.dec >> + >> +[LibraryClasses] >> + BaseMemoryLib >> + IoLib >> + PcdLib >> + UefiDriverEntryPoint >> + >> +[Pcd] >> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress >> + >> +[Protocols] >> + gEfiRngProtocolGuid ## PRODUCES >> + >> +[Guids] >> + gEfiRngAlgorithmRaw >> + >> +[Depex] >> + TRUE >> diff --git a/Platform/Marvell/Marvell.dec b/Platform/Marvell/Marvell.dec >> index e7d7c2c..78f5e53 100644 >> --- a/Platform/Marvell/Marvell.dec >> +++ b/Platform/Marvell/Marvell.dec >> @@ -195,6 +195,9 @@ >> #RTC >> gMarvellTokenSpaceGuid.PcdRtcEnabled|{ 0x0 }|VOID*|0x40000052 >> >> +#TRNG >> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress|0x0|UINT64|0x50000053 >> + >> [Protocols] >> gMarvellEepromProtocolGuid = { 0x71954bda, 0x60d3, 0x4ef8, { 0x8e, 0x3c, 0x0e, 0x33, 0x9f, 0x3b, 0xc2, 0x2b }} >> gMarvellMdioProtocolGuid = { 0x40010b03, 0x5f08, 0x496a, { 0xa2, 0x64, 0x10, 0x5e, 0x72, 0xd3, 0x71, 0xaa }} >> -- >> 2.7.4 >>