From: Sumit Garg <sumit.garg@linaro.org>
To: edk2-devel@lists.01.org
Cc: daniel.thompson@linaro.org, Sumit Garg <sumit.garg@linaro.org>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
Leif Lindholm <leif.lindholm@linaro.org>
Subject: [PATCH edk2-platforms v1 1/1] Silicon/SynQuacer: add OP-TEE based RNG driver
Date: Tue, 11 Dec 2018 13:15:41 +0530 [thread overview]
Message-ID: <1544514341-3176-1-git-send-email-sumit.garg@linaro.org> (raw)
This driver uses OpteeLib to interface with OP-TEE based RNG service
(pseudo trusted application) to implement EFI_RNG_PROTOCOL that is used
to seed kernel entropy pool.
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
---
Depends on "ArmPkg/OpteeLib: Add OPTEE_SUCCESS return code" patch.
For detailed implementation of OP-TEE based RNG service (pseudo
trusted application), please refer to OP-TEE PR here [1].
[1] https://github.com/OP-TEE/optee_os/pull/2564
Silicon/Socionext/SynQuacer/SynQuacer.dec | 2 +
Platform/Socionext/DeveloperBox/DeveloperBox.dsc | 1 +
Platform/Socionext/DeveloperBox/DeveloperBox.fdf | 1 +
Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf | 55 ++++
Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRng.c | 270 ++++++++++++++++++++
Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.uni | 19 ++
| 18 ++
7 files changed, 366 insertions(+)
diff --git a/Silicon/Socionext/SynQuacer/SynQuacer.dec b/Silicon/Socionext/SynQuacer/SynQuacer.dec
index ccaf80def06b..e58a373ecb3d 100644
--- a/Silicon/Socionext/SynQuacer/SynQuacer.dec
+++ b/Silicon/Socionext/SynQuacer/SynQuacer.dec
@@ -29,6 +29,8 @@ [Guids]
gSynQuacerPlatformFormSetGuid = { 0xe9cd576a, 0xaf9a, 0x4d41, { 0xbf, 0x1a, 0x29, 0xe1, 0xbc, 0x99, 0x99, 0x54 } }
+ gOpteeRngTaGuid = { 0xab7a617c, 0xb8e7, 0x4d8f, { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } }
+
[Ppis]
gSynQuacerDramInfoPpiGuid = { 0x3e1d7356, 0xdda4, 0x4b1a, { 0x93, 0x46, 0xbf, 0x89, 0x1c, 0x86, 0x46, 0xcc } }
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
index 997ea344330d..b18286a0b228 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
@@ -628,6 +628,7 @@ [Components.common]
#
# RNG
#
+ Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf
Silicon/Openmoko/ChaosKeyDxe/ChaosKeyDxe.inf
#
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.fdf b/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
index 3a92e0fe63ef..4a234a36525e 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
@@ -189,6 +189,7 @@ [FV.FvMain]
#
# RNG
#
+ INF Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf
INF Silicon/Openmoko/ChaosKeyDxe/ChaosKeyDxe.inf
#
diff --git a/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf
new file mode 100644
index 000000000000..6fef1b380270
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# Device driver for the OP-TEE based random number generator.
+#
+# Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
+#
+# 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 = 0x0001001A
+ BASE_NAME = OpteeRngDxe
+ MODULE_UNI_FILE = OpteeRngDxe.uni
+ FILE_GUID = 93A599F2-6D82-4FCC-9970-49BB013D695A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = OpteeRngEntry
+
+#
+# VALID_ARCHITECTURES = AARCH64 ARM
+#
+
+[Sources]
+ OpteeRng.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Socionext/SynQuacer/SynQuacer.dec
+
+[LibraryClasses]
+ OpteeLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiRngProtocolGuid # PROTOCOL BY_START
+
+[Guids]
+ gEfiRngAlgorithmRaw
+ gOpteeRngTaGuid
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ OpteeRngDxeExtra.uni
diff --git a/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRng.c b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRng.c
new file mode 100644
index 000000000000..089fad8b5ce5
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRng.c
@@ -0,0 +1,270 @@
+/** @file
+ Device driver for the OpteeRng hardware random number generator.
+
+ Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
+
+ 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 <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/OpteeLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Rng.h>
+
+#define PTA_COMMAND_GET_ENTROPY 0x0
+#define OPTEE_RNG_POOL_SIZE (4 * 1024)
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] AlgorithmListSize On input, the size in bytes of AlgorithmList
+ On output with a return code of EFI_SUCCESS,
+ the size in bytes of the data returned in
+ AlgorithmList. On output with a return
+ code of EFI_BUFFER_TOO_SMALL, the size of
+ AlgorithmList required to obtain the list.
+ @param[out] AlgorithmList 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
+GetInfo (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *AlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *AlgorithmList
+)
+{
+ UINTN Size;
+
+ //
+ // We only implement the raw algorithm
+ //
+ Size = sizeof gEfiRngAlgorithmRaw;
+
+ if (*AlgorithmListSize < Size) {
+ *AlgorithmListSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ gBS->CopyMem (AlgorithmList, &gEfiRngAlgorithmRaw, Size);
+ *AlgorithmListSize = Size;
+
+ 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] Algorithm 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] ValueLength The length in bytes of the memory buffer
+ pointed to by RNGValue. The driver shall
+ return exactly this numbers of bytes.
+ @param[out] Value 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 and RNGValueLength is
+ non-zero.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *Algorithm OPTIONAL,
+ IN UINTN ValueLength,
+ OUT UINT8 *Value
+)
+{
+ EFI_STATUS Status;
+ OPTEE_OPEN_SESSION_ARG OpenSessionArg;
+ OPTEE_INVOKE_FUNCTION_ARG InvokeFunctionArg;
+ UINT8 *OutPointer;
+ UINTN OutSize;
+ UINTN WaitMiliSeconds;
+
+ if ((Value == NULL) && (ValueLength != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ValueLength > OPTEE_RNG_POOL_SIZE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Algorithm != NULL && !CompareGuid (Algorithm, &gEfiRngAlgorithmRaw)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ZeroMem (&OpenSessionArg, sizeof (OPTEE_OPEN_SESSION_ARG));
+ CopyMem (&OpenSessionArg.Uuid, &gOpteeRngTaGuid, sizeof (EFI_GUID));
+
+ Status = OpteeOpenSession (&OpenSessionArg);
+ if ((Status != EFI_SUCCESS) || (OpenSessionArg.Return != OPTEE_SUCCESS)) {
+ DEBUG ((DEBUG_ERROR, "OP-TEE Open Session failed with return: %08x and"
+ "return origin: %d\n", OpenSessionArg.Return,
+ OpenSessionArg.ReturnOrigin));
+ return EFI_DEVICE_ERROR;
+ }
+
+ OutPointer = Value;
+
+ while (ValueLength > 0) {
+ ZeroMem (&InvokeFunctionArg, sizeof (OPTEE_INVOKE_FUNCTION_ARG));
+
+ InvokeFunctionArg.Function = PTA_COMMAND_GET_ENTROPY;
+ InvokeFunctionArg.Session = OpenSessionArg.Session;
+
+ InvokeFunctionArg.Params[0].Attribute =
+ OPTEE_MESSAGE_ATTRIBUTE_TYPE_MEMORY_INOUT;
+ InvokeFunctionArg.Params[0].Union.Memory.BufferAddress =
+ (UINT64) OutPointer;
+ InvokeFunctionArg.Params[0].Union.Memory.Size = ValueLength;
+
+ Status = OpteeInvokeFunction (&InvokeFunctionArg);
+ if ((Status != EFI_SUCCESS) ||
+ (InvokeFunctionArg.Return != OPTEE_SUCCESS)) {
+ DEBUG ((DEBUG_ERROR, "OP-TEE Invoke Function failed with return: %x and"
+ "return origin: %d\n", InvokeFunctionArg.Return,
+ InvokeFunctionArg.ReturnOrigin));
+
+ OpteeCloseSession (OpenSessionArg.Session);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ OutSize = MIN (InvokeFunctionArg.Params[0].Union.Memory.Size, ValueLength);
+
+ OutPointer += OutSize;
+ ValueLength -= OutSize;
+
+ //
+ // OP-TEE RNG Trusted application takes approximately 256ms for every 32
+ // bytes of full entropy output.
+ //
+ if (ValueLength > 0) {
+ WaitMiliSeconds = ((ValueLength + 32) * 256) / 32;
+ MicroSecondDelay (WaitMiliSeconds * 1000);
+ }
+ }
+
+ OpteeCloseSession (OpenSessionArg.Session);
+
+ return EFI_SUCCESS;
+}
+
+//
+// OP-TEE based Random Number Generator (RNG) protocol
+//
+EFI_RNG_PROTOCOL mOpteeRng = {
+ GetInfo,
+ GetRNG
+};
+
+/**
+ The user Entry Point for the OP-TEE Random Number Generator (RNG) driver.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval EFI_NOT_FOUND Not able to find OP-TEE based RNG.
+ @retval Other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+OpteeRngEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ OPTEE_OPEN_SESSION_ARG OpenSessionArg;
+
+ if (!IsOpteePresent()) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Initialize OP-TEE
+ //
+ Status = OpteeInit ();
+ if (Status != EFI_SUCCESS) {
+ return EFI_NOT_FOUND;
+ }
+
+ ZeroMem (&OpenSessionArg, sizeof (OPTEE_OPEN_SESSION_ARG));
+ CopyMem (&OpenSessionArg.Uuid, &gOpteeRngTaGuid, sizeof (EFI_GUID));
+
+ //
+ // Try to open session with RNG Trusted Application to check if its present
+ //
+ Status = OpteeOpenSession (&OpenSessionArg);
+ if ((Status != EFI_SUCCESS) || (OpenSessionArg.Return != OPTEE_SUCCESS)) {
+ return EFI_NOT_FOUND;
+ } else {
+ OpteeCloseSession (OpenSessionArg.Session);
+ }
+
+ //
+ // Install UEFI RNG (Random Number Generator) Protocol
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (&Handle,
+ &gEfiRngProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mOpteeRng);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "Failed to install OP-TEE RNG protocol interface (Status == %r)\n",
+ Status));
+ return Status;
+ }
+
+ DEBUG ((DEBUG_INIT | DEBUG_INFO, "*** Installed OpteeRng driver! ***\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.uni b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.uni
new file mode 100644
index 000000000000..320561f39d8c
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxe.uni
@@ -0,0 +1,19 @@
+// /** @file
+// Installs OP-TEE based UEFI Random Number Generator protocol.
+//
+// Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+//
+// 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Installs OP-TEE based UEFI Random Number Generator protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver installs UEFI Random Number Generator protocol based on OP-TEE library to interface with RNG service running in OP-TEE environment."
+
--git a/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxeExtra.uni b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxeExtra.uni
new file mode 100644
index 000000000000..eadd103de688
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// OpteeRngDxe Localized Strings and Content
+//
+// Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+//
+// 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.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"OP-TEE RNG DXE Driver"
+
--
2.7.4
next reply other threads:[~2018-12-11 7:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-11 7:45 Sumit Garg [this message]
2018-12-11 8:26 ` [PATCH edk2-platforms v1 1/1] Silicon/SynQuacer: add OP-TEE based RNG driver Ard Biesheuvel
2018-12-11 9:04 ` Sumit Garg
2018-12-11 9:06 ` Ard Biesheuvel
2018-12-11 16:07 ` Ard Biesheuvel
2018-12-12 5:35 ` Sumit Garg
2018-12-18 12:17 ` Sumit Garg
2018-12-18 12:46 ` Ard Biesheuvel
2018-12-20 10:43 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1544514341-3176-1-git-send-email-sumit.garg@linaro.org \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox