From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) by mx.groups.io with SMTP id smtpd.web11.19679.1669125691683558071 for ; Tue, 22 Nov 2022 06:01:32 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20210112 header.b=g94T865O; spf=pass (domain: gmail.com, ip: 209.85.128.49, mailfrom: pedro.falcato@gmail.com) Received: by mail-wm1-f49.google.com with SMTP id ja4-20020a05600c556400b003cf6e77f89cso1262986wmb.0 for ; Tue, 22 Nov 2022 06:01:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=T6WpHsoKYl2mWzX9Dt6r6vKJhg2KFGPCE0RcJd9XTZ8=; b=g94T865OFNkzC6+6aOlpRTnAwnzH+wWSjkk4hvwTpDutMdcMDAzd4z2DWLPta+9bGH ZZH8W7DEi/fEJO6rmq2FamciK8Uc9DAqMYH8OVycNgis/YvnRb0F5x+XxxS5RcW4FHfI yI6oDzpgeFZU7GTEGVKmUH77Ahj4gviuDUVSfnQsK3EMrwZNnedxF4sFhWf5q0LPVpzO sfcQNLbHUwg1gX8uVWNBb9U6/aluTB3Jx9Q001wTMqg6OW9p9mPHiC182lwIxjj5vc99 j3pT0ImTxft5/ea1XlDr+F+qBUYF5KtewYtnH8FS/PmTZuAX4V5SaijPyjJgyrdeHcQF KEgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=T6WpHsoKYl2mWzX9Dt6r6vKJhg2KFGPCE0RcJd9XTZ8=; b=x5S438FFMiqfH2J/5VqBTzJlkS6dolxDDHm49Vd8Klj/85bNhVS//FZ3TxtXsnommI yj1uPttc8qsqdFeauCAXgEXPAsAPhYYIeoyby28PvuYqR+r8uJ5socdKk5xjv+UkxwqC GbxMRk6FEa7w9PxKbiYFhWZkZl/rA2gejbORxDQQjXuEnznUOO0T0gGc95/zFypmwYY1 2LbaW0B2/bgdRjgAl5GXZ+AAQYWy93kF+/g1MdeXbm5vJvm1AM/JnwSoM5M5fzyEH3G5 eGpoqSSdrAkYSBJQHwm1sVG9dGO39MrmOb7m32Z6BPNqVat7mpk0aP4r2SLYF+xMCRoh i6xA== X-Gm-Message-State: ANoB5plg0nHg53QhX1YvmKoqoEEERyCxJE/4GEjJdZTFxWJH0bHX6apd q9XbO5k+s7m3ucntNb8lSnn9SnjmamZynLsk X-Google-Smtp-Source: AA0mqf4t3Ve8PJlnO3h/Hqq6j/5Q8+/vmyPYq3stq2cB+/PH4zHhLpq6jEvSAsSpAoQ2Yi9NaX3dMw== X-Received: by 2002:a05:600c:3108:b0:3c6:bd12:ac68 with SMTP id g8-20020a05600c310800b003c6bd12ac68mr19847029wmo.123.1669125685241; Tue, 22 Nov 2022 06:01:25 -0800 (PST) Return-Path: Received: from PC-PEDRO-ARCH.lan ([2001:8a0:7280:5801:9441:3dce:686c:bfc7]) by smtp.gmail.com with ESMTPSA id g17-20020a05600c311100b003cf4ec90938sm18590384wmo.21.2022.11.22.06.01.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Nov 2022 06:01:24 -0800 (PST) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Michael D Kinney , Liming Gao , Zhiguang Liu Subject: [PATCH 1/1] MdePkg/BaseRngLib: Add a smoketest for RDRAND and check CPUID Date: Tue, 22 Nov 2022 14:01:21 +0000 Message-Id: <20221122140121.550740-1-pedro.falcato@gmail.com> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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. Signed-off-by: Pedro Falcato Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu --- MdePkg/Library/BaseRngLib/Rand/RdRand.c | 81 ++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c index 070d41e2555f..ce9768955359 100644 --- a/MdePkg/Library/BaseRngLib/Rand/RdRand.c +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c @@ -2,6 +2,7 @@ Random number generator services that uses RdRand instruction access to provide high-quality random numbers. +Copyright (c) 2022, Pedro Falcato. All rights reserved.
Copyright (c) 2021, NUVIA Inc. All rights reserved.
Copyright (c) 2015, Intel Corporation. All rights reserved.
@@ -22,6 +23,70 @@ SPDX-License-Identifier: BSD-2-Clause-Patent STATIC BOOLEAN mRdRandSupported; +// +// Intel SDM says 10 tries is good enough for reliable RDRAND usage. +// We'll double this to 20 just to be safe, since a failure when testing +// makes RDRAND unavailable. +// +#define RDRAND_RETRIES 20 + +#define RDRAND_TEST_TRIES 10 + +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. This testing is quite naive. + // + UINT32 RandomNum; + BOOLEAN HasRandomNum; + UINT8 Idx; + UINT8 TestIteration; + + HasRandomNum = FALSE; + + for (TestIteration = 0; TestIteration < RDRAND_TEST_TRIES; TestIteration++) { + UINT32 Tmp; + // + // 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 (AsmRdRand32 (&Tmp)) { + break; + } + } + + if (Idx == RDRAND_RETRIES) { + DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: Failed to get an RDRAND random number - disabling\n")); + return FALSE; + } + + if (HasRandomNum) { + if (RandomNum != Tmp) { + // + // We got a different number, so take it the RNG works. + // + DEBUG ((DEBUG_INFO, "BaseRngLib/x86: RDRAND test complete.\n")); + return TRUE; + } + } + + RandomNum = Tmp; + HasRandomNum = TRUE; + } + + DEBUG ((DEBUG_ERROR, "BaseRngLib/x86: CPU BUG: RDRAND always returns the same result %x - disabling\n", RandomNum)); + + return FALSE; +} + /** The constructor function checks whether or not RDRAND instruction is supported by the host hardware. @@ -46,10 +111,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; } @@ -68,6 +136,7 @@ ArchGetRandomNumber16 ( OUT UINT16 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand16 (Rand); } @@ -86,6 +155,7 @@ ArchGetRandomNumber32 ( OUT UINT32 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand32 (Rand); } @@ -104,6 +174,7 @@ ArchGetRandomNumber64 ( OUT UINT64 *Rand ) { + ASSERT (mRdRandSupported); return AsmRdRand64 (Rand); } @@ -120,11 +191,5 @@ ArchIsRngSupported ( VOID ) { - /* - Existing software depends on this always returning TRUE, so for - now hard-code it. - - return mRdRandSupported; - */ - return TRUE; + return mRdRandSupported; } -- 2.38.1