From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web08.12647.1656515081832624494 for ; Wed, 29 Jun 2022 08:04:42 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C385D1763; Wed, 29 Jun 2022 08:04:41 -0700 (PDT) Received: from pierre123.arm.com (unknown [10.57.42.208]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5385D3F792; Wed, 29 Jun 2022 08:04:39 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [PATCH v3 16/21] SecurityPkg/RngDxe: Check before advertising Cpu Rng algo Date: Wed, 29 Jun 2022 17:02:29 +0200 Message-Id: <20220629150241.2597898-21-Pierre.Gondois@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220629150241.2597898-1-Pierre.Gondois@arm.com> References: <20220629150241.2597898-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Pierre Gondois RngGetBytes() relies on the RngLib. The RngLib might use the RNDR instruction if the FEAT_RNG feature is present. Check RngGetBytes() is working before advertising it via RngGetInfo(). To only check this one time, create a static array that is shared between RngGetInfo and RngGetRNG. This array contains GUIDs. The Rng algorithm with the lowest GUID and that has been checked will be the default Rng algorithm. This patch also prevents from having PcdCpuRngSupportedAlgorithm let to a zero GUID, but let the possibility to have no valid Rng algorithm in such case. Signed-off-by: Pierre Gondois --- .../RngDxe/AArch64/RngDxe.c | 77 +++++++++++++++++-- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/= SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c index f9c740d761ff..d8b696bbea5f 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c @@ -23,10 +23,44 @@ #include #include #include +#include #include =20 #include "RngDxeInternals.h" =20 +// +// Static array containing the validated Rng algorithm. +// This array is used by RngGetInfo and RngGetRNG and needs to be +// populated only once. +// The valid entry with the lowest index will be the default algorithm. +// +#define RNG_AVAILABLE_ALGO_MAX 1 +STATIC BOOLEAN mAvailableAlgoArrayInit =3D FALSE; +STATIC UINTN mAvailableAlgoArrayCount; +STATIC EFI_RNG_ALGORITHM mAvailableAlgoArray[RNG_AVAILABLE_ALGO_MAX]; + +/** Initialize mAvailableAlgoArray with the available Rng algorithms. +**/ +STATIC +VOID +EFIAPI +RngInitAvailableAlgoArray ( + VOID + ) +{ + // Check RngGetBytes() before advertising PcdCpuRngSupportedAlgorithm. + if (!EFI_ERROR (RngGetBytes (sizeof (Rand), (UINT8 *)&Rand))) { + CopyMem ( + &mAvailableAlgoArray[mAvailableAlgoArrayCount], + PcdGetPtr (PcdCpuRngSupportedAlgorithm), + sizeof (EFI_RNG_ALGORITHM) + ); + mAvailableAlgoArrayCount++; + } + + mAvailableAlgoArrayInit =3D TRUE; +} + /** Produces and returns an RNG value using either the default or specifie= d RNG algorithm. =20 @@ -59,18 +93,35 @@ RngGetRNG ( ) { EFI_STATUS Status; + UINTN Index; =20 if ((This =3D=3D NULL) || (RNGValueLength =3D=3D 0) || (RNGValue =3D=3D= NULL)) { return EFI_INVALID_PARAMETER; } =20 + if (!mAvailableAlgoArrayInit) { + RngInitAvailableAlgoArray (); + } + if (RNGAlgorithm =3D=3D NULL) { // // Use the default RNG algorithm if RNGAlgorithm is NULL. // - RNGAlgorithm =3D PcdGetPtr (PcdCpuRngSupportedAlgorithm); + for (Index =3D 0; Index < RNG_AVAILABLE_ALGO_MAX; Index++) { + if (!IsZeroGuid (&mAvailableAlgoArray[Index])) { + RNGAlgorithm =3D &mAvailableAlgoArray[Index]; + goto FoundAlgo; + } + } + + if (Index =3D=3D RNG_AVAILABLE_ALGO_MAX) { + // No algorithm available. + ASSERT (Index !=3D RNG_AVAILABLE_ALGO_MAX); + return EFI_DEVICE_ERROR; + } } =20 +FoundAlgo: if (CompareGuid (RNGAlgorithm, PcdGetPtr (PcdCpuRngSupportedAlgorithm)= )) { Status =3D RngGetBytes (RNGValueLength, RNGValue); return Status; @@ -113,24 +164,34 @@ RngGetInfo ( OUT EFI_RNG_ALGORITHM *RNGAlgorithmList ) { - UINTN RequiredSize; - EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm; - - RequiredSize =3D sizeof (EFI_RNG_ALGORITHM); + UINTN RequiredSize; =20 if ((This =3D=3D NULL) || (RNGAlgorithmListSize =3D=3D NULL)) { return EFI_INVALID_PARAMETER; } =20 + if (!mAvailableAlgoArrayInit) { + RngInitAvailableAlgoArray (); + } + + RequiredSize =3D mAvailableAlgoArrayCount * sizeof (EFI_RNG_ALGORITHM)= ; + + if (RequiredSize =3D=3D 0) { + // No supported algorithms found. + return EFI_UNSUPPORTED; + } + if (*RNGAlgorithmListSize < RequiredSize) { *RNGAlgorithmListSize =3D RequiredSize; return EFI_BUFFER_TOO_SMALL; } =20 - CpuRngSupportedAlgorithm =3D PcdGetPtr (PcdCpuRngSupportedAlgorithm); - - CopyMem (&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof (EFI_R= NG_ALGORITHM)); + if (RNGAlgorithmList =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } =20 + // There is no gap in the array, so copy the block. + CopyMem (RNGAlgorithmList, mAvailableAlgoArray, RequiredSize); *RNGAlgorithmListSize =3D RequiredSize; return EFI_SUCCESS; } --=20 2.25.1