From patchwork Wed Oct 25 06:45:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcin Wojtas X-Patchwork-Id: 117018 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp509378qgn; Tue, 24 Oct 2017 23:46:49 -0700 (PDT) X-Google-Smtp-Source: ABhQp+RUNnuLUuENgnrMh36qTm806l5FjRUhtADzUYr0nppRpXo51epJ9EmtEE5uCNpBnWP94mkB X-Received: by 10.98.148.9 with SMTP id m9mr1212553pfe.111.1508914008988; Tue, 24 Oct 2017 23:46:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1508914008; cv=none; d=google.com; s=arc-20160816; b=KO8cFM7ETHD76ae/SyJLoYuuLNeQqQY1agtaIymF2heL0ca0y9sIDRDy3NhuE4vdVM lA7qSkOCJ6XQsLxgt6h4oVx1zoGWPfg4npf1RfpoiKnzsEb2LtZ/er7C+HYwAtsiWFHF TKuwCZtaKxu7qJ/DGdKk/wr4rWDYhxW6opqqTC29ORwJNco+32Z64iVEX805WNVXBxda xN2C1jKLq5Wy07FPy4OhAZsV4PbzSEA+bCl5qkOfimD/N0AZGfd7T0lkeOenB3uugrg9 0CGE7g5nkkO20D46diSaU54KJGX5/5Y8DsrFrPcAtXk+VGOf4kTWzzU9XKYGwWvSfwz+ uXlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=0LvHhhJPiYNZ7UOEMKYVXBChKt6d9oQLs9fjhtZySFE=; b=noT0UUOBxFK8Ak5mk1EnOokRKpwKKFwDEzyXYW8vHx+YR54qIpqEig75sDMoZO0f3e AutkQzuShzmhEGB6ie3uNCDIRKnzC0SOH3i2IASuaOOq8ZQ45Pd6GIQAudzJGqyQH51c F7H3lVQ4LnIhZ0y7z3pWRz5jbvIWMZ7MlMjxLMpU5491r+bgd+WhFwVBf+Y3YxnmLh6k 1Q6CJmvbXXUW+8JPgOVasXX3yoyh18qF0M0AkNevgQEy/5/PC2puaUFvP2dy8i8KTIzj tivxrw/KOOsdE4T8hlOpNKjSeDW0D8xBw/50/bE/VelXwIqCBQK9pO1YSTWTaIuc+jXL mf4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=gvGTybLx; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id b2si1403437pgr.511.2017.10.24.23.46.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Oct 2017 23:46:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=gvGTybLx; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id B88A62034C089; Tue, 24 Oct 2017 23:43:03 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2a00:1450:4010:c07::241; helo=mail-lf0-x241.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-lf0-x241.google.com (mail-lf0-x241.google.com [IPv6:2a00:1450:4010:c07::241]) (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 C195920347156 for ; Tue, 24 Oct 2017 23:43:01 -0700 (PDT) Received: by mail-lf0-x241.google.com with SMTP id a2so4502923lfh.11 for ; Tue, 24 Oct 2017 23:46:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qZ+h2MPyUS32AeRZekIxNmJznIldLjpejjkh+JDaO3Q=; b=gvGTybLxrxJy54mx1z1DB9af18hLaJUqohIFKPJWoB7ktirpCP/lVo3IiU4pFxBkuv NeKDHZCXZDDA5QCC1uvNsmblf+2qOQlwr6I0ICiegOE049jNAd6IWoTKGZ8W3Cq8yZGv Y17I6sDnA6F6z0JCJryDH2oThSYJG+DPR52qxMFbTSqhfFHBp1bHcMCcWE7vbeqatOOP AuafcEPghAvLqlrj5r+KZMuWR8iHlM9XPQ1x1gOL28N7moW0tXDlJsKaSJMqeCFhfchA 9de8ybcuW9YsB6GU9lLX0HuV8HbzMXliOEZ0WrWFqhfrmMg0fWwDGDz2B7k4MNfbYFvT U3vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qZ+h2MPyUS32AeRZekIxNmJznIldLjpejjkh+JDaO3Q=; b=mHbH01qDEOGTaiI2coQw++WAQ4QvUh82Y9lqZEHvcnq8vm7SeTmiwD0xikMr7yry8w XlR933mxlnZCXynlQ+Ubp/mhmF8Lp67H/mXFGfIUsQJIAwJZEOXAIxKHAQs39rN9qKhc 1B64SR39LZtXpSv1d90ntg0pSKSwIF3sWHZVibMfgIPk6R7uRid/k5ny3vn75QTH7x2+ p47LqRdOgRQEJUQ7ZtVmHj3m8dfRhUoYm9lZqA9jaWD/bX2JMwVcjtJg9fwp3K4UvRJY VLlkN/0r04D6dm7oxyPbtPOtDVbbKTuttKYGqMlD/XyVDkUKMbu7fhp3m7lrsWRcf+GE NXaQ== X-Gm-Message-State: AMCzsaUvT9Me6LoWVCAXlKB6phx1EyEjGP6agnm891GpoCxQuKnnwpzs tFNqp8jJjmhbQfH/LhxDS8m/dp+Hc6U= X-Received: by 10.46.9.197 with SMTP id 188mr7600424ljj.134.1508914004326; Tue, 24 Oct 2017 23:46:44 -0700 (PDT) Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id r22sm513129ljr.16.2017.10.24.23.46.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Oct 2017 23:46:43 -0700 (PDT) From: Marcin Wojtas To: edk2-devel@lists.01.org Date: Wed, 25 Oct 2017 08:45:23 +0200 Message-Id: <1508913930-30886-2-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508913930-30886-1-git-send-email-mw@semihalf.com> References: <1508913930-30886-1-git-send-email-mw@semihalf.com> Subject: [edk2] [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: , Cc: jinghua@marvell.com, ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, nadavh@marvell.com, neta@marvell.com, kostap@marvell.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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 | 255 ++++++++++++++++++++ Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf | 47 ++++ Platform/Marvell/Marvell.dec | 3 + 5 files changed, 310 insertions(+) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm 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 }}