From patchwork Wed Jan 30 19:39:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157083 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp6333414jaa; Wed, 30 Jan 2019 11:39:50 -0800 (PST) X-Google-Smtp-Source: ALg8bN4IRWtEjbQSiqGAXcZl1wORVq1/ZAgEYxO+GJWC5nSaieou8LSX3NN4gL7xej0RLyAFGJ/6 X-Received: by 2002:a62:6f49:: with SMTP id k70mr31491147pfc.7.1548877190641; Wed, 30 Jan 2019 11:39:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548877190; cv=none; d=google.com; s=arc-20160816; b=wQ8mHL78M0Vrwk0kAnIrC5pySy7DYn4VP3xQHaWKRmWMyTXf14i1XdzMJEC3RDt8Zo n/rtKPmvF994CqfkfIZhtGoZp2zK+FKPKug9Rcw/8ensi1980Hk3MIxShQXe/Z4O4RJO GLf/T5Ha5GazEEaH1+zruIHkwN/oboGHVUhDvvOIOogcbnwH/BasNJ0HRZ5HXkTgz4Ex BGK2nToGDRPOeTC0VPWGp5GIPMz9kFz4xZzLlmiiYslfFNNujhgzDvGUC/EFyEZY8LY4 KdNC40WFxH4AvJtlVMzcdojwqTwu2zXlDTdRn8t2/7IlhblUR3LGQWJ0e7ayBm47DA1p 3hyQ== 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:message-id:date:to:from:dkim-signature:delivered-to; bh=APIf83l4wuzWA9mTm5yUy0UKpgLoF8g339JWKpZ29zM=; b=qA+zuNpr1c/TqxndKUCdn8MhVU5iaNICNJVzkemFILMifExZwn8RSVogtY20H+woYY +IVH5heJkiQbTaG4W3pnWET0x81q4O96SN13lftake/WpcqyGybEEXmXk+DNQqLRjFNq 5G0y5Lha8q2XvNLL5R18lpCGGXuTVs9Y1PpPBGpAf5DhVgB7mw6k76copGuuC5LaqGx+ R/Fnw+WEkEuMaNobmBRr7fgiX2qJ3yV41M/KnwR8P3QV9NxmOUJ2M72t5ZIdStq2I//p BeQQ5sPRyDo1+NNg87snIEjwtvjlQrhnHx+VqhrOF+GX89m2tPGnQ5z/2NGl5mFxx6iX Cvkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=VVGrREWz; 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 v2si2108712pgn.451.2019.01.30.11.39.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 11:39:50 -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=VVGrREWz; 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 27EE4211BB8DE; Wed, 30 Jan 2019 11:39:50 -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::442; helo=mail-wr1-x442.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) (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 2D286211BA47D for ; Wed, 30 Jan 2019 11:39:49 -0800 (PST) Received: by mail-wr1-x442.google.com with SMTP id u4so792974wrp.3 for ; Wed, 30 Jan 2019 11:39:49 -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:mime-version :content-transfer-encoding; bh=RB0t6KONujXDttU+uelvRep/tS9Qb90kdRMx+ewcQkM=; b=VVGrREWzJiLTppVzXPVQfncMnlfaGgOwIIGcHicxtxHWW0dTFgV4ST1gFREflh1gBy a1q3lt3D7kVn1c7NQXRe1293tTNlN4UhZLFEZ/Onx8KbqRTRnKteoJudglBQiqFRisFt lxvSH4OjNFkcJATBRmjcbG2YG7/E3KrPyKUY4= 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:mime-version :content-transfer-encoding; bh=RB0t6KONujXDttU+uelvRep/tS9Qb90kdRMx+ewcQkM=; b=FTaYq8zE3SRh/cuRjJXHiFsioOlRiXGpY+R1BSH0rAysfq4xhphN9ErNTEPDoqGCb+ 6shRUKtBlorNcACdHNn8fFtIvkBJcNMScILJGDMkJVIwbmYjs4VV7t27+rsMoZjvuv/2 ShOe39Qj6JctuZNjAL4kY3YxHrEkvVmpmSwCsGy1PevFkj7y1FBUpNbhTnzw4MNJ0jW4 iBfokH51EWCrtRDnUXpzo85s8qaP08ONQXI2DTHrlvGVfzxlJH2/PHhZ5atZoM/Xga2o d145XKHV6PmpRRBkRnZJRAMZ4KT4PnaLT6wvlqBVafGYj7RjXrE6W4mBTuxXiMlwzmgh okHw== X-Gm-Message-State: AJcUukf3kvR8GfuJKwz13wWEQ5weYIlrMkARvkakpL+NYkTvwkB/+TcS urhOu2Lb/SbyraHvcEQBOnSaES8LJpI= X-Received: by 2002:adf:ba05:: with SMTP id o5mr30502746wrg.325.1548877187243; Wed, 30 Jan 2019 11:39:47 -0800 (PST) Received: from sudo.home ([2a01:cb1d:112:6f00:f03c:28d4:cd5a:3698]) by smtp.gmail.com with ESMTPSA id n5sm3065535wrr.94.2019.01.30.11.39.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Jan 2019 11:39:46 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Wed, 30 Jan 2019 20:39:43 +0100 Message-Id: <20190130193943.12023-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [edk2] [PATCH edk2-platforms] 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 | 204 ++++++++++++++++++++ Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h | 26 +++ 3 files changed, 275 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..b1bc93ce0381 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c @@ -0,0 +1,204 @@ +/** @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 + +#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/Bcm2836Rng.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h new file mode 100644 index 000000000000..8274e2fe8f77 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h @@ -0,0 +1,26 @@ + /** @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. + * + **/ + +#ifndef __BCM2836_RNG_H__ +#define __BCM2836_RNG_H__ + +#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_RNG_H__ */