edk2/edk2-MdePkg-BaseRngLib-Add-a-smoketest-for-RDRAND-and-che.patch
Miroslav Rezanina 8e51a8153a * Wed Jul 03 2024 Miroslav Rezanina <mrezanin@redhat.com> - 20220126gitbb1bba3d77-13.el8_10.1
- edk2-MdeModulePkg-Change-use-of-EFI_D_-to-DEBUG_.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-Apply-uncrustify-changes.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-NetworkPkg-Apply-uncrustify-changes.p2.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Rename-RdRandGenerateEntropy-to-g.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Remove-ArchGetSupportedRngAlgorit.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Documentation-include-parameter-c.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Check-before-advertising-Cpu-Rng-.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Add-AArch64-RawAlgorithm-support-.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Add-debug-warning-for-NULL-PcdCpu.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Rename-AArch64-RngDxe.c.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Add-Arm-support-of-RngDxe.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Correctly-update-mAvailableAlgoAr.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Conditionally-install-EFI_RNG_PRO.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdeModulePkg-Duplicate-BaseRngLibTimerLib-to-MdeModu.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-Add-deprecated-warning-to-BaseRngLibTimer.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-SecurityPkg.dec-Move-PcdCpuRngSupportedA.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-DxeRngLib-Request-raw-algorithm-instead-of-de.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-Rng-Add-GUID-to-describe-Arm-Rndr-Rng-algorit.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdeModulePkg-Rng-Add-GUID-to-describe-unsafe-Rng-alg.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-Rng-Add-GetRngGuid-to-RngLib.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Use-GetRngGuid-when-probing-RngLi.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-Simplify-Rng-algorithm-selection-.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-NetworkPkg-SECURITY-PATCH-CVE-2023-45237.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-BaseRngLib-Add-a-smoketest-for-RDRAND-and-che.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-SecurityPkg-RngDxe-add-rng-test.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-OvmfPkg-wire-up-RngDxe.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-CryptoPkg-Test-call-ProcessLibraryConstructorList.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-MdePkg-X86UnitTestHost-set-rdrand-cpuid-bit.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- edk2-NetworkPkg-TcpDxe-Fixed-system-stuck-on-PXE-boot-flo.patch [RHEL-21854 RHEL-21856 RHEL-40099]
- Resolves: RHEL-21854
  (CVE-2023-45236 edk2: Predictable TCP Initial Sequence Numbers [rhel-8])
- Resolves: RHEL-21856
  (CVE-2023-45237 edk2: Use of a Weak PseudoRandom Number Generator [rhel-8])
- Resolves: RHEL-40099
  (CVE-2024-1298 edk2: Temporary DoS vulnerability [rhel-8.10.z])
2024-07-03 08:35:29 -04:00

214 lines
6.0 KiB
Diff

From 1d4b6d489cb919faa3ad67a3ae53fe26c4cd0a75 Mon Sep 17 00:00:00 2001
From: Jon Maloy <jmaloy@redhat.com>
Date: Thu, 20 Jun 2024 10:32:29 -0400
Subject: [PATCH 25/31] MdePkg/BaseRngLib: Add a smoketest for RDRAND and check
CPUID
RH-Author: Jon Maloy <jmaloy@redhat.com>
RH-MergeRequest: 77: UINT32 overflow in S3 ResumeCount and Pixiefail fixes
RH-Jira: RHEL-21854 RHEL-21856 RHEL-40099
RH-Acked-by: Gerd Hoffmann <None>
RH-Commit: [25/31] 11804d6f86a644ae2c3dcad89c633ad63b794d3f
JIRA: https://issues.redhat.com/browse/RHEL-21856
Upstream: Merged
CVE: CVE-2023-45237
commit c3a8ca7b54a9fd17acdf16c6282a92cc989fa92a
Author: Pedro Falcato <pedro.falcato@gmail.com>
Date: Tue Nov 22 22:31:03 2022 +0000
MdePkg/BaseRngLib: Add a smoketest for RDRAND and check CPUID
RDRAND has notoriously been broken many times over its lifespan.
Add a smoketest to RDRAND, in order to better sniff out potential
security concerns.
Also add a proper CPUID test in order to support older CPUs which may
not have it; it was previously being tested but then promptly ignored.
Testing algorithm inspired by linux's arch/x86/kernel/cpu/rdrand.c
:x86_init_rdrand() per commit 049f9ae9..
Many thanks to Jason Donenfeld for relicensing his linux RDRAND detection
code to MIT and the public domain.
>On Tue, Nov 22, 2022 at 2:21 PM Jason A. Donenfeld <Jason@zx2c4.com> wrote:
<..>
> I (re)wrote that function in Linux. I hereby relicense it as MIT, and
> also place it into public domain. Do with it what you will now.
>
> Jason
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4163
Signed-off-by: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Jon Maloy <jmaloy@gmail.com>
---
MdePkg/Library/BaseRngLib/Rand/RdRand.c | 99 +++++++++++++++++++++++--
1 file changed, 91 insertions(+), 8 deletions(-)
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
index aee8ea04e8..7132ab0efd 100644
--- a/MdePkg/Library/BaseRngLib/Rand/RdRand.c
+++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
@@ -3,6 +3,7 @@
to provide high-quality random numbers.
Copyright (c) 2023, Arm Limited. All rights reserved.<BR>
+Copyright (c) 2022, Pedro Falcato. All rights reserved.<BR>
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
@@ -25,6 +26,88 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
STATIC BOOLEAN mRdRandSupported;
+//
+// Intel SDM says 10 tries is good enough for reliable RDRAND usage.
+//
+#define RDRAND_RETRIES 10
+
+#define RDRAND_TEST_SAMPLES 8
+
+#define RDRAND_MIN_CHANGE 5
+
+//
+// Add a define for native-word RDRAND, just for the test.
+//
+#ifdef MDE_CPU_X64
+#define ASM_RDRAND AsmRdRand64
+#else
+#define ASM_RDRAND AsmRdRand32
+#endif
+
+/**
+ Tests RDRAND for broken implementations.
+
+ @retval TRUE RDRAND is reliable (and hopefully safe).
+ @retval FALSE RDRAND is unreliable and should be disabled, despite CPUID.
+
+**/
+STATIC
+BOOLEAN
+TestRdRand (
+ VOID
+ )
+{
+ //
+ // Test for notoriously broken rdrand implementations that always return the same
+ // value, like the Zen 3 uarch (all-1s) or other several AMD families on suspend/resume (also all-1s).
+ // Note that this should be expanded to extensively test for other sorts of possible errata.
+ //
+
+ //
+ // Our algorithm samples rdrand $RDRAND_TEST_SAMPLES times and expects
+ // a different result $RDRAND_MIN_CHANGE times for reliable RDRAND usage.
+ //
+ UINTN Prev;
+ UINT8 Idx;
+ UINT8 TestIteration;
+ UINT32 Changed;
+
+ Changed = 0;
+
+ for (TestIteration = 0; TestIteration < RDRAND_TEST_SAMPLES; TestIteration++) {
+ UINTN Sample;
+ //
+ // Note: We use a retry loop for rdrand. Normal users get this in BaseRng.c
+ // Any failure to get a random number will assume RDRAND does not work.
+ //
+ for (Idx = 0; Idx < RDRAND_RETRIES; Idx++) {
+ if (ASM_RDRAND (&Sample)) {
+ break;
+ }
+ }
+
+ if (Idx == RDRAND_RETRIES) {
+ DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: Failed to get an RDRAND random number - disabling\n"));
+ return FALSE;
+ }
+
+ if (TestIteration != 0) {
+ Changed += Sample != Prev;
+ }
+
+ Prev = Sample;
+ }
+
+ if (Changed < RDRAND_MIN_CHANGE) {
+ DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: RDRAND not reliable - disabling\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#undef ASM_RDRAND
+
/**
The constructor function checks whether or not RDRAND instruction is supported
by the host hardware.
@@ -49,10 +132,13 @@ BaseRngLibConstructor (
// CPUID. A value of 1 indicates that processor support RDRAND instruction.
//
AsmCpuid (1, 0, 0, &RegEcx, 0);
- ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);
+ if (mRdRandSupported) {
+ mRdRandSupported = TestRdRand ();
+ }
+
return EFI_SUCCESS;
}
@@ -71,6 +157,7 @@ ArchGetRandomNumber16 (
OUT UINT16 *Rand
)
{
+ ASSERT (mRdRandSupported);
return AsmRdRand16 (Rand);
}
@@ -89,6 +176,7 @@ ArchGetRandomNumber32 (
OUT UINT32 *Rand
)
{
+ ASSERT (mRdRandSupported);
return AsmRdRand32 (Rand);
}
@@ -107,6 +195,7 @@ ArchGetRandomNumber64 (
OUT UINT64 *Rand
)
{
+ ASSERT (mRdRandSupported);
return AsmRdRand64 (Rand);
}
@@ -123,13 +212,7 @@ ArchIsRngSupported (
VOID
)
{
- /*
- Existing software depends on this always returning TRUE, so for
- now hard-code it.
-
- return mRdRandSupported;
- */
- return TRUE;
+ return mRdRandSupported;
}
/**
--
2.39.3