NetworkPkg: SECURITY PATCH CVE-2023-45237

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4542

Bug Overview:
PixieFail Bug #9
CVE-2023-45237
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)

Use of a Weak PseudoRandom Number Generator

Change Overview:

Updates all Instances of NET_RANDOM (NetRandomInitSeed ()) to either

>
> EFI_STATUS
> EFIAPI
> PseudoRandomU32 (
>  OUT UINT32  *Output
>  );
>

or (depending on the use case)

>
> EFI_STATUS
> EFIAPI
> PseudoRandom (
>  OUT  VOID   *Output,
>  IN   UINTN  OutputLength
>  );
>

This is because the use of

Example:

The following code snippet PseudoRandomU32 () function is used:

>
> UINT32         Random;
>
> Status = PseudoRandomU32 (&Random);
> if (EFI_ERROR (Status)) {
>   DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n",
__func__, Status));
>   return Status;
> }
>

This also introduces a new PCD to enable/disable the use of the
secure implementation of algorithms for PseudoRandom () and
instead depend on the default implementation. This may be required for
some platforms where the UEFI Spec defined algorithms are not available.

>
> PcdEnforceSecureRngAlgorithms
>

If the platform does not have any one of the UEFI defined
secure RNG algorithms then the driver will assert.

Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>

Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
This commit is contained in:
Doug Flick
2024-05-08 22:56:28 -07:00
committed by mergify[bot]
parent a85336531c
commit 4c4ceb2ceb
27 changed files with 410 additions and 83 deletions

View File

@@ -2276,6 +2276,13 @@ Ip6ConfigInitInstance (
UINTN Index;
UINT16 IfIndex;
IP6_CONFIG_DATA_ITEM *DataItem;
UINT32 Random;
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
@@ -2381,7 +2388,7 @@ Ip6ConfigInitInstance (
// The NV variable is not set, so generate a random IAID, and write down the
// fresh new configuration as the NV variable now.
//
Instance->IaId = NET_RANDOM (NetRandomInitSeed ());
Instance->IaId = Random;
for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) {
Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31));

View File

@@ -3,7 +3,7 @@
Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -316,7 +316,11 @@ Ip6CreateService (
IpSb->CurHopLimit = IP6_HOP_LIMIT;
IpSb->LinkMTU = IP6_MIN_LINK_MTU;
IpSb->BaseReachableTime = IP6_REACHABLE_TIME;
Ip6UpdateReachableTime (IpSb);
Status = Ip6UpdateReachableTime (IpSb);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// RFC4861 RETRANS_TIMER: 1,000 milliseconds
//
@@ -516,11 +520,18 @@ Ip6DriverBindingStart (
EFI_STATUS Status;
EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
IP6_CONFIG_DATA_ITEM *DataItem;
UINT32 Random;
IpSb = NULL;
Ip6Cfg = NULL;
DataItem = NULL;
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
//
// Test for the Ip6 service binding protocol
//
@@ -656,7 +667,7 @@ Ip6DriverBindingStart (
//
// Initialize the IP6 ID
//
mIp6Id = NET_RANDOM (NetRandomInitSeed ());
mIp6Id = Random;
return EFI_SUCCESS;

View File

@@ -2,7 +2,7 @@
Implement IP6 pseudo interface.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -89,6 +89,14 @@ Ip6SetAddress (
IP6_PREFIX_LIST_ENTRY *PrefixEntry;
UINT64 Delay;
IP6_DELAY_JOIN_LIST *DelayNode;
EFI_STATUS Status;
UINT32 Random;
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);
@@ -164,7 +172,7 @@ Ip6SetAddress (
// Thus queue the address to be processed in Duplicate Address Detection module
// after the delay time (in milliseconds).
//
Delay = (UINT64)NET_RANDOM (NetRandomInitSeed ());
Delay = (UINT64)Random;
Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS);
Delay = RShiftU64 (Delay, 32);

View File

@@ -696,7 +696,15 @@ Ip6UpdateDelayTimer (
IN OUT IP6_MLD_GROUP *Group
)
{
UINT32 Delay;
UINT32 Delay;
EFI_STATUS Status;
UINT32 Random;
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
//
// If the Query packet specifies a Maximum Response Delay of zero, perform timer
@@ -715,7 +723,7 @@ Ip6UpdateDelayTimer (
// is less than the remaining value of the running timer.
//
if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) {
Group->DelayTimer = Delay / 4294967295UL * NET_RANDOM (NetRandomInitSeed ());
Group->DelayTimer = Delay / 4294967295UL * Random;
}
return EFI_SUCCESS;

View File

@@ -2,7 +2,7 @@
Implementation of Neighbor Discovery support routines.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -16,17 +16,28 @@ EFI_MAC_ADDRESS mZeroMacAddress;
@param[in, out] IpSb Points to the IP6_SERVICE.
@retval EFI_SUCCESS ReachableTime Updated
@retval others Failed to update ReachableTime
**/
VOID
EFI_STATUS
Ip6UpdateReachableTime (
IN OUT IP6_SERVICE *IpSb
)
{
UINT32 Random;
UINT32 Random;
EFI_STATUS Status;
Random = (NetRandomInitSeed () / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE;
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
Random = (Random / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE;
Random = Random + IP6_MIN_RANDOM_FACTOR_SCALED;
IpSb->ReachableTime = (IpSb->BaseReachableTime * Random) / IP6_RANDOM_FACTOR_SCALE;
return EFI_SUCCESS;
}
/**
@@ -972,10 +983,17 @@ Ip6InitDADProcess (
IP6_SERVICE *IpSb;
EFI_STATUS Status;
UINT32 MaxDelayTick;
UINT32 Random;
NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE);
ASSERT (AddressInfo != NULL);
Status = PseudoRandomU32 (&Random);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
return Status;
}
//
// Do nothing if we have already started DAD on the address.
//
@@ -1014,7 +1032,7 @@ Ip6InitDADProcess (
Entry->Transmit = 0;
Entry->Receive = 0;
MaxDelayTick = IP6_MAX_RTR_SOLICITATION_DELAY / IP6_TIMER_INTERVAL_IN_MS;
Entry->RetransTick = (MaxDelayTick * ((NET_RANDOM (NetRandomInitSeed ()) % 5) + 1)) / 5;
Entry->RetransTick = (MaxDelayTick * ((Random % 5) + 1)) / 5;
Entry->AddressInfo = AddressInfo;
Entry->Callback = Callback;
Entry->Context = Context;
@@ -2078,7 +2096,10 @@ Ip6ProcessRouterAdvertise (
// in BaseReachableTime and recompute a ReachableTime.
//
IpSb->BaseReachableTime = ReachableTime;
Ip6UpdateReachableTime (IpSb);
Status = Ip6UpdateReachableTime (IpSb);
if (EFI_ERROR (Status)) {
goto Exit;
}
}
if (RetransTimer != 0) {

View File

@@ -2,7 +2,7 @@
Definition of Neighbor Discovery support routines.
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -780,10 +780,10 @@ Ip6OnArpResolved (
/**
Update the ReachableTime in IP6 service binding instance data, in milliseconds.
@param[in, out] IpSb Points to the IP6_SERVICE.
@retval EFI_SUCCESS ReachableTime Updated
@retval others Failed to update ReachableTime
**/
VOID
EFI_STATUS
Ip6UpdateReachableTime (
IN OUT IP6_SERVICE *IpSb
);