From patchwork Sat Feb 16 10:34:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 158562 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp384354jaa; Sat, 16 Feb 2019 02:34:34 -0800 (PST) X-Google-Smtp-Source: AHgI3IbjIRkYNSLsBzTz+OT+GOF6dbY5Tpslm5ibYUbyKWb2srYzQ7wPdudML6rnsgr6gev09CAu X-Received: by 2002:a17:902:45:: with SMTP id 63mr7116769pla.281.1550313274221; Sat, 16 Feb 2019 02:34:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550313274; cv=none; d=google.com; s=arc-20160816; b=YD+CLiL13O8x1Detz31usMn3gXwgJ6nExOVbmyAUV7HP1JWNtdicWmo04EshroPDmG TdTj5vN9s254mMs08KnOdFpbJWSmQpK0MskYUGXVzDs4ApWceGD3WEtZAb55szbbHFw3 /9aUHDT7aXk699EgHI6Q+CgYxW1hv1MfX6P4ZPOusDJgLoZljHu8TSWfDK+fSfX8rPLo 1wkaHA+PP1mS9SBovOQKFBxlospylNkQImTPj3royfraf3eHjfC79QNXdBVdu4gi33H5 1P2Gubani9V8Sse7LpZGUPo6QmZMrBUy1JhmXjl2sKAvZQruPuapyzlX6muRpGoaP4mf M62A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:delivered-to; bh=zycNd9cLBE/W20y6Ea4sA1A4wytcnWDbKvUISVTgPoo=; b=J4/FTh1nOWmRNFphUgSdOTxItVL3sEc0PRbNdn1a99j+zb11+eg8j2X8SkK8Rj9x9+ 7BN8g9YGXwFRLp3NZ7/q03jPft38vRnzCEMik8MVufUThDQS5TOy6xx5s4exJNUjuArn srTMmeWvZrfERpcMqSbVlgz+TTAJNip0oEskD5zbYtXDiXuFImVdaSZh26aWDEfZU6NB YWdk7KT3SWh5WLWzak/ZgWnWrK/nUGo6NGlircIl9USm12D+arKhDRk/maaQIZYr8xH0 1X5IFrsfwZiK5Yo+RD2ez15wbHhww601ZzpQFKczPnHa1eNfpwMdGRP38PD+GKqdb0vF VZ7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZQuN74tb; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id g7si7904220plt.212.2019.02.16.02.34.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Feb 2019 02:34:34 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZQuN74tb; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D62EB208EB3F4; Sat, 16 Feb 2019 02:34:32 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:4864:20::341; helo=mail-wm1-x341.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) (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 C9585208D6147 for ; Sat, 16 Feb 2019 02:34:30 -0800 (PST) Received: by mail-wm1-x341.google.com with SMTP id d15so12493427wmb.3 for ; Sat, 16 Feb 2019 02:34:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/Rbb7BwmkD+fHVtd0dn4sG9CoI6t9wF2MXN3UI6EbDM=; b=ZQuN74tbeV4l8J4fs8Po+exwhYENsrTiOrL13sD0kK3Eqsm9MwBFHaWod61j9+xhVC 5GuE5MlQJLz8m+XexTwwLefSXj7rTqUkX0+Zpg5puO0ftrj53ykMuTvELn/QQn2yQiwr H7S0IAAEi7oLv9z8g+UA8WJ6HWCmYVJCSBZBJGU5RoHKKYjsrKL1fYNAaCBuF8Qp+SUp 8D4pTBMTm/Z6QT3ohCFyRqfk83zdpd6pwO6ZTtbC3imys0IQ8czCSHqzn5ySNurM6rcE uYS/1KUR8Dmiag8lPOz0/WLw5wkRswJ6J3wAp5BdGRJiltxYl1SXTRPIzyqJBuckOe6K +50Q== 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:mime-version:content-transfer-encoding; bh=/Rbb7BwmkD+fHVtd0dn4sG9CoI6t9wF2MXN3UI6EbDM=; b=ESW6ZnVvwflmWpyQZnsEdIBablrfxgW9vbb90vPO5c/B8lfLmpnlnGM0kX0Hx2kvnq P7eaHnLv2AHrvX+mL8po5msO+0JENwtOO2A0rFll7npDDAFsv0ObbodfChfhV2/Jki5O MXgHJeYK8P0UFU+QNgkjrtDDeBlEHnZwIyt3KT8QBaNRPcnN5mqfTTNddpI1Ld4K9gNZ oTnhNE08UXa+5O5K33MLYqOD5Y7aMSnDt9I93Bux2v3EXSqzcmQbKCS274YJuCthVQF8 Y8a7MOBQw9jZXaYdHlcZLrQrlH2xudFFmyGwVaWAHHAozyx8up1z4DN+RX8xXY3pem8S tPQw== X-Gm-Message-State: AHQUAua2gHfzXgR9pzjGsLB1JvTmwVOx+ZKLs2/s6araC5fRKHn6YYmt eilERRqVnKUb1BCADmvY8JOZ1Nf8bZA= X-Received: by 2002:a1c:ca01:: with SMTP id a1mr9276450wmg.124.1550313268815; Sat, 16 Feb 2019 02:34:28 -0800 (PST) Received: from sudo.home ([2a01:cb1d:112:6f00:ddaf:5369:7280:8c79]) by smtp.gmail.com with ESMTPSA id u10sm4740314wrr.33.2019.02.16.02.34.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Feb 2019 02:34:28 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Sat, 16 Feb 2019 11:34:21 +0100 Message-Id: <20190216103422.10907-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190216103422.10907-1-ard.biesheuvel@linaro.org> References: <20190216103422.10907-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Subject: [edk2] [PATCH edk2-platforms 1/2] Silicon/Bcm2836: add random number generator driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. This is used by Linux to seed the KASLR routines. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel --- Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c | 203 ++++++++++++++++++++ Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h | 9 + 3 files changed, 257 insertions(+) -- 2.20.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c new file mode 100644 index 000000000000..399d93158547 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c @@ -0,0 +1,203 @@ +/** @file + + This driver produces an EFI_RNG_PROTOCOL instance for the Broadcom 2836 RNG + + Copyright (C) 2019, 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 + +#include + +#include + +#define RNG_WARMUP_COUNT 0x40000 +#define RNG_MAX_RETRIES 0x100 // arbitrary upper bound + +/** + 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 +Bcm2836RngGetInfo ( + 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 +Bcm2836RngGetRNG ( + IN EFI_RNG_PROTOCOL *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ) +{ + UINT32 Val; + UINT32 Num; + UINT32 Retries; + + 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; + } + + while (RNGValueLength > 0) { + Retries = RNG_MAX_RETRIES; + do { + Num = MmioRead32 (RNG_STATUS) >> 24; + MemoryFence (); + } while (!Num && Retries-- > 0); + + if (!Num) { + return EFI_DEVICE_ERROR; + } + + while (RNGValueLength >= sizeof (UINT32) && Num > 0) { + WriteUnaligned32 ((VOID *)RNGValue, MmioRead32 (RNG_DATA)); + RNGValue += sizeof (UINT32); + RNGValueLength -= sizeof (UINT32); + Num--; + } + + if (RNGValueLength > 0 && Num > 0) { + Val = MmioRead32 (RNG_DATA); + while (RNGValueLength--) { + *RNGValue++ = (UINT8)Val; + Val >>= 8; + } + } + } + return EFI_SUCCESS; +} + +STATIC EFI_RNG_PROTOCOL mBcm2836RngProtocol = { + Bcm2836RngGetInfo, + Bcm2836RngGetRNG +}; + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +Bcm2836RngEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiRngProtocolGuid, &mBcm2836RngProtocol, + NULL); + ASSERT_EFI_ERROR (Status); + + MmioWrite32 (RNG_STATUS, RNG_WARMUP_COUNT); + MmioWrite32 (RNG_CTRL, RNG_CTRL_ENABLE); + + return EFI_SUCCESS; +} diff --git a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf new file mode 100644 index 000000000000..45e8825244f7 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf @@ -0,0 +1,45 @@ +#/** @file +# +# Copyright (c) 2019 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 = 0x0001001B + BASE_NAME = RngDxe + FILE_GUID = 9743084e-c82a-4714-b2ba-f571f81cb021 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Bcm2836RngEntryPoint + +[Sources] + RngDxe.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/Broadcom/Bcm283x/Bcm283x.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiRngProtocolGuid ## PRODUCES + +[Guids] + gEfiRngAlgorithmRaw + +[Depex] + TRUE diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h index f9fffb764649..f06eb2312c61 100644 --- a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h @@ -69,4 +69,13 @@ #define BCM2836_INTC_TIMER_CONTROL_OFFSET 0x00000040 #define BCM2836_INTC_TIMER_PENDING_OFFSET 0x00000060 +/* random number generator */ +#define RNG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + 0x00104000) + +#define RNG_CTRL (RNG_BASE_ADDRESS + 0x0) +#define RNG_STATUS (RNG_BASE_ADDRESS + 0x4) +#define RNG_DATA (RNG_BASE_ADDRESS + 0x8) + +#define RNG_CTRL_ENABLE 0x1 + #endif /*__BCM2836_H__ */