summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Sambu <soumya.sambu@windriver.com>2024-08-02 03:38:03 +0000
committerSteve Sakoman <steve@sakoman.com>2024-12-09 07:54:03 -0800
commitdd8ed68222f9249766bb4c376833d7d63d601c41 (patch)
tree04ea38afcf1739205c31b4031d56ca51bc7436fb
parent4c2d3e37308cac98614dfafed79b7323423af8bc (diff)
downloadpoky-dd8ed68222f9249766bb4c376833d7d63d601c41.tar.gz
ovmf: Fix CVE-2023-45236
EDK2's Network Package is susceptible to a predictable TCP Initial Sequence Number. This vulnerability can be exploited by an attacker to gain unauthorized access and potentially lead to a loss of Confidentiality. References: https://nvd.nist.gov/vuln/detail/CVE-2023-45236 Upstream-patch: https://github.com/tianocore/edk2/commit/1904a64bcc18199738e5be183d28887ac5d837d7 (From OE-Core rev: a9cd3321558e95f61ed4c5eca0dcf5a3f4704925) Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-core/ovmf/ovmf/CVE-2023-45236.patch829
-rw-r--r--meta/recipes-core/ovmf/ovmf_git.bb1
2 files changed, 830 insertions, 0 deletions
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45236.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45236.patch
new file mode 100644
index 0000000000..ac43392ce6
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45236.patch
@@ -0,0 +1,829 @@
1From 1904a64bcc18199738e5be183d28887ac5d837d7 Mon Sep 17 00:00:00 2001
2From: Doug Flick <dougflick@microsoft.com>
3Date: Wed, 8 May 2024 22:56:29 -0700
4Subject: [PATCH] NetworkPkg TcpDxe: SECURITY PATCH CVE-2023-45236
5
6REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4541
7REF: https://www.rfc-editor.org/rfc/rfc1948.txt
8REF: https://www.rfc-editor.org/rfc/rfc6528.txt
9REF: https://www.rfc-editor.org/rfc/rfc9293.txt
10
11Bug Overview:
12PixieFail Bug #8
13CVE-2023-45236
14CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
15CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
16
17Updates TCP ISN generation to use a cryptographic hash of the
18connection's identifying parameters and a secret key.
19This prevents an attacker from guessing the ISN used for some other
20connection.
21
22This is follows the guidance in RFC 1948, RFC 6528, and RFC 9293.
23
24RFC: 9293 Section 3.4.1. Initial Sequence Number Selection
25
26 A TCP implementation MUST use the above type of "clock" for clock-
27 driven selection of initial sequence numbers (MUST-8), and SHOULD
28 generate its initial sequence numbers with the expression:
29
30 ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
31
32 where M is the 4 microsecond timer, and F() is a pseudorandom
33 function (PRF) of the connection's identifying parameters ("localip,
34 localport, remoteip, remoteport") and a secret key ("secretkey")
35 (SHLD-1). F() MUST NOT be computable from the outside (MUST-9), or
36 an attacker could still guess at sequence numbers from the ISN used
37 for some other connection. The PRF could be implemented as a
38 cryptographic hash of the concatenation of the TCP connection
39 parameters and some secret data. For discussion of the selection of
40 a specific hash algorithm and management of the secret key data,
41 please see Section 3 of [42].
42
43 For each connection there is a send sequence number and a receive
44 sequence number. The initial send sequence number (ISS) is chosen by
45 the data sending TCP peer, and the initial receive sequence number
46 (IRS) is learned during the connection-establishing procedure.
47
48 For a connection to be established or initialized, the two TCP peers
49 must synchronize on each other's initial sequence numbers. This is
50 done in an exchange of connection-establishing segments carrying a
51 control bit called "SYN" (for synchronize) and the initial sequence
52 numbers. As a shorthand, segments carrying the SYN bit are also
53 called "SYNs". Hence, the solution requires a suitable mechanism for
54 picking an initial sequence number and a slightly involved handshake
55 to exchange the ISNs.
56
57Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
58Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
59
60Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
61Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
62
63CVE: CVE-2023-45236
64
65Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1904a64bcc18199738e5be183d28887ac5d837d7]
66
67Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
68---
69 NetworkPkg/SecurityFixes.yaml | 22 +++
70 NetworkPkg/TcpDxe/TcpDriver.c | 92 ++++++++++++-
71 NetworkPkg/TcpDxe/TcpDxe.inf | 8 +-
72 NetworkPkg/TcpDxe/TcpFunc.h | 23 ++--
73 NetworkPkg/TcpDxe/TcpInput.c | 13 +-
74 NetworkPkg/TcpDxe/TcpMain.h | 59 ++++++--
75 NetworkPkg/TcpDxe/TcpMisc.c | 244 ++++++++++++++++++++++++++++++++--
76 NetworkPkg/TcpDxe/TcpTimer.c | 3 +-
77 8 files changed, 415 insertions(+), 49 deletions(-)
78
79diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml
80index 2b2c794697..ab355419cc 100644
81--- a/NetworkPkg/SecurityFixes.yaml
82+++ b/NetworkPkg/SecurityFixes.yaml
83@@ -121,6 +121,28 @@ CVE_2023_45235:
84 - http://www.openwall.com/lists/oss-security/2024/01/16/2
85 - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
86 - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
87+CVE_2023_45236:
88+ commit_titles:
89+ - "NetworkPkg: TcpDxe: SECURITY PATCH CVE-2023-45236 Patch"
90+ cve: CVE-2023-45236
91+ date_reported: 2023-08-28 13:56 UTC
92+ description: "Bug 08 - edk2/NetworkPkg: Predictable TCP Initial Sequence Numbers"
93+ note:
94+ files_impacted:
95+ - NetworkPkg/Include/Library/NetLib.h
96+ - NetworkPkg/TcpDxe/TcpDriver.c
97+ - NetworkPkg/TcpDxe/TcpDxe.inf
98+ - NetworkPkg/TcpDxe/TcpFunc.h
99+ - NetworkPkg/TcpDxe/TcpInput.c
100+ - NetworkPkg/TcpDxe/TcpMain.h
101+ - NetworkPkg/TcpDxe/TcpMisc.c
102+ - NetworkPkg/TcpDxe/TcpTimer.c
103+ links:
104+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4541
105+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45236
106+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
107+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
108+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
109 CVE_2023_45237:
110 commit_titles:
111 - "NetworkPkg:: SECURITY PATCH CVE 2023-45237"
112diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
113index 8fe6badd68..40bba4080c 100644
114--- a/NetworkPkg/TcpDxe/TcpDriver.c
115+++ b/NetworkPkg/TcpDxe/TcpDriver.c
116@@ -83,6 +83,12 @@ EFI_SERVICE_BINDING_PROTOCOL gTcpServiceBinding = {
117 TcpServiceBindingDestroyChild
118 };
119
120+//
121+// This is the handle for the Hash2ServiceBinding Protocol instance this driver produces
122+// if the platform does not provide one.
123+//
124+EFI_HANDLE mHash2ServiceHandle = NULL;
125+
126 /**
127 Create and start the heartbeat timer for the TCP driver.
128
129@@ -165,6 +171,23 @@ TcpDriverEntryPoint (
130 EFI_STATUS Status;
131 UINT32 Random;
132
133+ //
134+ // Initialize the Secret used for hashing TCP sequence numbers
135+ //
136+ // Normally this should be regenerated periodically, but since
137+ // this is only used for UEFI networking and not a general purpose
138+ // operating system, it is not necessary to regenerate it.
139+ //
140+ Status = PseudoRandomU32 (&mTcpGlobalSecret);
141+ if (EFI_ERROR (Status)) {
142+ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
143+ return Status;
144+ }
145+
146+ //
147+ // Get a random number used to generate a random port number
148+ // Intentionally not linking this to mTcpGlobalSecret to avoid leaking information about the secret
149+ //
150 Status = PseudoRandomU32 (&Random);
151 if (EFI_ERROR (Status)) {
152 DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status));
153@@ -207,9 +230,8 @@ TcpDriverEntryPoint (
154 }
155
156 //
157- // Initialize ISS and random port.
158+ // Initialize the random port.
159 //
160- mTcpGlobalIss = Random % mTcpGlobalIss;
161 mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN));
162 mTcp6RandomPort = mTcp4RandomPort;
163
164@@ -224,6 +246,8 @@ TcpDriverEntryPoint (
165 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
166
167 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
168+ @retval EFI_UNSUPPORTED Service Binding Protocols are unavailable.
169+ @retval EFI_ALREADY_STARTED The TCP driver is already started on the controller.
170 @retval EFI_SUCCESS A new IP6 service binding private was created.
171
172 **/
173@@ -234,11 +258,13 @@ TcpCreateService (
174 IN UINT8 IpVersion
175 )
176 {
177- EFI_STATUS Status;
178- EFI_GUID *IpServiceBindingGuid;
179- EFI_GUID *TcpServiceBindingGuid;
180- TCP_SERVICE_DATA *TcpServiceData;
181- IP_IO_OPEN_DATA OpenData;
182+ EFI_STATUS Status;
183+ EFI_GUID *IpServiceBindingGuid;
184+ EFI_GUID *TcpServiceBindingGuid;
185+ TCP_SERVICE_DATA *TcpServiceData;
186+ IP_IO_OPEN_DATA OpenData;
187+ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding;
188+ EFI_HASH2_PROTOCOL *Hash2Protocol;
189
190 if (IpVersion == IP_VERSION_4) {
191 IpServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
192@@ -272,6 +298,33 @@ TcpCreateService (
193 return EFI_UNSUPPORTED;
194 }
195
196+ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
197+ if (EFI_ERROR (Status)) {
198+ //
199+ // If we can't find the Hashing protocol, then we need to create one.
200+ //
201+
202+ //
203+ // Platform is expected to publish the hash service binding protocol to support TCP.
204+ //
205+ Status = gBS->LocateProtocol (
206+ &gEfiHash2ServiceBindingProtocolGuid,
207+ NULL,
208+ (VOID **)&Hash2ServiceBinding
209+ );
210+ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->CreateChild == NULL)) {
211+ return EFI_UNSUPPORTED;
212+ }
213+
214+ //
215+ // Create an instance of the hash protocol for this controller.
216+ //
217+ Status = Hash2ServiceBinding->CreateChild (Hash2ServiceBinding, &mHash2ServiceHandle);
218+ if (EFI_ERROR (Status)) {
219+ return EFI_UNSUPPORTED;
220+ }
221+ }
222+
223 //
224 // Create the TCP service data.
225 //
226@@ -423,6 +476,7 @@ TcpDestroyService (
227 EFI_STATUS Status;
228 LIST_ENTRY *List;
229 TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
230+ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding;
231
232 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
233
234@@ -439,6 +493,30 @@ TcpDestroyService (
235 return EFI_SUCCESS;
236 }
237
238+ //
239+ // Destroy the Hash2ServiceBinding instance if it is created by Tcp driver.
240+ //
241+ if (mHash2ServiceHandle != NULL) {
242+ Status = gBS->LocateProtocol (
243+ &gEfiHash2ServiceBindingProtocolGuid,
244+ NULL,
245+ (VOID **)&Hash2ServiceBinding
246+ );
247+ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->DestroyChild == NULL)) {
248+ return EFI_UNSUPPORTED;
249+ }
250+
251+ //
252+ // Destroy the instance of the hashing protocol for this controller.
253+ //
254+ Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, &mHash2ServiceHandle);
255+ if (EFI_ERROR (Status)) {
256+ return EFI_UNSUPPORTED;
257+ }
258+
259+ mHash2ServiceHandle = NULL;
260+ }
261+
262 Status = gBS->OpenProtocol (
263 NicHandle,
264 ServiceBindingGuid,
265diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf
266index cf5423f4c5..76de4cf9ec 100644
267--- a/NetworkPkg/TcpDxe/TcpDxe.inf
268+++ b/NetworkPkg/TcpDxe/TcpDxe.inf
269@@ -6,6 +6,7 @@
270 # stack has been loaded in system. This driver supports both IPv4 and IPv6 network stack.
271 #
272 # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
273+# Copyright (c) Microsoft Corporation
274 #
275 # SPDX-License-Identifier: BSD-2-Clause-Patent
276 #
277@@ -68,7 +69,6 @@
278 NetLib
279 IpIoLib
280
281-
282 [Protocols]
283 ## SOMETIMES_CONSUMES
284 ## SOMETIMES_PRODUCES
285@@ -81,6 +81,12 @@
286 gEfiIp6ServiceBindingProtocolGuid ## TO_START
287 gEfiTcp6ProtocolGuid ## BY_START
288 gEfiTcp6ServiceBindingProtocolGuid ## BY_START
289+ gEfiHash2ProtocolGuid ## BY_START
290+ gEfiHash2ServiceBindingProtocolGuid ## BY_START
291+
292+[Guids]
293+ gEfiHashAlgorithmMD5Guid ## CONSUMES
294+ gEfiHashAlgorithmSha256Guid ## CONSUMES
295
296 [Depex]
297 gEfiHash2ServiceBindingProtocolGuid
298diff --git a/NetworkPkg/TcpDxe/TcpFunc.h b/NetworkPkg/TcpDxe/TcpFunc.h
299index a7af01fff2..c707bee3e5 100644
300--- a/NetworkPkg/TcpDxe/TcpFunc.h
301+++ b/NetworkPkg/TcpDxe/TcpFunc.h
302@@ -2,7 +2,7 @@
303 Declaration of external functions shared in TCP driver.
304
305 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
306-
307+ Copyright (c) Microsoft Corporation
308 SPDX-License-Identifier: BSD-2-Clause-Patent
309
310 **/
311@@ -36,8 +36,11 @@ VOID
312
313 @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
314
315+ @retval EFI_SUCCESS The operation completed successfully
316+ @retval others The underlying functions failed and could not complete the operation
317+
318 **/
319-VOID
320+EFI_STATUS
321 TcpInitTcbLocal (
322 IN OUT TCP_CB *Tcb
323 );
324@@ -128,17 +131,6 @@ TcpCloneTcb (
325 IN TCP_CB *Tcb
326 );
327
328-/**
329- Compute an ISS to be used by a new connection.
330-
331- @return The result ISS.
332-
333-**/
334-TCP_SEQNO
335-TcpGetIss (
336- VOID
337- );
338-
339 /**
340 Get the local mss.
341
342@@ -202,8 +194,11 @@ TcpFormatNetbuf (
343 @param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a
344 connection.
345
346+ @retval EFI_SUCCESS The operation completed successfully
347+ @retval others The underlying functions failed and could not complete the operation
348+
349 **/
350-VOID
351+EFI_STATUS
352 TcpOnAppConnect (
353 IN OUT TCP_CB *Tcb
354 );
355diff --git a/NetworkPkg/TcpDxe/TcpInput.c b/NetworkPkg/TcpDxe/TcpInput.c
356index fb1aa827f8..0477a15d0c 100644
357--- a/NetworkPkg/TcpDxe/TcpInput.c
358+++ b/NetworkPkg/TcpDxe/TcpInput.c
359@@ -724,6 +724,7 @@ TcpInput (
360 TCP_SEQNO Urg;
361 UINT16 Checksum;
362 INT32 Usable;
363+ EFI_STATUS Status;
364
365 ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));
366
367@@ -872,7 +873,17 @@ TcpInput (
368 Tcb->LocalEnd.Port = Head->DstPort;
369 Tcb->RemoteEnd.Port = Head->SrcPort;
370
371- TcpInitTcbLocal (Tcb);
372+ Status = TcpInitTcbLocal (Tcb);
373+ if (EFI_ERROR (Status)) {
374+ DEBUG (
375+ (DEBUG_ERROR,
376+ "TcpInput: discard a segment because failed to init local end for TCB %p\n",
377+ Tcb)
378+ );
379+
380+ goto DISCARD;
381+ }
382+
383 TcpInitTcbPeer (Tcb, Seg, &Option);
384
385 TcpSetState (Tcb, TCP_SYN_RCVD);
386diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h
387index c0c9b7f46e..4d5566ab93 100644
388--- a/NetworkPkg/TcpDxe/TcpMain.h
389+++ b/NetworkPkg/TcpDxe/TcpMain.h
390@@ -3,7 +3,7 @@
391 It is the common head file for all Tcp*.c in TCP driver.
392
393 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
394-
395+ Copyright (c) Microsoft Corporation
396 SPDX-License-Identifier: BSD-2-Clause-Patent
397
398 **/
399@@ -13,6 +13,7 @@
400
401 #include <Protocol/ServiceBinding.h>
402 #include <Protocol/DriverBinding.h>
403+#include <Protocol/Hash2.h>
404 #include <Library/IpIoLib.h>
405 #include <Library/DevicePathLib.h>
406 #include <Library/PrintLib.h>
407@@ -31,7 +32,7 @@ extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
408
409 extern LIST_ENTRY mTcpRunQue;
410 extern LIST_ENTRY mTcpListenQue;
411-extern TCP_SEQNO mTcpGlobalIss;
412+extern TCP_SEQNO mTcpGlobalSecret;
413 extern UINT32 mTcpTick;
414
415 ///
416@@ -45,14 +46,6 @@ extern UINT32 mTcpTick;
417
418 #define TCP_EXPIRE_TIME 65535
419
420-///
421-/// The implementation selects the initial send sequence number and the unit to
422-/// be added when it is increased.
423-///
424-#define TCP_BASE_ISS 0x4d7e980b
425-#define TCP_ISS_INCREMENT_1 2048
426-#define TCP_ISS_INCREMENT_2 100
427-
428 typedef union {
429 EFI_TCP4_CONFIG_DATA Tcp4CfgData;
430 EFI_TCP6_CONFIG_DATA Tcp6CfgData;
431@@ -774,4 +767,50 @@ Tcp6Poll (
432 IN EFI_TCP6_PROTOCOL *This
433 );
434
435+/**
436+ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local
437+ and remote IP addresses and ports.
438+
439+ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1
440+ Where the ISN is computed as follows:
441+ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret)
442+
443+ Otherwise:
444+ ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
445+
446+ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the
447+ connection's identifying parameters ("localip, localport, remoteip, remoteport")
448+ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the
449+ outside (MUST-9), or an attacker could still guess at sequence numbers from the
450+ ISN used for some other connection. The PRF could be implemented as a
451+ cryptographic hash of the concatenation of the TCP connection parameters and some
452+ secret data. For discussion of the selection of a specific hash algorithm and
453+ management of the secret key data."
454+
455+ @param[in] LocalIp A pointer to the local IP address of the TCP connection.
456+ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer.
457+ @param[in] LocalPort The local port number of the TCP connection.
458+ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection.
459+ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer.
460+ @param[in] RemotePort The remote port number of the TCP connection.
461+ @param[out] Isn A pointer to the variable that will receive the Initial
462+ Sequence Number (ISN).
463+
464+ @retval EFI_SUCCESS The operation completed successfully, and the ISN was
465+ retrieved.
466+ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid.
467+ @retval EFI_UNSUPPORTED The operation is not supported.
468+
469+**/
470+EFI_STATUS
471+TcpGetIsn (
472+ IN UINT8 *LocalIp,
473+ IN UINTN LocalIpSize,
474+ IN UINT16 LocalPort,
475+ IN UINT8 *RemoteIp,
476+ IN UINTN RemoteIpSize,
477+ IN UINT16 RemotePort,
478+ OUT TCP_SEQNO *Isn
479+ );
480+
481 #endif
482diff --git a/NetworkPkg/TcpDxe/TcpMisc.c b/NetworkPkg/TcpDxe/TcpMisc.c
483index c93212d47d..3310306f63 100644
484--- a/NetworkPkg/TcpDxe/TcpMisc.c
485+++ b/NetworkPkg/TcpDxe/TcpMisc.c
486@@ -3,7 +3,7 @@
487
488 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
489 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
490-
491+ Copyright (c) Microsoft Corporation
492 SPDX-License-Identifier: BSD-2-Clause-Patent
493
494 **/
495@@ -20,7 +20,34 @@ LIST_ENTRY mTcpListenQue = {
496 &mTcpListenQue
497 };
498
499-TCP_SEQNO mTcpGlobalIss = TCP_BASE_ISS;
500+//
501+// The Session secret
502+// This must be initialized to a random value at boot time
503+//
504+TCP_SEQNO mTcpGlobalSecret;
505+
506+//
507+// Union to hold either an IPv4 or IPv6 address
508+// This is used to simplify the ISN hash computation
509+//
510+typedef union {
511+ UINT8 IPv4[4];
512+ UINT8 IPv6[16];
513+} NETWORK_ADDRESS;
514+
515+//
516+// The ISN is computed by hashing this structure
517+// It is initialized with the local and remote IP addresses and ports
518+// and the secret
519+//
520+//
521+typedef struct {
522+ UINT16 LocalPort;
523+ UINT16 RemotePort;
524+ NETWORK_ADDRESS LocalAddress;
525+ NETWORK_ADDRESS RemoteAddress;
526+ TCP_SEQNO Secret;
527+} ISN_HASH_CTX;
528
529 CHAR16 *mTcpStateName[] = {
530 L"TCP_CLOSED",
531@@ -41,12 +68,18 @@ CHAR16 *mTcpStateName[] = {
532
533 @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
534
535+ @retval EFI_SUCCESS The operation completed successfully
536+ @retval others The underlying functions failed and could not complete the operation
537+
538 **/
539-VOID
540+EFI_STATUS
541 TcpInitTcbLocal (
542 IN OUT TCP_CB *Tcb
543 )
544 {
545+ TCP_SEQNO Isn;
546+ EFI_STATUS Status;
547+
548 //
549 // Compute the checksum of the fixed parts of pseudo header
550 //
551@@ -57,6 +90,16 @@ TcpInitTcbLocal (
552 0x06,
553 0
554 );
555+
556+ Status = TcpGetIsn (
557+ Tcb->LocalEnd.Ip.v4.Addr,
558+ sizeof (IPv4_ADDRESS),
559+ Tcb->LocalEnd.Port,
560+ Tcb->RemoteEnd.Ip.v4.Addr,
561+ sizeof (IPv4_ADDRESS),
562+ Tcb->RemoteEnd.Port,
563+ &Isn
564+ );
565 } else {
566 Tcb->HeadSum = NetIp6PseudoHeadChecksum (
567 &Tcb->LocalEnd.Ip.v6,
568@@ -64,9 +107,25 @@ TcpInitTcbLocal (
569 0x06,
570 0
571 );
572+
573+ Status = TcpGetIsn (
574+ Tcb->LocalEnd.Ip.v6.Addr,
575+ sizeof (IPv6_ADDRESS),
576+ Tcb->LocalEnd.Port,
577+ Tcb->RemoteEnd.Ip.v6.Addr,
578+ sizeof (IPv6_ADDRESS),
579+ Tcb->RemoteEnd.Port,
580+ &Isn
581+ );
582+ }
583+
584+ if (EFI_ERROR (Status)) {
585+ DEBUG ((DEBUG_ERROR, "TcpInitTcbLocal: failed to get isn\n"));
586+ ASSERT (FALSE);
587+ return Status;
588 }
589
590- Tcb->Iss = TcpGetIss ();
591+ Tcb->Iss = Isn;
592 Tcb->SndUna = Tcb->Iss;
593 Tcb->SndNxt = Tcb->Iss;
594
595@@ -82,6 +141,8 @@ TcpInitTcbLocal (
596 Tcb->RetxmitSeqMax = 0;
597
598 Tcb->ProbeTimerOn = FALSE;
599+
600+ return EFI_SUCCESS;
601 }
602
603 /**
604@@ -506,18 +567,162 @@ TcpCloneTcb (
605 }
606
607 /**
608- Compute an ISS to be used by a new connection.
609-
610- @return The resulting ISS.
611+ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local
612+ and remote IP addresses and ports.
613+
614+ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1
615+ Where the ISN is computed as follows:
616+ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret)
617+
618+ Otherwise:
619+ ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
620+
621+ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the
622+ connection's identifying parameters ("localip, localport, remoteip, remoteport")
623+ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the
624+ outside (MUST-9), or an attacker could still guess at sequence numbers from the
625+ ISN used for some other connection. The PRF could be implemented as a
626+ cryptographic hash of the concatenation of the TCP connection parameters and some
627+ secret data. For discussion of the selection of a specific hash algorithm and
628+ management of the secret key data."
629+
630+ @param[in] LocalIp A pointer to the local IP address of the TCP connection.
631+ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer.
632+ @param[in] LocalPort The local port number of the TCP connection.
633+ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection.
634+ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer.
635+ @param[in] RemotePort The remote port number of the TCP connection.
636+ @param[out] Isn A pointer to the variable that will receive the Initial
637+ Sequence Number (ISN).
638+
639+ @retval EFI_SUCCESS The operation completed successfully, and the ISN was
640+ retrieved.
641+ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid.
642+ @retval EFI_UNSUPPORTED The operation is not supported.
643
644 **/
645-TCP_SEQNO
646-TcpGetIss (
647- VOID
648+EFI_STATUS
649+TcpGetIsn (
650+ IN UINT8 *LocalIp,
651+ IN UINTN LocalIpSize,
652+ IN UINT16 LocalPort,
653+ IN UINT8 *RemoteIp,
654+ IN UINTN RemoteIpSize,
655+ IN UINT16 RemotePort,
656+ OUT TCP_SEQNO *Isn
657 )
658 {
659- mTcpGlobalIss += TCP_ISS_INCREMENT_1;
660- return mTcpGlobalIss;
661+ EFI_STATUS Status;
662+ EFI_HASH2_PROTOCOL *Hash2Protocol;
663+ EFI_HASH2_OUTPUT HashResult;
664+ ISN_HASH_CTX IsnHashCtx;
665+ EFI_TIME TimeStamp;
666+
667+ //
668+ // Check that the ISN pointer is valid
669+ //
670+ if (Isn == NULL) {
671+ return EFI_INVALID_PARAMETER;
672+ }
673+
674+ //
675+ // The local ip may be a v4 or v6 address and may not be NULL
676+ //
677+ if ((LocalIp == NULL) || (LocalIpSize == 0) || (RemoteIp == NULL) || (RemoteIpSize == 0)) {
678+ return EFI_INVALID_PARAMETER;
679+ }
680+
681+ //
682+ // the local ip may be a v4 or v6 address
683+ //
684+ if ((LocalIpSize != sizeof (EFI_IPv4_ADDRESS)) && (LocalIpSize != sizeof (EFI_IPv6_ADDRESS))) {
685+ return EFI_INVALID_PARAMETER;
686+ }
687+
688+ //
689+ // Locate the Hash Protocol
690+ //
691+ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
692+ if (EFI_ERROR (Status)) {
693+ DEBUG ((DEBUG_NET, "Failed to locate Hash Protocol: %r\n", Status));
694+
695+ //
696+ // TcpCreateService(..) is expected to be called prior to this function
697+ //
698+ ASSERT_EFI_ERROR (Status);
699+ return Status;
700+ }
701+
702+ //
703+ // Initialize the hash algorithm
704+ //
705+ Status = Hash2Protocol->HashInit (Hash2Protocol, &gEfiHashAlgorithmSha256Guid);
706+ if (EFI_ERROR (Status)) {
707+ DEBUG ((DEBUG_NET, "Failed to initialize sha256 hash algorithm: %r\n", Status));
708+ return Status;
709+ }
710+
711+ IsnHashCtx.LocalPort = LocalPort;
712+ IsnHashCtx.RemotePort = RemotePort;
713+ IsnHashCtx.Secret = mTcpGlobalSecret;
714+
715+ //
716+ // Check the IP address family and copy accordingly
717+ //
718+ if (LocalIpSize == sizeof (EFI_IPv4_ADDRESS)) {
719+ CopyMem (&IsnHashCtx.LocalAddress.IPv4, LocalIp, LocalIpSize);
720+ } else if (LocalIpSize == sizeof (EFI_IPv6_ADDRESS)) {
721+ CopyMem (&IsnHashCtx.LocalAddress.IPv6, LocalIp, LocalIpSize);
722+ } else {
723+ return EFI_INVALID_PARAMETER; // Unsupported address size
724+ }
725+
726+ //
727+ // Repeat the process for the remote IP address
728+ //
729+ if (RemoteIpSize == sizeof (EFI_IPv4_ADDRESS)) {
730+ CopyMem (&IsnHashCtx.RemoteAddress.IPv4, RemoteIp, RemoteIpSize);
731+ } else if (RemoteIpSize == sizeof (EFI_IPv6_ADDRESS)) {
732+ CopyMem (&IsnHashCtx.RemoteAddress.IPv6, RemoteIp, RemoteIpSize);
733+ } else {
734+ return EFI_INVALID_PARAMETER; // Unsupported address size
735+ }
736+
737+ //
738+ // Compute the hash
739+ // Update the hash with the data
740+ //
741+ Status = Hash2Protocol->HashUpdate (Hash2Protocol, (UINT8 *)&IsnHashCtx, sizeof (IsnHashCtx));
742+ if (EFI_ERROR (Status)) {
743+ DEBUG ((DEBUG_NET, "Failed to update hash: %r\n", Status));
744+ return Status;
745+ }
746+
747+ //
748+ // Finalize the hash and retrieve the result
749+ //
750+ Status = Hash2Protocol->HashFinal (Hash2Protocol, &HashResult);
751+ if (EFI_ERROR (Status)) {
752+ DEBUG ((DEBUG_NET, "Failed to finalize hash: %r\n", Status));
753+ return Status;
754+ }
755+
756+ Status = gRT->GetTime (&TimeStamp, NULL);
757+ if (EFI_ERROR (Status)) {
758+ return Status;
759+ }
760+
761+ //
762+ // copy the first 4 bytes of the hash result into the ISN
763+ //
764+ CopyMem (Isn, HashResult.Md5Hash, sizeof (*Isn));
765+
766+ //
767+ // now add the timestamp to the ISN as 4 microseconds units (1000 / 4 = 250)
768+ //
769+ *Isn += (TCP_SEQNO)TimeStamp.Nanosecond * 250;
770+
771+ return Status;
772 }
773
774 /**
775@@ -721,17 +926,28 @@ TcpFormatNetbuf (
776 @param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a
777 connection.
778
779+ @retval EFI_SUCCESS The operation completed successfully
780+ @retval others The underlying functions failed and could not complete the operation
781+
782 **/
783-VOID
784+EFI_STATUS
785 TcpOnAppConnect (
786 IN OUT TCP_CB *Tcb
787 )
788 {
789- TcpInitTcbLocal (Tcb);
790+ EFI_STATUS Status;
791+
792+ Status = TcpInitTcbLocal (Tcb);
793+ if (EFI_ERROR (Status)) {
794+ return Status;
795+ }
796+
797 TcpSetState (Tcb, TCP_SYN_SENT);
798
799 TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
800 TcpToSendData (Tcb, 1);
801+
802+ return EFI_SUCCESS;
803 }
804
805 /**
806diff --git a/NetworkPkg/TcpDxe/TcpTimer.c b/NetworkPkg/TcpDxe/TcpTimer.c
807index 5d2e124977..065b1bdf5f 100644
808--- a/NetworkPkg/TcpDxe/TcpTimer.c
809+++ b/NetworkPkg/TcpDxe/TcpTimer.c
810@@ -2,7 +2,7 @@
811 TCP timer related functions.
812
813 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
814-
815+ Copyright (c) Microsoft Corporation
816 SPDX-License-Identifier: BSD-2-Clause-Patent
817
818 **/
819@@ -483,7 +483,6 @@ TcpTickingDpc (
820 INT16 Index;
821
822 mTcpTick++;
823- mTcpGlobalIss += TCP_ISS_INCREMENT_2;
824
825 //
826 // Don't use LIST_FOR_EACH, which isn't delete safe.
827--
8282.40.0
829
diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb
index 47ed2c7cd3..dbfed086e4 100644
--- a/meta/recipes-core/ovmf/ovmf_git.bb
+++ b/meta/recipes-core/ovmf/ovmf_git.bb
@@ -49,6 +49,7 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
49 file://CVE-2023-45229-0004.patch \ 49 file://CVE-2023-45229-0004.patch \
50 file://CVE-2023-45237-0001.patch \ 50 file://CVE-2023-45237-0001.patch \
51 file://CVE-2023-45237-0002.patch \ 51 file://CVE-2023-45237-0002.patch \
52 file://CVE-2023-45236.patch \
52 " 53 "
53 54
54PV = "edk2-stable202202" 55PV = "edk2-stable202202"