From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::243; helo=mail-wm0-x243.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) (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 5D3D421CEB15C for ; Wed, 25 Oct 2017 03:40:35 -0700 (PDT) Received: by mail-wm0-x243.google.com with SMTP id r196so1026129wmf.2 for ; Wed, 25 Oct 2017 03:44:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=AWuJ7eVkMOG/SmeDXfqaSBUEDQBm1F7r6Gj3Zjj5RNM=; b=ODKXGzmUWkDaFW/8fD+Oy/M+bz+bsMNvaXaCmXDJRv6Yc4tpJy1pb1bHueZP8L3rhQ m4m56YDBH6/1+IseIw9TVLZrm6dtWlSoRwTNOBNXYE+33vkvOKHLKE90bjiQklSuyRjW v1E384vi3gcOnFeaOHaUidru+E4XD/1SHw/gI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=AWuJ7eVkMOG/SmeDXfqaSBUEDQBm1F7r6Gj3Zjj5RNM=; b=kPe38tPjRC6pMQIBeyqk6fDJsLVpNpzQJ3L3cIclx1dH3w2oJS76NBoa7fdss818Pm OBh5cc7hwHtBk2mrHfhj6HzOPdD+C/erEqg/LP/znbb0WBlWKWzSIALIhw7YhF7jIz+b 8oh+J7n5nJy9e2q84ig3cHppA9/CJySODITsjow/csWfMn7JpyQ8h77btE1C1uvN00eq KBjex/CQdyyllR6jkHixeInWwbMGKHX4g2gnc+Xqp+7RXwrCaiKIHk+LqEasN1zGJETr H3HJKwiZfoYo9WoCpXQ+KXokTrsThyLgcNac+1aRHy1VrdYRDTGCGGWkStyQ6Cfk8htF h0UQ== X-Gm-Message-State: AMCzsaW8nqIbtUqm4evQ+qt5q1k6LL1is3GMwTMk2GAUusl++KvhLC2F DzJ/CN+PffN7aSKdzY6ZR8oJEw== X-Google-Smtp-Source: ABhQp+T1fSL194RvYWGgX+xwQQcYuAsy1XGKl6TVi0gjM3efpMGvsaJfIW7xuvoAAGnXrXSA2Lgcsg== X-Received: by 10.28.107.17 with SMTP id g17mr1452737wmc.58.1508928258424; Wed, 25 Oct 2017 03:44:18 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id n14sm3164165wrg.38.2017.10.25.03.44.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 25 Oct 2017 03:44:17 -0700 (PDT) Date: Wed, 25 Oct 2017 11:44:15 +0100 From: Leif Lindholm To: Marcin Wojtas Cc: edk2-devel@lists.01.org, ard.biesheuvel@linaro.org, nadavh@marvell.com, neta@marvell.com, kostap@marvell.com, jinghua@marvell.com, jsd@semihalf.com Message-ID: <20171025104415.tklfpw2xqho5irje@bivouac.eciton.net> References: <1508913930-30886-1-git-send-email-mw@semihalf.com> <1508913930-30886-2-git-send-email-mw@semihalf.com> MIME-Version: 1.0 In-Reply-To: <1508913930-30886-2-git-send-email-mw@semihalf.com> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [platforms: PATCH v2 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, 25 Oct 2017 10:40:35 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Oct 25, 2017 at 08:45:23AM +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 Reviewed-by: Leif Lindholm > --- > Platform/Marvell/Armada/Armada.dsc.inc | 4 + > Platform/Marvell/Armada/Armada70x0.fdf | 1 + > Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c | 255 ++++++++++++++++++++ > Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf | 47 ++++ > Platform/Marvell/Marvell.dec | 3 + > 5 files changed, 310 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..014443d > --- /dev/null > +++ b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c > @@ -0,0 +1,255 @@ > +/** @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; > + } > + // Wait for more TRNG data to arrive > + gBS->Stall (10); > + } > + 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 >