--- /dev/null
+From 4c4ceb2ceb80c42fd5545b2a4bd80321f07f4345 Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Wed, 8 May 2024 22:56:28 -0700
+Subject: [PATCH] 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>
+
+CVE: CVE-2023-45237
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/4c4ceb2ceb80c42fd5545b2a4bd80321f07f4345]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c | 10 +-
+ NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c | 11 +-
+ NetworkPkg/DnsDxe/DnsDhcp.c | 10 +-
+ NetworkPkg/DnsDxe/DnsImpl.c | 11 +-
+ NetworkPkg/HttpBootDxe/HttpBootDhcp6.c | 10 +-
+ NetworkPkg/IScsiDxe/IScsiCHAP.c | 19 ++-
+ NetworkPkg/IScsiDxe/IScsiMisc.c | 14 +--
+ NetworkPkg/IScsiDxe/IScsiMisc.h | 6 +-
+ NetworkPkg/Include/Library/NetLib.h | 40 +++++--
+ NetworkPkg/Ip4Dxe/Ip4Driver.c | 10 +-
+ NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 9 +-
+ NetworkPkg/Ip6Dxe/Ip6Driver.c | 17 ++-
+ NetworkPkg/Ip6Dxe/Ip6If.c | 12 +-
+ NetworkPkg/Ip6Dxe/Ip6Mld.c | 12 +-
+ NetworkPkg/Ip6Dxe/Ip6Nd.c | 33 +++++-
+ NetworkPkg/Ip6Dxe/Ip6Nd.h | 8 +-
+ NetworkPkg/Library/DxeNetLib/DxeNetLib.c | 130 ++++++++++++++++++---
+ NetworkPkg/Library/DxeNetLib/DxeNetLib.inf | 14 ++-
+ NetworkPkg/NetworkPkg.dec | 7 ++
+ NetworkPkg/SecurityFixes.yaml | 39 +++++++
+ NetworkPkg/TcpDxe/TcpDriver.c | 15 ++-
+ NetworkPkg/TcpDxe/TcpDxe.inf | 3 +
+ NetworkPkg/Udp4Dxe/Udp4Driver.c | 10 +-
+ NetworkPkg/Udp6Dxe/Udp6Driver.c | 11 +-
+ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c | 9 +-
+ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 11 +-
+ NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c | 12 +-
+ 27 files changed, 410 insertions(+), 83 deletions(-)
+
+diff --git a/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c b/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c
+index 8c37e93be3..892caee368 100644
+--- a/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c
++++ b/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c
+@@ -1,6 +1,7 @@
+ /** @file\r
+ \r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -189,6 +190,13 @@ Dhcp4CreateService (
+ {\r
+ DHCP_SERVICE *DhcpSb;\r
+ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ *Service = NULL;\r
+ DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE));\r
+@@ -203,7 +211,7 @@ Dhcp4CreateService (
+ DhcpSb->Image = ImageHandle;\r
+ InitializeListHead (&DhcpSb->Children);\r
+ DhcpSb->DhcpState = Dhcp4Stopped;\r
+- DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());\r
++ DhcpSb->Xid = Random;\r
+ CopyMem (\r
+ &DhcpSb->ServiceBinding,\r
+ &mDhcp4ServiceBindingTemplate,\r
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+index b591a4605b..e7f2787a98 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+@@ -3,7 +3,7 @@
+ implementation for Dhcp6 Driver.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -123,6 +123,13 @@ Dhcp6CreateService (
+ {\r
+ DHCP6_SERVICE *Dhcp6Srv;\r
+ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ *Service = NULL;\r
+ Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));\r
+@@ -147,7 +154,7 @@ Dhcp6CreateService (
+ Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;\r
+ Dhcp6Srv->Controller = Controller;\r
+ Dhcp6Srv->Image = ImageHandle;\r
+- Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));\r
++ Dhcp6Srv->Xid = (0xffffff & Random);\r
+ \r
+ CopyMem (\r
+ &Dhcp6Srv->ServiceBinding,\r
+diff --git a/NetworkPkg/DnsDxe/DnsDhcp.c b/NetworkPkg/DnsDxe/DnsDhcp.c
+index 933565a32d..9eb3c1d2d8 100644
+--- a/NetworkPkg/DnsDxe/DnsDhcp.c
++++ b/NetworkPkg/DnsDxe/DnsDhcp.c
+@@ -2,6 +2,7 @@
+ Functions implementation related with DHCPv4/v6 for DNS driver.\r
+ \r
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -277,6 +278,7 @@ GetDns4ServerFromDhcp4 (
+ EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token;\r
+ BOOLEAN IsDone;\r
+ UINTN Index;\r
++ UINT32 Random;\r
+ \r
+ Image = Instance->Service->ImageHandle;\r
+ Controller = Instance->Service->ControllerHandle;\r
+@@ -292,6 +294,12 @@ GetDns4ServerFromDhcp4 (
+ Data = NULL;\r
+ InterfaceInfo = NULL;\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ ZeroMem ((UINT8 *)ParaList, sizeof (ParaList));\r
+ \r
+ ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA));\r
+@@ -467,7 +475,7 @@ GetDns4ServerFromDhcp4 (
+ \r
+ Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet);\r
+ \r
+- Token.Packet->Dhcp4.Header.Xid = HTONL (NET_RANDOM (NetRandomInitSeed ()));\r
++ Token.Packet->Dhcp4.Header.Xid = Random;\r
+ \r
+ Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000);\r
+ \r
+diff --git a/NetworkPkg/DnsDxe/DnsImpl.c b/NetworkPkg/DnsDxe/DnsImpl.c
+index d311812800..c2629bb8df 100644
+--- a/NetworkPkg/DnsDxe/DnsImpl.c
++++ b/NetworkPkg/DnsDxe/DnsImpl.c
+@@ -2,6 +2,7 @@
+ DnsDxe support functions implementation.\r
+ \r
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -1963,6 +1964,14 @@ ConstructDNSQuery (
+ NET_FRAGMENT Frag;\r
+ DNS_HEADER *DnsHeader;\r
+ DNS_QUERY_SECTION *DnsQuery;\r
++ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ //\r
+ // Messages carried by UDP are restricted to 512 bytes (not counting the IP\r
+@@ -1977,7 +1986,7 @@ ConstructDNSQuery (
+ // Fill header\r
+ //\r
+ DnsHeader = (DNS_HEADER *)Frag.Bulk;\r
+- DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed ());\r
++ DnsHeader->Identification = (UINT16)Random;\r
+ DnsHeader->Flags.Uint16 = 0x0000;\r
+ DnsHeader->Flags.Bits.RD = 1;\r
+ DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;\r
+diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
+index b22cef4ff5..f964515b0f 100644
+--- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
++++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
+@@ -2,6 +2,7 @@
+ Functions implementation related with DHCPv6 for HTTP boot driver.\r
+ \r
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -951,6 +952,7 @@ HttpBootDhcp6Sarr (
+ UINT32 OptCount;\r
+ UINT8 Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE];\r
+ EFI_STATUS Status;\r
++ UINT32 Random;\r
+ \r
+ Dhcp6 = Private->Dhcp6;\r
+ ASSERT (Dhcp6 != NULL);\r
+@@ -961,6 +963,12 @@ HttpBootDhcp6Sarr (
+ OptCount = HttpBootBuildDhcp6Options (Private, OptList, Buffer);\r
+ ASSERT (OptCount > 0);\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));\r
+ if (Retransmit == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+@@ -976,7 +984,7 @@ HttpBootDhcp6Sarr (
+ Config.IaInfoEvent = NULL;\r
+ Config.RapidCommit = FALSE;\r
+ Config.ReconfigureAccept = FALSE;\r
+- Config.IaDescriptor.IaId = NET_RANDOM (NetRandomInitSeed ());\r
++ Config.IaDescriptor.IaId = Random;\r
+ Config.IaDescriptor.Type = EFI_DHCP6_IA_TYPE_NA;\r
+ Config.SolicitRetransmission = Retransmit;\r
+ Retransmit->Irt = 4;\r
+diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
+index b507f11cd4..bebb1ac29b 100644
+--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
++++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
+@@ -3,6 +3,7 @@
+ Configuration.\r
+ \r
+ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -576,16 +577,24 @@ IScsiCHAPToSendReq (
+ //\r
+ // CHAP_I=<I>\r
+ //\r
+- IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);\r
++ Status = IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);\r
++ if (EFI_ERROR (Status)) {\r
++ break;\r
++ }\r
++\r
+ AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier);\r
+ IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr);\r
+ //\r
+ // CHAP_C=<C>\r
+ //\r
+- IScsiGenRandom (\r
+- (UINT8 *)AuthData->OutChallenge,\r
+- AuthData->Hash->DigestSize\r
+- );\r
++ Status = IScsiGenRandom (\r
++ (UINT8 *)AuthData->OutChallenge,\r
++ AuthData->Hash->DigestSize\r
++ );\r
++ if (EFI_ERROR (Status)) {\r
++ break;\r
++ }\r
++\r
+ BinToHexStatus = IScsiBinToHex (\r
+ (UINT8 *)AuthData->OutChallenge,\r
+ AuthData->Hash->DigestSize,\r
+diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
+index b3ea90158f..cd77f1a13e 100644
+--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
++++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
+@@ -2,6 +2,7 @@
+ Miscellaneous routines for iSCSI driver.\r
+ \r
+ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -474,20 +475,17 @@ IScsiNetNtoi (
+ @param[in, out] Rand The buffer to contain random numbers.\r
+ @param[in] RandLength The length of the Rand buffer.\r
+ \r
++ @retval EFI_SUCCESS on success\r
++ @retval others on error\r
++\r
+ **/\r
+-VOID\r
++EFI_STATUS\r
+ IScsiGenRandom (\r
+ IN OUT UINT8 *Rand,\r
+ IN UINTN RandLength\r
+ )\r
+ {\r
+- UINT32 Random;\r
+-\r
+- while (RandLength > 0) {\r
+- Random = NET_RANDOM (NetRandomInitSeed ());\r
+- *Rand++ = (UINT8)(Random);\r
+- RandLength--;\r
+- }\r
++ return PseudoRandom (Rand, RandLength);\r
+ }\r
+ \r
+ /**\r
+diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
+index a951eee70e..91b2cd2261 100644
+--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
++++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
+@@ -2,6 +2,7 @@
+ Miscellaneous definitions for iSCSI driver.\r
+ \r
+ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -202,8 +203,11 @@ IScsiNetNtoi (
+ @param[in, out] Rand The buffer to contain random numbers.\r
+ @param[in] RandLength The length of the Rand buffer.\r
+ \r
++ @retval EFI_SUCCESS on success\r
++ @retval others on error\r
++\r
+ **/\r
+-VOID\r
++EFI_STATUS\r
+ IScsiGenRandom (\r
+ IN OUT UINT8 *Rand,\r
+ IN UINTN RandLength\r
+diff --git a/NetworkPkg/Include/Library/NetLib.h b/NetworkPkg/Include/Library/NetLib.h
+index 8c0e62b388..e8108b79db 100644
+--- a/NetworkPkg/Include/Library/NetLib.h
++++ b/NetworkPkg/Include/Library/NetLib.h
+@@ -3,6 +3,7 @@
+ It provides basic functions for the UEFI network stack.\r
+ \r
+ Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -539,8 +540,6 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr;
+ #define TICKS_PER_MS 10000U\r
+ #define TICKS_PER_SECOND 10000000U\r
+ \r
+-#define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)\r
+-\r
+ /**\r
+ Extract a UINT32 from a byte stream.\r
+ \r
+@@ -580,19 +579,40 @@ NetPutUint32 (
+ );\r
+ \r
+ /**\r
+- Initialize a random seed using current time and monotonic count.\r
++ Generate a Random output data given a length.\r
+ \r
+- Get current time and monotonic count first. Then initialize a random seed\r
+- based on some basic mathematics operation on the hour, day, minute, second,\r
+- nanosecond and year of the current time and the monotonic count value.\r
++ @param[out] Output - The buffer to store the generated random data.\r
++ @param[in] OutputLength - The length of the output buffer.\r
+ \r
+- @return The random seed initialized with current time.\r
++ @retval EFI_SUCCESS On Success\r
++ @retval EFI_INVALID_PARAMETER Pointer is null or size is zero\r
++ @retval EFI_NOT_FOUND RNG protocol not found\r
++ @retval Others Error from RngProtocol->GetRNG()\r
+ \r
++ @return Status code\r
+ **/\r
+-UINT32\r
++EFI_STATUS\r
+ EFIAPI\r
+-NetRandomInitSeed (\r
+- VOID\r
++PseudoRandom (\r
++ OUT VOID *Output,\r
++ IN UINTN OutputLength\r
++ );\r
++\r
++/**\r
++ Generate a 32-bit pseudo-random number.\r
++\r
++ @param[out] Output - The buffer to store the generated random number.\r
++\r
++ @retval EFI_SUCCESS On Success\r
++ @retval EFI_NOT_FOUND RNG protocol not found\r
++ @retval Others Error from RngProtocol->GetRNG()\r
++\r
++ @return Status code\r
++**/\r
++EFI_STATUS\r
++EFIAPI\r
++PseudoRandomU32 (\r
++ OUT UINT32 *Output\r
+ );\r
+ \r
+ #define NET_LIST_USER_STRUCT(Entry, Type, Field) \\r
+diff --git a/NetworkPkg/Ip4Dxe/Ip4Driver.c b/NetworkPkg/Ip4Dxe/Ip4Driver.c
+index ec483ff01f..683423f38d 100644
+--- a/NetworkPkg/Ip4Dxe/Ip4Driver.c
++++ b/NetworkPkg/Ip4Dxe/Ip4Driver.c
+@@ -2,6 +2,7 @@
+ The driver binding and service binding protocol for IP4 driver.\r
+ \r
+ Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+ \r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+@@ -549,11 +550,18 @@ Ip4DriverBindingStart (
+ EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;\r
+ UINTN Index;\r
+ IP4_CONFIG2_DATA_ITEM *DataItem;\r
++ UINT32 Random;\r
+ \r
+ IpSb = NULL;\r
+ Ip4Cfg2 = NULL;\r
+ DataItem = NULL;\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ //\r
+ // Test for the Ip4 service binding protocol\r
+ //\r
+@@ -653,7 +661,7 @@ Ip4DriverBindingStart (
+ //\r
+ // Initialize the IP4 ID\r
+ //\r
+- mIp4Id = (UINT16)NET_RANDOM (NetRandomInitSeed ());\r
++ mIp4Id = (UINT16)Random;\r
+ \r
+ return Status;\r
+ \r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
+index 70e232ce6c..4c1354d26c 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
++++ b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
+@@ -2276,6 +2276,13 @@ Ip6ConfigInitInstance (
+ UINTN Index;\r
+ UINT16 IfIndex;\r
+ IP6_CONFIG_DATA_ITEM *DataItem;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
+ \r
+@@ -2381,7 +2388,7 @@ Ip6ConfigInitInstance (
+ // The NV variable is not set, so generate a random IAID, and write down the\r
+ // fresh new configuration as the NV variable now.\r
+ //\r
+- Instance->IaId = NET_RANDOM (NetRandomInitSeed ());\r
++ Instance->IaId = Random;\r
+ \r
+ for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) {\r
+ Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31));\r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.c b/NetworkPkg/Ip6Dxe/Ip6Driver.c
+index b483a7d136..cbe011dad4 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6Driver.c
++++ b/NetworkPkg/Ip6Dxe/Ip6Driver.c
+@@ -3,7 +3,7 @@
+ \r
+ Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -316,7 +316,11 @@ Ip6CreateService (
+ IpSb->CurHopLimit = IP6_HOP_LIMIT;\r
+ IpSb->LinkMTU = IP6_MIN_LINK_MTU;\r
+ IpSb->BaseReachableTime = IP6_REACHABLE_TIME;\r
+- Ip6UpdateReachableTime (IpSb);\r
++ Status = Ip6UpdateReachableTime (IpSb);\r
++ if (EFI_ERROR (Status)) {\r
++ goto ON_ERROR;\r
++ }\r
++\r
+ //\r
+ // RFC4861 RETRANS_TIMER: 1,000 milliseconds\r
+ //\r
+@@ -516,11 +520,18 @@ Ip6DriverBindingStart (
+ EFI_STATUS Status;\r
+ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;\r
+ IP6_CONFIG_DATA_ITEM *DataItem;\r
++ UINT32 Random;\r
+ \r
+ IpSb = NULL;\r
+ Ip6Cfg = NULL;\r
+ DataItem = NULL;\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ //\r
+ // Test for the Ip6 service binding protocol\r
+ //\r
+@@ -656,7 +667,7 @@ Ip6DriverBindingStart (
+ //\r
+ // Initialize the IP6 ID\r
+ //\r
+- mIp6Id = NET_RANDOM (NetRandomInitSeed ());\r
++ mIp6Id = Random;\r
+ \r
+ return EFI_SUCCESS;\r
+ \r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6If.c b/NetworkPkg/Ip6Dxe/Ip6If.c
+index 4629c05f25..f3d11c4d21 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6If.c
++++ b/NetworkPkg/Ip6Dxe/Ip6If.c
+@@ -2,7 +2,7 @@
+ Implement IP6 pseudo interface.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -89,6 +89,14 @@ Ip6SetAddress (
+ IP6_PREFIX_LIST_ENTRY *PrefixEntry;\r
+ UINT64 Delay;\r
+ IP6_DELAY_JOIN_LIST *DelayNode;\r
++ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);\r
+ \r
+@@ -164,7 +172,7 @@ Ip6SetAddress (
+ // Thus queue the address to be processed in Duplicate Address Detection module\r
+ // after the delay time (in milliseconds).\r
+ //\r
+- Delay = (UINT64)NET_RANDOM (NetRandomInitSeed ());\r
++ Delay = (UINT64)Random;\r
+ Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS);\r
+ Delay = RShiftU64 (Delay, 32);\r
+ \r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6Mld.c b/NetworkPkg/Ip6Dxe/Ip6Mld.c
+index e6b2b653e2..498a118543 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6Mld.c
++++ b/NetworkPkg/Ip6Dxe/Ip6Mld.c
+@@ -696,7 +696,15 @@ Ip6UpdateDelayTimer (
+ IN OUT IP6_MLD_GROUP *Group\r
+ )\r
+ {\r
+- UINT32 Delay;\r
++ UINT32 Delay;\r
++ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ //\r
+ // If the Query packet specifies a Maximum Response Delay of zero, perform timer\r
+@@ -715,7 +723,7 @@ Ip6UpdateDelayTimer (
+ // is less than the remaining value of the running timer.\r
+ //\r
+ if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) {\r
+- Group->DelayTimer = Delay / 4294967295UL * NET_RANDOM (NetRandomInitSeed ());\r
++ Group->DelayTimer = Delay / 4294967295UL * Random;\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c
+index c10c7017f8..72aa45c10f 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6Nd.c
++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c
+@@ -2,7 +2,7 @@
+ Implementation of Neighbor Discovery support routines.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -16,17 +16,28 @@ EFI_MAC_ADDRESS mZeroMacAddress;
+ \r
+ @param[in, out] IpSb Points to the IP6_SERVICE.\r
+ \r
++ @retval EFI_SUCCESS ReachableTime Updated\r
++ @retval others Failed to update ReachableTime\r
+ **/\r
+-VOID\r
++EFI_STATUS\r
+ Ip6UpdateReachableTime (\r
+ IN OUT IP6_SERVICE *IpSb\r
+ )\r
+ {\r
+- UINT32 Random;\r
++ UINT32 Random;\r
++ EFI_STATUS Status;\r
+ \r
+- Random = (NetRandomInitSeed () / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE;\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
++ Random = (Random / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE;\r
+ Random = Random + IP6_MIN_RANDOM_FACTOR_SCALED;\r
+ IpSb->ReachableTime = (IpSb->BaseReachableTime * Random) / IP6_RANDOM_FACTOR_SCALE;\r
++\r
++ return EFI_SUCCESS;\r
+ }\r
+ \r
+ /**\r
+@@ -972,10 +983,17 @@ Ip6InitDADProcess (
+ IP6_SERVICE *IpSb;\r
+ EFI_STATUS Status;\r
+ UINT32 MaxDelayTick;\r
++ UINT32 Random;\r
+ \r
+ NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE);\r
+ ASSERT (AddressInfo != NULL);\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ //\r
+ // Do nothing if we have already started DAD on the address.\r
+ //\r
+@@ -1014,7 +1032,7 @@ Ip6InitDADProcess (
+ Entry->Transmit = 0;\r
+ Entry->Receive = 0;\r
+ MaxDelayTick = IP6_MAX_RTR_SOLICITATION_DELAY / IP6_TIMER_INTERVAL_IN_MS;\r
+- Entry->RetransTick = (MaxDelayTick * ((NET_RANDOM (NetRandomInitSeed ()) % 5) + 1)) / 5;\r
++ Entry->RetransTick = (MaxDelayTick * ((Random % 5) + 1)) / 5;\r
+ Entry->AddressInfo = AddressInfo;\r
+ Entry->Callback = Callback;\r
+ Entry->Context = Context;\r
+@@ -2078,7 +2096,10 @@ Ip6ProcessRouterAdvertise (
+ // in BaseReachableTime and recompute a ReachableTime.\r
+ //\r
+ IpSb->BaseReachableTime = ReachableTime;\r
+- Ip6UpdateReachableTime (IpSb);\r
++ Status = Ip6UpdateReachableTime (IpSb);\r
++ if (EFI_ERROR (Status)) {\r
++ goto Exit;\r
++ }\r
+ }\r
+ \r
+ if (RetransTimer != 0) {\r
+diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h
+index bf64e9114e..5795e23c7d 100644
+--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h
++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h
+@@ -2,7 +2,7 @@
+ Definition of Neighbor Discovery support routines.\r
+ \r
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -780,10 +780,10 @@ Ip6OnArpResolved (
+ /**\r
+ Update the ReachableTime in IP6 service binding instance data, in milliseconds.\r
+ \r
+- @param[in, out] IpSb Points to the IP6_SERVICE.\r
+-\r
++ @retval EFI_SUCCESS ReachableTime Updated\r
++ @retval others Failed to update ReachableTime\r
+ **/\r
+-VOID\r
++EFI_STATUS\r
+ Ip6UpdateReachableTime (\r
+ IN OUT IP6_SERVICE *IpSb\r
+ );\r
+diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
+index fd4a9e15a8..01c13c08d2 100644
+--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
+@@ -3,6 +3,7 @@
+ \r
+ Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ **/\r
+ \r
+@@ -31,6 +32,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
+ #include <Library/DevicePathLib.h>\r
+ #include <Library/PrintLib.h>\r
+ #include <Library/UefiLib.h>\r
++#include <Protocol/Rng.h>\r
+ \r
+ #define NIC_ITEM_CONFIG_SIZE (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE)\r
+ #define DEFAULT_ZERO_START ((UINTN) ~0)\r
+@@ -127,6 +129,25 @@ GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = {
+ 0\r
+ };\r
+ \r
++//\r
++// These represent UEFI SPEC defined algorithms that should be supported by\r
++// the RNG protocol and are generally considered secure.\r
++//\r
++// The order of the algorithms in this array is important. This order is the order\r
++// in which the algorithms will be tried by the RNG protocol.\r
++// If your platform needs to use a specific algorithm for the random number generator,\r
++// then you should place that algorithm first in the array.\r
++//\r
++GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID *mSecureHashAlgorithms[] = {\r
++ &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256\r
++ &gEfiRngAlgorithmSp80090Hmac256Guid, // SP800-90A DRBG HMAC using SHA-256\r
++ &gEfiRngAlgorithmSp80090Hash256Guid, // SP800-90A DRBG Hash using SHA-256\r
++ &gEfiRngAlgorithmArmRndr, // unspecified SP800-90A DRBG via ARM RNDR register\r
++ &gEfiRngAlgorithmRaw, // Raw data from NRBG (or TRNG)\r
++};\r
++\r
++#define SECURE_HASH_ALGORITHMS_SIZE (sizeof (mSecureHashAlgorithms) / sizeof (EFI_GUID *))\r
++\r
+ /**\r
+ Locate the handles that support SNP, then open one of them\r
+ to send the syslog packets. The caller isn't required to close\r
+@@ -884,34 +905,107 @@ Ip6Swap128 (
+ }\r
+ \r
+ /**\r
+- Initialize a random seed using current time and monotonic count.\r
++ Generate a Random output data given a length.\r
+ \r
+- Get current time and monotonic count first. Then initialize a random seed\r
+- based on some basic mathematics operation on the hour, day, minute, second,\r
+- nanosecond and year of the current time and the monotonic count value.\r
++ @param[out] Output - The buffer to store the generated random data.\r
++ @param[in] OutputLength - The length of the output buffer.\r
+ \r
+- @return The random seed initialized with current time.\r
++ @retval EFI_SUCCESS On Success\r
++ @retval EFI_INVALID_PARAMETER Pointer is null or size is zero\r
++ @retval EFI_NOT_FOUND RNG protocol not found\r
++ @retval Others Error from RngProtocol->GetRNG()\r
+ \r
++ @return Status code\r
+ **/\r
+-UINT32\r
++EFI_STATUS\r
+ EFIAPI\r
+-NetRandomInitSeed (\r
+- VOID\r
++PseudoRandom (\r
++ OUT VOID *Output,\r
++ IN UINTN OutputLength\r
+ )\r
+ {\r
+- EFI_TIME Time;\r
+- UINT32 Seed;\r
+- UINT64 MonotonicCount;\r
++ EFI_RNG_PROTOCOL *RngProtocol;\r
++ EFI_STATUS Status;\r
++ UINTN AlgorithmIndex;\r
++\r
++ if ((Output == NULL) || (OutputLength == 0)) {\r
++ return EFI_INVALID_PARAMETER;\r
++ }\r
++\r
++ Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "Failed to locate EFI_RNG_PROTOCOL: %r\n", Status));\r
++ ASSERT_EFI_ERROR (Status);\r
++ return Status;\r
++ }\r
++\r
++ if (PcdGetBool (PcdEnforceSecureRngAlgorithms)) {\r
++ for (AlgorithmIndex = 0; AlgorithmIndex < SECURE_HASH_ALGORITHMS_SIZE; AlgorithmIndex++) {\r
++ Status = RngProtocol->GetRNG (RngProtocol, mSecureHashAlgorithms[AlgorithmIndex], OutputLength, (UINT8 *)Output);\r
++ if (!EFI_ERROR (Status)) {\r
++ //\r
++ // Secure Algorithm was supported on this platform\r
++ //\r
++ return EFI_SUCCESS;\r
++ } else if (Status == EFI_UNSUPPORTED) {\r
++ //\r
++ // Secure Algorithm was not supported on this platform\r
++ //\r
++ DEBUG ((DEBUG_ERROR, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status));\r
++\r
++ //\r
++ // Try the next secure algorithm\r
++ //\r
++ continue;\r
++ } else {\r
++ //\r
++ // Some other error occurred\r
++ //\r
++ DEBUG ((DEBUG_ERROR, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status));\r
++ ASSERT_EFI_ERROR (Status);\r
++ return Status;\r
++ }\r
++ }\r
++\r
++ //\r
++ // If we get here, we failed to generate random data using any secure algorithm\r
++ // Platform owner should ensure that at least one secure algorithm is supported\r
++ //\r
++ ASSERT_EFI_ERROR (Status);\r
++ return Status;\r
++ }\r
++\r
++ //\r
++ // Lets try using the default algorithm (which may not be secure)\r
++ //\r
++ Status = RngProtocol->GetRNG (RngProtocol, NULL, OutputLength, (UINT8 *)Output);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random data: %r\n", __func__, Status));\r
++ ASSERT_EFI_ERROR (Status);\r
++ return Status;\r
++ }\r
+ \r
+- gRT->GetTime (&Time, NULL);\r
+- Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second);\r
+- Seed ^= Time.Nanosecond;\r
+- Seed ^= Time.Year << 7;\r
++ return EFI_SUCCESS;\r
++}\r
++\r
++/**\r
++ Generate a 32-bit pseudo-random number.\r
+ \r
+- gBS->GetNextMonotonicCount (&MonotonicCount);\r
+- Seed += (UINT32)MonotonicCount;\r
++ @param[out] Output - The buffer to store the generated random number.\r
+ \r
+- return Seed;\r
++ @retval EFI_SUCCESS On Success\r
++ @retval EFI_NOT_FOUND RNG protocol not found\r
++ @retval Others Error from RngProtocol->GetRNG()\r
++\r
++ @return Status code\r
++**/\r
++EFI_STATUS\r
++EFIAPI\r
++PseudoRandomU32 (\r
++ OUT UINT32 *Output\r
++ )\r
++{\r
++ return PseudoRandom (Output, sizeof (*Output));\r
+ }\r
+ \r
+ /**\r
+diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
+index 8145d256ec..a8f534a293 100644
+--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
+@@ -3,6 +3,7 @@
+ #\r
+ # Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ # (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
++# Copyright (c) Microsoft Corporation\r
+ # SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ #\r
+ ##\r
+@@ -49,7 +50,11 @@
+ gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable\r
+ gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable\r
+ gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES\r
+-\r
++ gEfiRngAlgorithmRaw ## CONSUMES\r
++ gEfiRngAlgorithmSp80090Ctr256Guid ## CONSUMES\r
++ gEfiRngAlgorithmSp80090Hmac256Guid ## CONSUMES\r
++ gEfiRngAlgorithmSp80090Hash256Guid ## CONSUMES\r
++ gEfiRngAlgorithmArmRndr ## CONSUMES\r
+ \r
+ [Protocols]\r
+ gEfiSimpleNetworkProtocolGuid ## SOMETIMES_CONSUMES\r
+@@ -59,3 +64,10 @@
+ gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES\r
+ gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES\r
+ gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES\r
++ gEfiRngProtocolGuid ## CONSUMES\r
++\r
++[FixedPcd]\r
++ gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES\r
++\r
++[Depex]\r
++ gEfiRngProtocolGuid\r
+diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
+index 928e84fec4..ff335e957c 100644
+--- a/NetworkPkg/NetworkPkg.dec
++++ b/NetworkPkg/NetworkPkg.dec
+@@ -5,6 +5,7 @@
+ #\r
+ # Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP<BR>\r
++# Copyright (c) Microsoft Corporation\r
+ #\r
+ # SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ #\r
+@@ -127,6 +128,12 @@
+ # @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call.\r
+ gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C\r
+ \r
++ ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections.\r
++ # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms.\r
++ # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider.\r
++ # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms.\r
++ gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D\r
++\r
+ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]\r
+ ## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355).\r
+ # 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT]\r
+diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml
+index 7e900483fe..2b2c794697 100644
+--- a/NetworkPkg/SecurityFixes.yaml
++++ b/NetworkPkg/SecurityFixes.yaml
+@@ -121,3 +121,42 @@ CVE_2023_45235:
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45237:\r
++ commit_titles:\r
++ - "NetworkPkg:: SECURITY PATCH CVE 2023-45237"\r
++ cve: CVE-2023-45237\r
++ date_reported: 2023-08-28 13:56 UTC\r
++ description: "Bug 09 - Use of a Weak PseudoRandom Number Generator"\r
++ note:\r
++ files_impacted:\r
++ - NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c\r
++ - NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c\r
++ - NetworkPkg/DnsDxe/DnsDhcp.c\r
++ - NetworkPkg/DnsDxe/DnsImpl.c\r
++ - NetworkPkg/HttpBootDxe/HttpBootDhcp6.c\r
++ - NetworkPkg/IScsiDxe/IScsiCHAP.c\r
++ - NetworkPkg/IScsiDxe/IScsiMisc.c\r
++ - NetworkPkg/IScsiDxe/IScsiMisc.h\r
++ - NetworkPkg/Include/Library/NetLib.h\r
++ - NetworkPkg/Ip4Dxe/Ip4Driver.c\r
++ - NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c\r
++ - NetworkPkg/Ip6Dxe/Ip6Driver.c\r
++ - NetworkPkg/Ip6Dxe/Ip6If.c\r
++ - NetworkPkg/Ip6Dxe/Ip6Mld.c\r
++ - NetworkPkg/Ip6Dxe/Ip6Nd.c\r
++ - NetworkPkg/Ip6Dxe/Ip6Nd.h\r
++ - NetworkPkg/Library/DxeNetLib/DxeNetLib.c\r
++ - NetworkPkg/Library/DxeNetLib/DxeNetLib.inf\r
++ - NetworkPkg/NetworkPkg.dec\r
++ - NetworkPkg/TcpDxe/TcpDriver.c\r
++ - NetworkPkg/Udp4Dxe/Udp4Driver.c\r
++ - NetworkPkg/Udp6Dxe/Udp6Driver.c\r
++ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c\r
++ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c\r
++ - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c\r
++ links:\r
++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4542\r
++ - https://nvd.nist.gov/vuln/detail/CVE-2023-45237\r
++ - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
+diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
+index 98a90e0210..8fe6badd68 100644
+--- a/NetworkPkg/TcpDxe/TcpDriver.c
++++ b/NetworkPkg/TcpDxe/TcpDriver.c
+@@ -2,7 +2,7 @@
+ The driver binding and service binding protocol for the TCP driver.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -163,7 +163,13 @@ TcpDriverEntryPoint (
+ )\r
+ {\r
+ EFI_STATUS Status;\r
+- UINT32 Seed;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ //\r
+ // Install the TCP Driver Binding Protocol\r
+@@ -203,9 +209,8 @@ TcpDriverEntryPoint (
+ //\r
+ // Initialize ISS and random port.\r
+ //\r
+- Seed = NetRandomInitSeed ();\r
+- mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
+- mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (NET_RANDOM (Seed) % TCP_PORT_KNOWN));\r
++ mTcpGlobalIss = Random % mTcpGlobalIss;\r
++ mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN));\r
+ mTcp6RandomPort = mTcp4RandomPort;\r
+ \r
+ return EFI_SUCCESS;\r
+diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf
+index c0acbdca57..cf5423f4c5 100644
+--- a/NetworkPkg/TcpDxe/TcpDxe.inf
++++ b/NetworkPkg/TcpDxe/TcpDxe.inf
+@@ -82,5 +82,8 @@
+ gEfiTcp6ProtocolGuid ## BY_START\r
+ gEfiTcp6ServiceBindingProtocolGuid ## BY_START\r
+ \r
++[Depex]\r
++ gEfiHash2ServiceBindingProtocolGuid\r
++\r
+ [UserExtensions.TianoCore."ExtraFiles"]\r
+ TcpDxeExtra.uni\r
+diff --git a/NetworkPkg/Udp4Dxe/Udp4Driver.c b/NetworkPkg/Udp4Dxe/Udp4Driver.c
+index cb917fcfc9..c7ea16f4cd 100644
+--- a/NetworkPkg/Udp4Dxe/Udp4Driver.c
++++ b/NetworkPkg/Udp4Dxe/Udp4Driver.c
+@@ -1,6 +1,7 @@
+ /** @file\r
+ \r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
++Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -555,6 +556,13 @@ Udp4DriverEntryPoint (
+ )\r
+ {\r
+ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ //\r
+ // Install the Udp4DriverBinding and Udp4ComponentName protocols.\r
+@@ -571,7 +579,7 @@ Udp4DriverEntryPoint (
+ //\r
+ // Initialize the UDP random port.\r
+ //\r
+- mUdp4RandomPort = (UINT16)(((UINT16)NetRandomInitSeed ()) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN);\r
++ mUdp4RandomPort = (UINT16)(((UINT16)Random) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN);\r
+ }\r
+ \r
+ return Status;\r
+diff --git a/NetworkPkg/Udp6Dxe/Udp6Driver.c b/NetworkPkg/Udp6Dxe/Udp6Driver.c
+index ae96fb9966..edb758d57c 100644
+--- a/NetworkPkg/Udp6Dxe/Udp6Driver.c
++++ b/NetworkPkg/Udp6Dxe/Udp6Driver.c
+@@ -2,7 +2,7 @@
+ Driver Binding functions and Service Binding functions for the Network driver module.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -596,6 +596,13 @@ Udp6DriverEntryPoint (
+ )\r
+ {\r
+ EFI_STATUS Status;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
+ \r
+ //\r
+ // Install the Udp6DriverBinding and Udp6ComponentName protocols.\r
+@@ -614,7 +621,7 @@ Udp6DriverEntryPoint (
+ // Initialize the UDP random port.\r
+ //\r
+ mUdp6RandomPort = (UINT16)(\r
+- ((UINT16)NetRandomInitSeed ()) %\r
++ ((UINT16)Random) %\r
+ UDP6_PORT_KNOWN +\r
+ UDP6_PORT_KNOWN\r
+ );\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
+index 91146b78cb..452038c219 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
+@@ -2,7 +2,7 @@
+ Functions implementation related with DHCPv4 for UefiPxeBc Driver.\r
+ \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+-\r
++ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+ **/\r
+@@ -1381,6 +1381,12 @@ PxeBcDhcp4Discover (
+ UINT8 VendorOptLen;\r
+ UINT32 Xid;\r
+ \r
++ Status = PseudoRandomU32 (&Xid);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ Mode = Private->PxeBc.Mode;\r
+ Dhcp4 = Private->Dhcp4;\r
+ Status = EFI_SUCCESS;\r
+@@ -1471,7 +1477,6 @@ PxeBcDhcp4Discover (
+ //\r
+ // Set fields of the token for the request packet.\r
+ //\r
+- Xid = NET_RANDOM (NetRandomInitSeed ());\r
+ Token.Packet->Dhcp4.Header.Xid = HTONL (Xid);\r
+ Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)((IsBCast) ? 0x8000 : 0x0));\r
+ CopyMem (&Token.Packet->Dhcp4.Header.ClientAddr, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+index 7fd1281c11..bcabbd2219 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+@@ -2180,7 +2180,7 @@ PxeBcDhcp6Discover (
+ UINTN ReadSize;\r
+ UINT16 OpCode;\r
+ UINT16 OpLen;\r
+- UINT32 Xid;\r
++ UINT32 Random;\r
+ EFI_STATUS Status;\r
+ UINTN DiscoverLenNeeded;\r
+ \r
+@@ -2198,6 +2198,12 @@ PxeBcDhcp6Discover (
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ \r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));\r
++ return Status;\r
++ }\r
++\r
+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);\r
+ Discover = AllocateZeroPool (DiscoverLenNeeded);\r
+ if (Discover == NULL) {\r
+@@ -2207,8 +2213,7 @@ PxeBcDhcp6Discover (
+ //\r
+ // Build the discover packet by the cached request packet before.\r
+ //\r
+- Xid = NET_RANDOM (NetRandomInitSeed ());\r
+- Discover->TransactionId = HTONL (Xid);\r
++ Discover->TransactionId = HTONL (Random);\r
+ Discover->MessageType = Request->Dhcp6.Header.MessageType;\r
+ RequestOpt = Request->Dhcp6.Option;\r
+ DiscoverOpt = Discover->DhcpOptions;\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
+index d84aca7e85..4cd915b411 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
+@@ -3,6 +3,7 @@
+ \r
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+ Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
++ Copyright (c) Microsoft Corporation\r
+ \r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ \r
+@@ -892,6 +893,13 @@ PxeBcCreateIp6Children (
+ PXEBC_PRIVATE_PROTOCOL *Id;\r
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
+ UINTN Index;\r
++ UINT32 Random;\r
++\r
++ Status = PseudoRandomU32 (&Random);\r
++ if (EFI_ERROR (Status)) {\r
++ DEBUG ((DEBUG_ERROR, "Failed to generate random number using EFI_RNG_PROTOCOL: %r\n", Status));\r
++ return Status;\r
++ }\r
+ \r
+ if (Private->Ip6Nic != NULL) {\r
+ //\r
+@@ -935,9 +943,9 @@ PxeBcCreateIp6Children (
+ }\r
+ \r
+ //\r
+- // Generate a random IAID for the Dhcp6 assigned address.\r
++ // Set a random IAID for the Dhcp6 assigned address.\r
+ //\r
+- Private->IaId = NET_RANDOM (NetRandomInitSeed ());\r
++ Private->IaId = Random;\r
+ if (Private->Snp != NULL) {\r
+ for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {\r
+ Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));\r
+--
+2.40.0
+