Skip to content

Commit

Permalink
NetworkPkg: SECURITY PATCH CVE-2023-45237
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Flickdm authored and mergify[bot] committed May 24, 2024
1 parent a853365 commit 4c4ceb2
Show file tree
Hide file tree
Showing 27 changed files with 410 additions and 83 deletions.
10 changes: 9 additions & 1 deletion NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -189,6 +190,13 @@ Dhcp4CreateService (
{
DHCP_SERVICE *DhcpSb;
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;
}

*Service = NULL;
DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE));
Expand All @@ -203,7 +211,7 @@ Dhcp4CreateService (
DhcpSb->Image = ImageHandle;
InitializeListHead (&DhcpSb->Children);
DhcpSb->DhcpState = Dhcp4Stopped;
DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());
DhcpSb->Xid = Random;
CopyMem (
&DhcpSb->ServiceBinding,
&mDhcp4ServiceBindingTemplate,
Expand Down
11 changes: 9 additions & 2 deletions NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
implementation for Dhcp6 Driver.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -123,6 +123,13 @@ Dhcp6CreateService (
{
DHCP6_SERVICE *Dhcp6Srv;
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;
}

*Service = NULL;
Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));
Expand All @@ -147,7 +154,7 @@ Dhcp6CreateService (
Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;
Dhcp6Srv->Controller = Controller;
Dhcp6Srv->Image = ImageHandle;
Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));
Dhcp6Srv->Xid = (0xffffff & Random);

CopyMem (
&Dhcp6Srv->ServiceBinding,
Expand Down
10 changes: 9 additions & 1 deletion NetworkPkg/DnsDxe/DnsDhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Functions implementation related with DHCPv4/v6 for DNS driver.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -277,6 +278,7 @@ GetDns4ServerFromDhcp4 (
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token;
BOOLEAN IsDone;
UINTN Index;
UINT32 Random;

Image = Instance->Service->ImageHandle;
Controller = Instance->Service->ControllerHandle;
Expand All @@ -292,6 +294,12 @@ GetDns4ServerFromDhcp4 (
Data = NULL;
InterfaceInfo = NULL;

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

ZeroMem ((UINT8 *)ParaList, sizeof (ParaList));

ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA));
Expand Down Expand Up @@ -467,7 +475,7 @@ GetDns4ServerFromDhcp4 (

Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet);

Token.Packet->Dhcp4.Header.Xid = HTONL (NET_RANDOM (NetRandomInitSeed ()));
Token.Packet->Dhcp4.Header.Xid = Random;

Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000);

Expand Down
11 changes: 10 additions & 1 deletion NetworkPkg/DnsDxe/DnsImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
DnsDxe support functions implementation.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -1963,6 +1964,14 @@ ConstructDNSQuery (
NET_FRAGMENT Frag;
DNS_HEADER *DnsHeader;
DNS_QUERY_SECTION *DnsQuery;
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;
}

//
// Messages carried by UDP are restricted to 512 bytes (not counting the IP
Expand All @@ -1977,7 +1986,7 @@ ConstructDNSQuery (
// Fill header
//
DnsHeader = (DNS_HEADER *)Frag.Bulk;
DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed ());
DnsHeader->Identification = (UINT16)Random;
DnsHeader->Flags.Uint16 = 0x0000;
DnsHeader->Flags.Bits.RD = 1;
DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;
Expand Down
10 changes: 9 additions & 1 deletion NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Functions implementation related with DHCPv6 for HTTP boot driver.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -951,6 +952,7 @@ HttpBootDhcp6Sarr (
UINT32 OptCount;
UINT8 Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE];
EFI_STATUS Status;
UINT32 Random;

Dhcp6 = Private->Dhcp6;
ASSERT (Dhcp6 != NULL);
Expand All @@ -961,6 +963,12 @@ HttpBootDhcp6Sarr (
OptCount = HttpBootBuildDhcp6Options (Private, OptList, Buffer);
ASSERT (OptCount > 0);

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

Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));
if (Retransmit == NULL) {
return EFI_OUT_OF_RESOURCES;
Expand All @@ -976,7 +984,7 @@ HttpBootDhcp6Sarr (
Config.IaInfoEvent = NULL;
Config.RapidCommit = FALSE;
Config.ReconfigureAccept = FALSE;
Config.IaDescriptor.IaId = NET_RANDOM (NetRandomInitSeed ());
Config.IaDescriptor.IaId = Random;
Config.IaDescriptor.Type = EFI_DHCP6_IA_TYPE_NA;
Config.SolicitRetransmission = Retransmit;
Retransmit->Irt = 4;
Expand Down
19 changes: 14 additions & 5 deletions NetworkPkg/IScsiDxe/IScsiCHAP.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Configuration.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -576,16 +577,24 @@ IScsiCHAPToSendReq (
//
// CHAP_I=<I>
//
IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);
Status = IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);
if (EFI_ERROR (Status)) {
break;
}

AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier);
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr);
//
// CHAP_C=<C>
//
IScsiGenRandom (
(UINT8 *)AuthData->OutChallenge,
AuthData->Hash->DigestSize
);
Status = IScsiGenRandom (
(UINT8 *)AuthData->OutChallenge,
AuthData->Hash->DigestSize
);
if (EFI_ERROR (Status)) {
break;
}

BinToHexStatus = IScsiBinToHex (
(UINT8 *)AuthData->OutChallenge,
AuthData->Hash->DigestSize,
Expand Down
14 changes: 6 additions & 8 deletions NetworkPkg/IScsiDxe/IScsiMisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Miscellaneous routines for iSCSI driver.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -474,20 +475,17 @@ IScsiNetNtoi (
@param[in, out] Rand The buffer to contain random numbers.
@param[in] RandLength The length of the Rand buffer.
@retval EFI_SUCCESS on success
@retval others on error
**/
VOID
EFI_STATUS
IScsiGenRandom (
IN OUT UINT8 *Rand,
IN UINTN RandLength
)
{
UINT32 Random;

while (RandLength > 0) {
Random = NET_RANDOM (NetRandomInitSeed ());
*Rand++ = (UINT8)(Random);
RandLength--;
}
return PseudoRandom (Rand, RandLength);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion NetworkPkg/IScsiDxe/IScsiMisc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Miscellaneous definitions for iSCSI driver.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -202,8 +203,11 @@ IScsiNetNtoi (
@param[in, out] Rand The buffer to contain random numbers.
@param[in] RandLength The length of the Rand buffer.
@retval EFI_SUCCESS on success
@retval others on error
**/
VOID
EFI_STATUS
IScsiGenRandom (
IN OUT UINT8 *Rand,
IN UINTN RandLength
Expand Down
40 changes: 30 additions & 10 deletions NetworkPkg/Include/Library/NetLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
It provides basic functions for the UEFI network stack.
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
Expand Down Expand Up @@ -539,8 +540,6 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr;
#define TICKS_PER_MS 10000U
#define TICKS_PER_SECOND 10000000U

#define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)

/**
Extract a UINT32 from a byte stream.
Expand Down Expand Up @@ -580,19 +579,40 @@ NetPutUint32 (
);

/**
Initialize a random seed using current time and monotonic count.
Generate a Random output data given a length.
Get current time and monotonic count first. Then initialize a random seed
based on some basic mathematics operation on the hour, day, minute, second,
nanosecond and year of the current time and the monotonic count value.
@param[out] Output - The buffer to store the generated random data.
@param[in] OutputLength - The length of the output buffer.
@return The random seed initialized with current time.
@retval EFI_SUCCESS On Success
@retval EFI_INVALID_PARAMETER Pointer is null or size is zero
@retval EFI_NOT_FOUND RNG protocol not found
@retval Others Error from RngProtocol->GetRNG()
@return Status code
**/
UINT32
EFI_STATUS
EFIAPI
NetRandomInitSeed (
VOID
PseudoRandom (
OUT VOID *Output,
IN UINTN OutputLength
);

/**
Generate a 32-bit pseudo-random number.
@param[out] Output - The buffer to store the generated random number.
@retval EFI_SUCCESS On Success
@retval EFI_NOT_FOUND RNG protocol not found
@retval Others Error from RngProtocol->GetRNG()
@return Status code
**/
EFI_STATUS
EFIAPI
PseudoRandomU32 (
OUT UINT32 *Output
);

#define NET_LIST_USER_STRUCT(Entry, Type, Field) \
Expand Down
10 changes: 9 additions & 1 deletion NetworkPkg/Ip4Dxe/Ip4Driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
The driver binding and service binding protocol for IP4 driver.
Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
Expand Down Expand Up @@ -549,11 +550,18 @@ Ip4DriverBindingStart (
EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;
UINTN Index;
IP4_CONFIG2_DATA_ITEM *DataItem;
UINT32 Random;

IpSb = NULL;
Ip4Cfg2 = 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 Ip4 service binding protocol
//
Expand Down Expand Up @@ -653,7 +661,7 @@ Ip4DriverBindingStart (
//
// Initialize the IP4 ID
//
mIp4Id = (UINT16)NET_RANDOM (NetRandomInitSeed ());
mIp4Id = (UINT16)Random;

return Status;

Expand Down
9 changes: 8 additions & 1 deletion NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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));
Expand Down
Loading

0 comments on commit 4c4ceb2

Please sign in to comment.