Skip to content

Commit 5e87833

Browse files
committed
NetworkPkg:: SECURITY PATCH CVE 2023-45237
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4542 Bug Overview: PixieFail Bug tianocore#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 > 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 NIST SP-800-90 approved 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 the NIST SP-800-90 approved algorithms then the driver will assert. Cc: Saloni Kasbekar <[email protected]> Cc: Zachary Clark-williams <[email protected]> Signed-off-by: Doug Flick [MSFT] <[email protected]>
1 parent 86c8d69 commit 5e87833

26 files changed

+358
-83
lines changed

NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ Dhcp4CreateService (
189189
{
190190
DHCP_SERVICE *DhcpSb;
191191
EFI_STATUS Status;
192+
UINT32 Random;
193+
194+
Status = PseudoRandomU32 (&Random);
195+
if (EFI_ERROR (Status)) {
196+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
197+
return Status;
198+
}
192199

193200
*Service = NULL;
194201
DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE));
@@ -203,7 +210,7 @@ Dhcp4CreateService (
203210
DhcpSb->Image = ImageHandle;
204211
InitializeListHead (&DhcpSb->Children);
205212
DhcpSb->DhcpState = Dhcp4Stopped;
206-
DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());
213+
DhcpSb->Xid = Random;
207214
CopyMem (
208215
&DhcpSb->ServiceBinding,
209216
&mDhcp4ServiceBindingTemplate,

NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ Dhcp6CreateService (
123123
{
124124
DHCP6_SERVICE *Dhcp6Srv;
125125
EFI_STATUS Status;
126+
UINT32 Random;
127+
128+
Status = PseudoRandomU32 (&Random);
129+
if (EFI_ERROR (Status)) {
130+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
131+
return Status;
132+
}
126133

127134
*Service = NULL;
128135
Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));
@@ -147,7 +154,7 @@ Dhcp6CreateService (
147154
Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;
148155
Dhcp6Srv->Controller = Controller;
149156
Dhcp6Srv->Image = ImageHandle;
150-
Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));
157+
Dhcp6Srv->Xid = (0xffffff & Random);
151158

152159
CopyMem (
153160
&Dhcp6Srv->ServiceBinding,

NetworkPkg/DnsDxe/DnsDhcp.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ GetDns4ServerFromDhcp4 (
277277
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token;
278278
BOOLEAN IsDone;
279279
UINTN Index;
280+
UINT32 Random;
280281

281282
Image = Instance->Service->ImageHandle;
282283
Controller = Instance->Service->ControllerHandle;
@@ -292,6 +293,12 @@ GetDns4ServerFromDhcp4 (
292293
Data = NULL;
293294
InterfaceInfo = NULL;
294295

296+
Status = PseudoRandomU32 (&Random);
297+
if (EFI_ERROR (Status)) {
298+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
299+
return Status;
300+
}
301+
295302
ZeroMem ((UINT8 *)ParaList, sizeof (ParaList));
296303

297304
ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA));
@@ -467,7 +474,7 @@ GetDns4ServerFromDhcp4 (
467474

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

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

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

NetworkPkg/DnsDxe/DnsImpl.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,14 @@ ConstructDNSQuery (
19631963
NET_FRAGMENT Frag;
19641964
DNS_HEADER *DnsHeader;
19651965
DNS_QUERY_SECTION *DnsQuery;
1966+
EFI_STATUS Status;
1967+
UINT32 Random;
1968+
1969+
Status = PseudoRandomU32 (&Random);
1970+
if (EFI_ERROR (Status)) {
1971+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
1972+
return Status;
1973+
}
19661974

19671975
//
19681976
// Messages carried by UDP are restricted to 512 bytes (not counting the IP
@@ -1977,7 +1985,7 @@ ConstructDNSQuery (
19771985
// Fill header
19781986
//
19791987
DnsHeader = (DNS_HEADER *)Frag.Bulk;
1980-
DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed ());
1988+
DnsHeader->Identification = (UINT16)Random;
19811989
DnsHeader->Flags.Uint16 = 0x0000;
19821990
DnsHeader->Flags.Bits.RD = 1;
19831991
DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD;

NetworkPkg/HttpBootDxe/HttpBootDhcp6.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,7 @@ HttpBootDhcp6Sarr (
951951
UINT32 OptCount;
952952
UINT8 Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE];
953953
EFI_STATUS Status;
954+
UINT32 Random;
954955

955956
Dhcp6 = Private->Dhcp6;
956957
ASSERT (Dhcp6 != NULL);
@@ -961,6 +962,12 @@ HttpBootDhcp6Sarr (
961962
OptCount = HttpBootBuildDhcp6Options (Private, OptList, Buffer);
962963
ASSERT (OptCount > 0);
963964

965+
Status = PseudoRandomU32 (&Random);
966+
if (EFI_ERROR (Status)) {
967+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
968+
return Status;
969+
}
970+
964971
Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));
965972
if (Retransmit == NULL) {
966973
return EFI_OUT_OF_RESOURCES;
@@ -976,7 +983,7 @@ HttpBootDhcp6Sarr (
976983
Config.IaInfoEvent = NULL;
977984
Config.RapidCommit = FALSE;
978985
Config.ReconfigureAccept = FALSE;
979-
Config.IaDescriptor.IaId = NET_RANDOM (NetRandomInitSeed ());
986+
Config.IaDescriptor.IaId = Random;
980987
Config.IaDescriptor.Type = EFI_DHCP6_IA_TYPE_NA;
981988
Config.SolicitRetransmission = Retransmit;
982989
Retransmit->Irt = 4;

NetworkPkg/IScsiDxe/IScsiCHAP.c

+13-5
Original file line numberDiff line numberDiff line change
@@ -576,16 +576,24 @@ IScsiCHAPToSendReq (
576576
//
577577
// CHAP_I=<I>
578578
//
579-
IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);
579+
Status = IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1);
580+
if (EFI_ERROR (Status)) {
581+
break;
582+
}
583+
580584
AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier);
581585
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr);
582586
//
583587
// CHAP_C=<C>
584588
//
585-
IScsiGenRandom (
586-
(UINT8 *)AuthData->OutChallenge,
587-
AuthData->Hash->DigestSize
588-
);
589+
Status = IScsiGenRandom (
590+
(UINT8 *)AuthData->OutChallenge,
591+
AuthData->Hash->DigestSize
592+
);
593+
if (EFI_ERROR (Status)) {
594+
break;
595+
}
596+
589597
BinToHexStatus = IScsiBinToHex (
590598
(UINT8 *)AuthData->OutChallenge,
591599
AuthData->Hash->DigestSize,

NetworkPkg/IScsiDxe/IScsiMisc.c

+5-8
Original file line numberDiff line numberDiff line change
@@ -474,20 +474,17 @@ IScsiNetNtoi (
474474
@param[in, out] Rand The buffer to contain random numbers.
475475
@param[in] RandLength The length of the Rand buffer.
476476
477+
@retval EFI_SUCCESS on success
478+
@retval others on error
479+
477480
**/
478-
VOID
481+
EFI_STATUS
479482
IScsiGenRandom (
480483
IN OUT UINT8 *Rand,
481484
IN UINTN RandLength
482485
)
483486
{
484-
UINT32 Random;
485-
486-
while (RandLength > 0) {
487-
Random = NET_RANDOM (NetRandomInitSeed ());
488-
*Rand++ = (UINT8)(Random);
489-
RandLength--;
490-
}
487+
return PseudoRandom (Rand, RandLength);
491488
}
492489

493490
/**

NetworkPkg/IScsiDxe/IScsiMisc.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,11 @@ IScsiNetNtoi (
202202
@param[in, out] Rand The buffer to contain random numbers.
203203
@param[in] RandLength The length of the Rand buffer.
204204
205+
@retval EFI_SUCCESS on success
206+
@retval others on error
207+
205208
**/
206-
VOID
209+
EFI_STATUS
207210
IScsiGenRandom (
208211
IN OUT UINT8 *Rand,
209212
IN UINTN RandLength

NetworkPkg/Include/Library/NetLib.h

+8-13
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,6 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr;
539539
#define TICKS_PER_MS 10000U
540540
#define TICKS_PER_SECOND 10000000U
541541

542-
#define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)
543-
544542
/**
545543
Extract a UINT32 from a byte stream.
546544
@@ -579,20 +577,17 @@ NetPutUint32 (
579577
IN UINT32 Data
580578
);
581579

582-
/**
583-
Initialize a random seed using current time and monotonic count.
584-
585-
Get current time and monotonic count first. Then initialize a random seed
586-
based on some basic mathematics operation on the hour, day, minute, second,
587-
nanosecond and year of the current time and the monotonic count value.
580+
/*
581+
Generate a 32-bit pseudo-random number.
588582
589-
@return The random seed initialized with current time.
583+
@param[out] Output - The buffer to store the generated random number.
590584
591-
**/
592-
UINT32
585+
@return EFI_SUCCESS on success, error code on failure.
586+
*/
587+
EFI_STATUS
593588
EFIAPI
594-
NetRandomInitSeed (
595-
VOID
589+
PseudoRandomU32 (
590+
OUT UINT32 *Output
596591
);
597592

598593
#define NET_LIST_USER_STRUCT(Entry, Type, Field) \

NetworkPkg/Ip4Dxe/Ip4Driver.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -549,11 +549,18 @@ Ip4DriverBindingStart (
549549
EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;
550550
UINTN Index;
551551
IP4_CONFIG2_DATA_ITEM *DataItem;
552+
UINT32 Random;
552553

553554
IpSb = NULL;
554555
Ip4Cfg2 = NULL;
555556
DataItem = NULL;
556557

558+
Status = PseudoRandomU32 (&Random);
559+
if (EFI_ERROR (Status)) {
560+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
561+
return Status;
562+
}
563+
557564
//
558565
// Test for the Ip4 service binding protocol
559566
//
@@ -653,7 +660,7 @@ Ip4DriverBindingStart (
653660
//
654661
// Initialize the IP4 ID
655662
//
656-
mIp4Id = (UINT16)NET_RANDOM (NetRandomInitSeed ());
663+
mIp4Id = (UINT16)Random;
657664

658665
return Status;
659666

NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -2276,6 +2276,13 @@ Ip6ConfigInitInstance (
22762276
UINTN Index;
22772277
UINT16 IfIndex;
22782278
IP6_CONFIG_DATA_ITEM *DataItem;
2279+
UINT32 Random;
2280+
2281+
Status = PseudoRandomU32 (&Random);
2282+
if (EFI_ERROR (Status)) {
2283+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
2284+
return Status;
2285+
}
22792286

22802287
IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
22812288

@@ -2381,7 +2388,7 @@ Ip6ConfigInitInstance (
23812388
// The NV variable is not set, so generate a random IAID, and write down the
23822389
// fresh new configuration as the NV variable now.
23832390
//
2384-
Instance->IaId = NET_RANDOM (NetRandomInitSeed ());
2391+
Instance->IaId = Random;
23852392

23862393
for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) {
23872394
Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31));

NetworkPkg/Ip6Dxe/Ip6Driver.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,11 @@ Ip6CreateService (
316316
IpSb->CurHopLimit = IP6_HOP_LIMIT;
317317
IpSb->LinkMTU = IP6_MIN_LINK_MTU;
318318
IpSb->BaseReachableTime = IP6_REACHABLE_TIME;
319-
Ip6UpdateReachableTime (IpSb);
319+
Status = Ip6UpdateReachableTime (IpSb);
320+
if (EFI_ERROR (Status)) {
321+
goto ON_ERROR;
322+
}
323+
320324
//
321325
// RFC4861 RETRANS_TIMER: 1,000 milliseconds
322326
//
@@ -516,11 +520,18 @@ Ip6DriverBindingStart (
516520
EFI_STATUS Status;
517521
EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
518522
IP6_CONFIG_DATA_ITEM *DataItem;
523+
UINT32 Random;
519524

520525
IpSb = NULL;
521526
Ip6Cfg = NULL;
522527
DataItem = NULL;
523528

529+
Status = PseudoRandomU32 (&Random);
530+
if (EFI_ERROR (Status)) {
531+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
532+
return Status;
533+
}
534+
524535
//
525536
// Test for the Ip6 service binding protocol
526537
//
@@ -656,7 +667,7 @@ Ip6DriverBindingStart (
656667
//
657668
// Initialize the IP6 ID
658669
//
659-
mIp6Id = NET_RANDOM (NetRandomInitSeed ());
670+
mIp6Id = Random;
660671

661672
return EFI_SUCCESS;
662673

NetworkPkg/Ip6Dxe/Ip6If.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ Ip6SetAddress (
8989
IP6_PREFIX_LIST_ENTRY *PrefixEntry;
9090
UINT64 Delay;
9191
IP6_DELAY_JOIN_LIST *DelayNode;
92+
EFI_STATUS Status;
93+
UINT32 Random;
94+
95+
Status = PseudoRandomU32 (&Random);
96+
if (EFI_ERROR (Status)) {
97+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
98+
return Status;
99+
}
92100

93101
NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);
94102

@@ -164,7 +172,7 @@ Ip6SetAddress (
164172
// Thus queue the address to be processed in Duplicate Address Detection module
165173
// after the delay time (in milliseconds).
166174
//
167-
Delay = (UINT64)NET_RANDOM (NetRandomInitSeed ());
175+
Delay = (UINT64)Random;
168176
Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS);
169177
Delay = RShiftU64 (Delay, 32);
170178

NetworkPkg/Ip6Dxe/Ip6Mld.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,15 @@ Ip6UpdateDelayTimer (
696696
IN OUT IP6_MLD_GROUP *Group
697697
)
698698
{
699-
UINT32 Delay;
699+
UINT32 Delay;
700+
EFI_STATUS Status;
701+
UINT32 Random;
702+
703+
Status = PseudoRandomU32 (&Random);
704+
if (EFI_ERROR (Status)) {
705+
DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
706+
return Status;
707+
}
700708

701709
//
702710
// If the Query packet specifies a Maximum Response Delay of zero, perform timer
@@ -715,7 +723,7 @@ Ip6UpdateDelayTimer (
715723
// is less than the remaining value of the running timer.
716724
//
717725
if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) {
718-
Group->DelayTimer = Delay / 4294967295UL * NET_RANDOM (NetRandomInitSeed ());
726+
Group->DelayTimer = Delay / 4294967295UL * Random;
719727
}
720728

721729
return EFI_SUCCESS;

0 commit comments

Comments
 (0)