public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Sumit Garg <sumit.garg@linaro.org>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	Daniel Thompson <daniel.thompson@linaro.org>,
	 Leif Lindholm <leif.lindholm@linaro.org>
Subject: Re: [PATCH edk2-platforms v1 1/1] Silicon/SynQuacer: add OP-TEE based RNG driver
Date: Tue, 11 Dec 2018 09:26:16 +0100	[thread overview]
Message-ID: <CAKv+Gu-W-1xBq5M79cPdurSgdaKS5j8qz1rn2T2ge_CD5CpaQA@mail.gmail.com> (raw)
In-Reply-To: <1544514341-3176-1-git-send-email-sumit.garg@linaro.org>

On Tue, 11 Dec 2018 at 08:46, Sumit Garg <sumit.garg@linaro.org> wrote:
>
> 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>

Excellent! Happy to see this code going upstream.

This code looks fine to me, but I'd like to test it with an updated
OP-TEE build first before I merge it.


> ---
>
> 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 ++
>  Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxeExtra.uni |  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."
> +
> diff --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
>


  reply	other threads:[~2018-12-11  8:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-11  7:45 [PATCH edk2-platforms v1 1/1] Silicon/SynQuacer: add OP-TEE based RNG driver Sumit Garg
2018-12-11  8:26 ` Ard Biesheuvel [this message]
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=CAKv+Gu-W-1xBq5M79cPdurSgdaKS5j8qz1rn2T2ge_CD5CpaQA@mail.gmail.com \
    --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