diff mbox series

[edk2,edk2-platforms,v1,1/1] Silicon/SynQuacer: add OP-TEE based RNG driver

Message ID 1544514341-3176-1-git-send-email-sumit.garg@linaro.org
State New
Headers show
Series [edk2,edk2-platforms,v1,1/1] Silicon/SynQuacer: add OP-TEE based RNG driver | expand

Commit Message

Sumit Garg Dec. 11, 2018, 7:45 a.m. UTC
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 ++
 Silicon/Socionext/SynQuacer/Drivers/OpteeRngDxe/OpteeRngDxeExtra.uni |  18 ++
 7 files changed, 366 insertions(+)

-- 
2.7.4

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Comments

Ard Biesheuvel Dec. 11, 2018, 8:26 a.m. UTC | #1
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

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Sumit Garg Dec. 11, 2018, 9:04 a.m. UTC | #2
On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> 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.

>


Thanks Ard.

> This code looks fine to me, but I'd like to test it with an updated

> OP-TEE build first before I merge it.

>


Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could
share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

-Sumit

>

> > ---

> >

> > 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

> >

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Dec. 11, 2018, 9:06 a.m. UTC | #3
On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:
>

> On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >

> > 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.

> >

>

> Thanks Ard.

>

> > This code looks fine to me, but I'd like to test it with an updated

> > OP-TEE build first before I merge it.

> >

>

> Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

>


Yes please, that would be useful.


> >

> > > ---

> > >

> > > 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

> > >

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Dec. 11, 2018, 4:07 p.m. UTC | #4
On Tue, 11 Dec 2018 at 10:06, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:

> >

> > On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > >

> > > 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.

> > >

> >

> > Thanks Ard.

> >

> > > This code looks fine to me, but I'd like to test it with an updated

> > > OP-TEE build first before I merge it.

> > >

> >

> > Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> > share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

> >

>

> Yes please, that would be useful.

>

>


OK, I successfully tested this patch on my SynQuacer box. Very nice work!

So this is ready to go in as soon as the OP-TEE side is merged as
well, so please keep me informed about that (and contribute a new
ARM-TF + OP-TEE build to edk2-non-osi)

Thanks!

> > >

> > > > ---

> > > >

> > > > 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

> > > >

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Sumit Garg Dec. 12, 2018, 5:35 a.m. UTC | #5
On Tue, 11 Dec 2018 at 21:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> On Tue, 11 Dec 2018 at 10:06, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >

> > On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:

> > >

> > > On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > >

> > > > 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.

> > > >

> > >

> > > Thanks Ard.

> > >

> > > > This code looks fine to me, but I'd like to test it with an updated

> > > > OP-TEE build first before I merge it.

> > > >

> > >

> > > Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> > > share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

> > >

> >

> > Yes please, that would be useful.

> >

> >

>

> OK, I successfully tested this patch on my SynQuacer box. Very nice work!

>


Thanks Ard for testing this patch.

> So this is ready to go in as soon as the OP-TEE side is merged as

> well, so please keep me informed about that (and contribute a new

> ARM-TF + OP-TEE build to edk2-non-osi)


Sure will let you know about OP-TEE PR merge and yes will contribute a
new ARM-TF + OP-TEE build to edk2-non-osi.

-Sumit

>

> Thanks!

>

> > > >

> > > > > ---

> > > > >

> > > > > 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

> > > > >

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Sumit Garg Dec. 18, 2018, 12:17 p.m. UTC | #6
Hi Ard,

On Wed, 12 Dec 2018 at 11:05, Sumit Garg <sumit.garg@linaro.org> wrote:
>

> On Tue, 11 Dec 2018 at 21:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >

> > On Tue, 11 Dec 2018 at 10:06, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > >

> > > On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:

> > > >

> > > > On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > > >

> > > > > 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.

> > > > >

> > > >

> > > > Thanks Ard.

> > > >

> > > > > This code looks fine to me, but I'd like to test it with an updated

> > > > > OP-TEE build first before I merge it.

> > > > >

> > > >

> > > > Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> > > > share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

> > > >

> > >

> > > Yes please, that would be useful.

> > >

> > >

> >

> > OK, I successfully tested this patch on my SynQuacer box. Very nice work!

> >

>

> Thanks Ard for testing this patch.

>

> > So this is ready to go in as soon as the OP-TEE side is merged as

> > well, so please keep me informed about that (and contribute a new

> > ARM-TF + OP-TEE build to edk2-non-osi)

>

> Sure will let you know about OP-TEE PR merge and yes will contribute a

> new ARM-TF + OP-TEE build to edk2-non-osi.

>


OP-TEE PR [1] has been merged. Also I have sent a patch to contribute
new ARM-TF + OP-TEE build. Please have a look.

[1] https://github.com/OP-TEE/optee_os/pull/2564

-Sumit

>

> >

> > Thanks!

> >

> > > > >

> > > > > > ---

> > > > > >

> > > > > > 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

> > > > > >

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Dec. 18, 2018, 12:46 p.m. UTC | #7
On Tue, 18 Dec 2018 at 13:17, Sumit Garg <sumit.garg@linaro.org> wrote:
>

> Hi Ard,

>

> On Wed, 12 Dec 2018 at 11:05, Sumit Garg <sumit.garg@linaro.org> wrote:

> >

> > On Tue, 11 Dec 2018 at 21:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > >

> > > On Tue, 11 Dec 2018 at 10:06, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > >

> > > > On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:

> > > > >

> > > > > On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > > > >

> > > > > > 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.

> > > > > >

> > > > >

> > > > > Thanks Ard.

> > > > >

> > > > > > This code looks fine to me, but I'd like to test it with an updated

> > > > > > OP-TEE build first before I merge it.

> > > > > >

> > > > >

> > > > > Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> > > > > share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

> > > > >

> > > >

> > > > Yes please, that would be useful.

> > > >

> > > >

> > >

> > > OK, I successfully tested this patch on my SynQuacer box. Very nice work!

> > >

> >

> > Thanks Ard for testing this patch.

> >

> > > So this is ready to go in as soon as the OP-TEE side is merged as

> > > well, so please keep me informed about that (and contribute a new

> > > ARM-TF + OP-TEE build to edk2-non-osi)

> >

> > Sure will let you know about OP-TEE PR merge and yes will contribute a

> > new ARM-TF + OP-TEE build to edk2-non-osi.

> >

>

> OP-TEE PR [1] has been merged. Also I have sent a patch to contribute

> new ARM-TF + OP-TEE build. Please have a look.

>

> [1] https://github.com/OP-TEE/optee_os/pull/2564

>


Wonderful! Thanks a lot.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Dec. 20, 2018, 10:43 a.m. UTC | #8
On Tue, 18 Dec 2018 at 13:46, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>

> On Tue, 18 Dec 2018 at 13:17, Sumit Garg <sumit.garg@linaro.org> wrote:

> >

> > Hi Ard,

> >

> > On Wed, 12 Dec 2018 at 11:05, Sumit Garg <sumit.garg@linaro.org> wrote:

> > >

> > > On Tue, 11 Dec 2018 at 21:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > >

> > > > On Tue, 11 Dec 2018 at 10:06, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > > >

> > > > > On Tue, 11 Dec 2018 at 10:04, Sumit Garg <sumit.garg@linaro.org> wrote:

> > > > > >

> > > > > > On Tue, 11 Dec 2018 at 13:56, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > > > > > >

> > > > > > > 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.

> > > > > > >

> > > > > >

> > > > > > Thanks Ard.

> > > > > >

> > > > > > > This code looks fine to me, but I'd like to test it with an updated

> > > > > > > OP-TEE build first before I merge it.

> > > > > > >

> > > > > >

> > > > > > Agree, will wait for OP-TEE PR to be merged. BTW, if you need I could

> > > > > > share updated "fip_all_arm_tf.bin" using OP-TEE PR for testing.

> > > > > >

> > > > >

> > > > > Yes please, that would be useful.

> > > > >

> > > > >

> > > >

> > > > OK, I successfully tested this patch on my SynQuacer box. Very nice work!

> > > >

> > >

> > > Thanks Ard for testing this patch.

> > >

> > > > So this is ready to go in as soon as the OP-TEE side is merged as

> > > > well, so please keep me informed about that (and contribute a new

> > > > ARM-TF + OP-TEE build to edk2-non-osi)

> > >

> > > Sure will let you know about OP-TEE PR merge and yes will contribute a

> > > new ARM-TF + OP-TEE build to edk2-non-osi.

> > >

> >

> > OP-TEE PR [1] has been merged. Also I have sent a patch to contribute

> > new ARM-TF + OP-TEE build. Please have a look.

> >

> > [1] https://github.com/OP-TEE/optee_os/pull/2564

> >

>

> Wonderful! Thanks a lot.


Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>


Pushed as c955b5129771..dc6b5ef8a6c2
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox series

Patch

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"
+