diff --git a/0001-CryptoPkg-OpensslLib-Modify-process_files.pl-for-Ope.patch b/0001-CryptoPkg-OpensslLib-Modify-process_files.pl-for-Ope.patch deleted file mode 100644 index 9e46e174116fb3dac9ff026076a7bf46f7baec86..0000000000000000000000000000000000000000 --- a/0001-CryptoPkg-OpensslLib-Modify-process_files.pl-for-Ope.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 87c0bd44a43769905f3bb9bea4c8af307c58a79b Mon Sep 17 00:00:00 2001 -From: Xiang Zheng -Date: Fri, 17 Apr 2020 15:05:54 +0800 -Subject: [PATCH 1/2] CryptoPkg/OpensslLib: Modify process_files.pl for OpenSSL - 1.1.1f - -Before upgrading the version of OpenSSL to 1.1.1f, we need to update -process_files.pl so that we can auto-generate the correct files. - -This patch may confict with the opensource codes in the future, than -let it go with opensouce. - -Change-Id: Id17969bab444bad8cdd139258ef53d5eed91ff88 -Signed-off-by: Xiang Zheng ---- - .../Library/Include/{internal => crypto}/dso_conf.h | 0 - CryptoPkg/Library/OpensslLib/process_files.pl | 10 +++++----- - 2 files changed, 5 insertions(+), 5 deletions(-) - rename CryptoPkg/Library/Include/{internal => crypto}/dso_conf.h (100%) - -diff --git a/CryptoPkg/Library/Include/internal/dso_conf.h b/CryptoPkg/Library/Include/crypto/dso_conf.h -similarity index 100% -rename from CryptoPkg/Library/Include/internal/dso_conf.h -rename to CryptoPkg/Library/Include/crypto/dso_conf.h -diff --git a/CryptoPkg/Library/OpensslLib/process_files.pl b/CryptoPkg/Library/OpensslLib/process_files.pl -index bbcfa0d0..a99ad866 100755 ---- a/CryptoPkg/Library/OpensslLib/process_files.pl -+++ b/CryptoPkg/Library/OpensslLib/process_files.pl -@@ -109,8 +109,8 @@ BEGIN { - # Generate dso_conf.h per config data - system( - "perl -I. -Mconfigdata util/dofile.pl " . -- "crypto/include/internal/dso_conf.h.in " . -- "> include/internal/dso_conf.h" -+ "include/crypto/dso_conf.h.in " . -+ "> include/crypto/dso_conf.h" - ) == 0 || - die "Failed to generate dso_conf.h!\n"; - -@@ -264,9 +264,9 @@ copy($OPENSSL_PATH . "/include/openssl/opensslconf.h", - $OPENSSL_PATH . "/../../Include/openssl/") || - die "Cannot copy opensslconf.h!"; - print "Done!"; --print "\n--> Duplicating dso_conf.h into Include/internal ... "; --copy($OPENSSL_PATH . "/include/internal/dso_conf.h", -- $OPENSSL_PATH . "/../../Include/internal/") || -+print "\n--> Duplicating dso_conf.h into Include/crypto ... "; -+copy($OPENSSL_PATH . "/include/crypto/dso_conf.h", -+ $OPENSSL_PATH . "/../../Include/crypto/") || - die "Cannot copy dso_conf.h!"; - print "Done!\n"; - --- -2.19.1 - diff --git a/0018-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch b/0001-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch similarity index 100% rename from 0018-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch rename to 0001-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch diff --git a/0002-CryptoPkg-Upgrade-OpenSSL-to-1.1.1f.patch b/0002-CryptoPkg-Upgrade-OpenSSL-to-1.1.1f.patch deleted file mode 100644 index b022c171028de0cc3a112ac28e32355226b3e54c..0000000000000000000000000000000000000000 --- a/0002-CryptoPkg-Upgrade-OpenSSL-to-1.1.1f.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 55d39c51a03048f4bb1218fc70a9ed445e2b75f6 Mon Sep 17 00:00:00 2001 -From: Xiang Zheng -Date: Mon, 20 Apr 2020 17:40:25 +0800 -Subject: [PATCH 2/2] CryptoPkg: Upgrade OpenSSL to 1.1.1f - -Upgrade OpenSLL to 1.1.1f - -Signed-off-by: Xiang Zheng ---- - CryptoPkg/CryptoPkg.dec | 1 - - .../Library/BaseCryptLib/Hash/CryptSm3.c | 2 +- - .../BaseCryptLib/Pk/CryptPkcs7VerifyEku.c | 4 +- - CryptoPkg/Library/Include/crypto/dso_conf.h | 6 +- - .../Library/Include/openssl/opensslconf.h | 3 - - CryptoPkg/Library/OpensslLib/OpensslLib.inf | 88 +++++++++---------- - .../Library/OpensslLib/OpensslLibCrypto.inf | 78 ++++++++-------- - CryptoPkg/Library/OpensslLib/rand_pool.c | 2 +- - 8 files changed, 90 insertions(+), 94 deletions(-) - -diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec -index 4d1a1368..5888941b 100644 ---- a/CryptoPkg/CryptoPkg.dec -+++ b/CryptoPkg/CryptoPkg.dec -@@ -23,7 +23,6 @@ - Private - Library/Include - Library/OpensslLib/openssl/include -- Library/OpensslLib/openssl/crypto/include - - [LibraryClasses] - ## @libraryclass Provides basic library functions for cryptographic primitives. -diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3.c -index eacf4826..235331c2 100644 ---- a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3.c -+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3.c -@@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - **/ - - #include "InternalCryptLib.h" --#include "internal/sm3.h" -+#include "crypto/sm3.h" - - /** - Retrieves the size, in bytes, of the context buffer required for SM3 hash operations. -diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEku.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEku.c -index 229c244b..c9fdb65b 100644 ---- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEku.c -+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEku.c -@@ -15,13 +15,13 @@ - #include - #include - #include --#include -+#include - #include - #include - #include - #include - #include --#include -+#include - - /** - This function will return the leaf signer certificate in a chain. This is -diff --git a/CryptoPkg/Library/Include/crypto/dso_conf.h b/CryptoPkg/Library/Include/crypto/dso_conf.h -index 43c89158..abbbf62c 100644 ---- a/CryptoPkg/Library/Include/crypto/dso_conf.h -+++ b/CryptoPkg/Library/Include/crypto/dso_conf.h -@@ -1,5 +1,5 @@ - /* WARNING: do not edit! */ --/* Generated from crypto/include/internal/dso_conf.h.in */ -+/* Generated from include/crypto/dso_conf.h.in */ - /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. - * -@@ -9,8 +9,8 @@ - * https://www.openssl.org/source/license.html - */ - --#ifndef HEADER_DSO_CONF_H --# define HEADER_DSO_CONF_H -+#ifndef OSSL_CRYPTO_DSO_CONF_H -+# define OSSL_CRYPTO_DSO_CONF_H - # define DSO_NONE - # define DSO_EXTENSION ".so" - #endif -diff --git a/CryptoPkg/Library/Include/openssl/opensslconf.h b/CryptoPkg/Library/Include/openssl/opensslconf.h -index 2b4d538e..a27aa658 100644 ---- a/CryptoPkg/Library/Include/openssl/opensslconf.h -+++ b/CryptoPkg/Library/Include/openssl/opensslconf.h -@@ -241,9 +241,6 @@ extern "C" { - #ifndef OPENSSL_NO_DYNAMIC_ENGINE - # define OPENSSL_NO_DYNAMIC_ENGINE - #endif --#ifndef OPENSSL_NO_AFALGENG --# define OPENSSL_NO_AFALGENG --#endif - - - /* -diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -index 3fa52f55..a010e6bc 100644 ---- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf -+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf -@@ -494,57 +494,57 @@ - $(OPENSSL_PATH)/crypto/x509v3/v3_tlsf.c - $(OPENSSL_PATH)/crypto/x509v3/v3_utl.c - $(OPENSSL_PATH)/crypto/x509v3/v3err.c -- $(OPENSSL_PATH)/crypto/hmac/hmac_lcl.h -- $(OPENSSL_PATH)/crypto/dh/dh_locl.h -- $(OPENSSL_PATH)/crypto/bio/bio_lcl.h -- $(OPENSSL_PATH)/crypto/conf/conf_def.h -- $(OPENSSL_PATH)/crypto/conf/conf_lcl.h -- $(OPENSSL_PATH)/crypto/lhash/lhash_lcl.h -- $(OPENSSL_PATH)/crypto/sha/sha_locl.h -- $(OPENSSL_PATH)/crypto/md5/md5_locl.h -- $(OPENSSL_PATH)/crypto/store/store_locl.h -- $(OPENSSL_PATH)/crypto/dso/dso_locl.h -- $(OPENSSL_PATH)/crypto/pkcs12/p12_lcl.h -+ $(OPENSSL_PATH)/crypto/dso/dso_local.h -+ $(OPENSSL_PATH)/crypto/dh/dh_local.h -+ $(OPENSSL_PATH)/crypto/rc4/rc4_local.h -+ $(OPENSSL_PATH)/crypto/ui/ui_local.h -+ $(OPENSSL_PATH)/crypto/async/async_local.h -+ $(OPENSSL_PATH)/crypto/modes/modes_local.h -+ $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.h -+ $(OPENSSL_PATH)/crypto/asn1/asn1_local.h -+ $(OPENSSL_PATH)/crypto/asn1/charmap.h -+ $(OPENSSL_PATH)/crypto/asn1/standard_methods.h -+ $(OPENSSL_PATH)/crypto/asn1/tbl_standard.h -+ $(OPENSSL_PATH)/crypto/md4/md4_local.h -+ $(OPENSSL_PATH)/crypto/rand/rand_local.h -+ $(OPENSSL_PATH)/crypto/pkcs12/p12_local.h -+ $(OPENSSL_PATH)/crypto/lhash/lhash_local.h -+ $(OPENSSL_PATH)/crypto/evp/evp_local.h -+ $(OPENSSL_PATH)/crypto/rsa/rsa_local.h -+ $(OPENSSL_PATH)/crypto/bn/bn_local.h -+ $(OPENSSL_PATH)/crypto/bn/bn_prime.h -+ $(OPENSSL_PATH)/crypto/bn/rsaz_exp.h -+ $(OPENSSL_PATH)/crypto/des/des_local.h -+ $(OPENSSL_PATH)/crypto/des/spr.h - $(OPENSSL_PATH)/crypto/arm_arch.h - $(OPENSSL_PATH)/crypto/mips_arch.h - $(OPENSSL_PATH)/crypto/ppc_arch.h - $(OPENSSL_PATH)/crypto/s390x_arch.h - $(OPENSSL_PATH)/crypto/sparc_arch.h - $(OPENSSL_PATH)/crypto/vms_rms.h -- $(OPENSSL_PATH)/crypto/bn/bn_lcl.h -- $(OPENSSL_PATH)/crypto/bn/bn_prime.h -- $(OPENSSL_PATH)/crypto/bn/rsaz_exp.h -- $(OPENSSL_PATH)/crypto/ui/ui_locl.h -- $(OPENSSL_PATH)/crypto/md4/md4_locl.h -- $(OPENSSL_PATH)/crypto/rc4/rc4_locl.h -- $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.h -- $(OPENSSL_PATH)/crypto/asn1/asn1_locl.h -- $(OPENSSL_PATH)/crypto/asn1/charmap.h -- $(OPENSSL_PATH)/crypto/asn1/standard_methods.h -- $(OPENSSL_PATH)/crypto/asn1/tbl_standard.h -- $(OPENSSL_PATH)/crypto/evp/evp_locl.h -- $(OPENSSL_PATH)/crypto/rand/rand_lcl.h -- $(OPENSSL_PATH)/crypto/ocsp/ocsp_lcl.h -- $(OPENSSL_PATH)/crypto/modes/modes_lcl.h -- $(OPENSSL_PATH)/crypto/comp/comp_lcl.h -- $(OPENSSL_PATH)/crypto/rsa/rsa_locl.h -- $(OPENSSL_PATH)/crypto/x509/x509_lcl.h -+ $(OPENSSL_PATH)/crypto/ocsp/ocsp_local.h -+ $(OPENSSL_PATH)/crypto/md5/md5_local.h -+ $(OPENSSL_PATH)/crypto/aes/aes_local.h -+ $(OPENSSL_PATH)/crypto/store/store_local.h -+ $(OPENSSL_PATH)/crypto/objects/obj_dat.h -+ $(OPENSSL_PATH)/crypto/objects/obj_local.h -+ $(OPENSSL_PATH)/crypto/objects/obj_xref.h -+ $(OPENSSL_PATH)/crypto/hmac/hmac_local.h - $(OPENSSL_PATH)/crypto/async/arch/async_null.h - $(OPENSSL_PATH)/crypto/async/arch/async_posix.h - $(OPENSSL_PATH)/crypto/async/arch/async_win.h -- $(OPENSSL_PATH)/crypto/sm3/sm3_locl.h -- $(OPENSSL_PATH)/crypto/des/des_locl.h -- $(OPENSSL_PATH)/crypto/des/spr.h -- $(OPENSSL_PATH)/crypto/siphash/siphash_local.h -- $(OPENSSL_PATH)/crypto/aes/aes_locl.h -- $(OPENSSL_PATH)/crypto/async/async_locl.h - $(OPENSSL_PATH)/crypto/x509v3/ext_dat.h -- $(OPENSSL_PATH)/crypto/x509v3/pcy_int.h -+ $(OPENSSL_PATH)/crypto/x509v3/pcy_local.h - $(OPENSSL_PATH)/crypto/x509v3/standard_exts.h - $(OPENSSL_PATH)/crypto/x509v3/v3_admis.h -- $(OPENSSL_PATH)/crypto/objects/obj_dat.h -- $(OPENSSL_PATH)/crypto/objects/obj_lcl.h -- $(OPENSSL_PATH)/crypto/objects/obj_xref.h -+ $(OPENSSL_PATH)/crypto/conf/conf_def.h -+ $(OPENSSL_PATH)/crypto/conf/conf_local.h -+ $(OPENSSL_PATH)/crypto/comp/comp_local.h -+ $(OPENSSL_PATH)/crypto/sha/sha_local.h -+ $(OPENSSL_PATH)/crypto/x509/x509_local.h -+ $(OPENSSL_PATH)/crypto/sm3/sm3_local.h -+ $(OPENSSL_PATH)/crypto/bio/bio_local.h -+ $(OPENSSL_PATH)/crypto/siphash/siphash_local.h - $(OPENSSL_PATH)/ssl/bio_ssl.c - $(OPENSSL_PATH)/ssl/d1_lib.c - $(OPENSSL_PATH)/ssl/d1_msg.c -@@ -589,13 +589,13 @@ - $(OPENSSL_PATH)/ssl/t1_trce.c - $(OPENSSL_PATH)/ssl/tls13_enc.c - $(OPENSSL_PATH)/ssl/tls_srp.c -- $(OPENSSL_PATH)/ssl/statem/statem.h -- $(OPENSSL_PATH)/ssl/statem/statem_locl.h -- $(OPENSSL_PATH)/ssl/packet_locl.h -+ $(OPENSSL_PATH)/ssl/packet_local.h - $(OPENSSL_PATH)/ssl/ssl_cert_table.h -- $(OPENSSL_PATH)/ssl/ssl_locl.h -+ $(OPENSSL_PATH)/ssl/ssl_local.h -+ $(OPENSSL_PATH)/ssl/statem/statem.h -+ $(OPENSSL_PATH)/ssl/statem/statem_local.h - $(OPENSSL_PATH)/ssl/record/record.h -- $(OPENSSL_PATH)/ssl/record/record_locl.h -+ $(OPENSSL_PATH)/ssl/record/record_local.h - # Autogenerated files list ends here - buildinf.h - rand_pool_noise.h -diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf -index f1f9fbb9..de8a9ef2 100644 ---- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf -+++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf -@@ -494,57 +494,57 @@ - $(OPENSSL_PATH)/crypto/x509v3/v3_tlsf.c - $(OPENSSL_PATH)/crypto/x509v3/v3_utl.c - $(OPENSSL_PATH)/crypto/x509v3/v3err.c -- $(OPENSSL_PATH)/crypto/hmac/hmac_lcl.h -- $(OPENSSL_PATH)/crypto/dh/dh_locl.h -- $(OPENSSL_PATH)/crypto/bio/bio_lcl.h -- $(OPENSSL_PATH)/crypto/conf/conf_def.h -- $(OPENSSL_PATH)/crypto/conf/conf_lcl.h -- $(OPENSSL_PATH)/crypto/lhash/lhash_lcl.h -- $(OPENSSL_PATH)/crypto/sha/sha_locl.h -- $(OPENSSL_PATH)/crypto/md5/md5_locl.h -- $(OPENSSL_PATH)/crypto/store/store_locl.h -- $(OPENSSL_PATH)/crypto/dso/dso_locl.h -- $(OPENSSL_PATH)/crypto/pkcs12/p12_lcl.h -+ $(OPENSSL_PATH)/crypto/dso/dso_local.h -+ $(OPENSSL_PATH)/crypto/dh/dh_local.h -+ $(OPENSSL_PATH)/crypto/rc4/rc4_local.h -+ $(OPENSSL_PATH)/crypto/ui/ui_local.h -+ $(OPENSSL_PATH)/crypto/async/async_local.h -+ $(OPENSSL_PATH)/crypto/modes/modes_local.h -+ $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.h -+ $(OPENSSL_PATH)/crypto/asn1/asn1_local.h -+ $(OPENSSL_PATH)/crypto/asn1/charmap.h -+ $(OPENSSL_PATH)/crypto/asn1/standard_methods.h -+ $(OPENSSL_PATH)/crypto/asn1/tbl_standard.h -+ $(OPENSSL_PATH)/crypto/md4/md4_local.h -+ $(OPENSSL_PATH)/crypto/rand/rand_local.h -+ $(OPENSSL_PATH)/crypto/pkcs12/p12_local.h -+ $(OPENSSL_PATH)/crypto/lhash/lhash_local.h -+ $(OPENSSL_PATH)/crypto/evp/evp_local.h -+ $(OPENSSL_PATH)/crypto/rsa/rsa_local.h -+ $(OPENSSL_PATH)/crypto/bn/bn_local.h -+ $(OPENSSL_PATH)/crypto/bn/bn_prime.h -+ $(OPENSSL_PATH)/crypto/bn/rsaz_exp.h -+ $(OPENSSL_PATH)/crypto/des/des_local.h -+ $(OPENSSL_PATH)/crypto/des/spr.h - $(OPENSSL_PATH)/crypto/arm_arch.h - $(OPENSSL_PATH)/crypto/mips_arch.h - $(OPENSSL_PATH)/crypto/ppc_arch.h - $(OPENSSL_PATH)/crypto/s390x_arch.h - $(OPENSSL_PATH)/crypto/sparc_arch.h - $(OPENSSL_PATH)/crypto/vms_rms.h -- $(OPENSSL_PATH)/crypto/bn/bn_lcl.h -- $(OPENSSL_PATH)/crypto/bn/bn_prime.h -- $(OPENSSL_PATH)/crypto/bn/rsaz_exp.h -- $(OPENSSL_PATH)/crypto/ui/ui_locl.h -- $(OPENSSL_PATH)/crypto/md4/md4_locl.h -- $(OPENSSL_PATH)/crypto/rc4/rc4_locl.h -- $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.h -- $(OPENSSL_PATH)/crypto/asn1/asn1_locl.h -- $(OPENSSL_PATH)/crypto/asn1/charmap.h -- $(OPENSSL_PATH)/crypto/asn1/standard_methods.h -- $(OPENSSL_PATH)/crypto/asn1/tbl_standard.h -- $(OPENSSL_PATH)/crypto/evp/evp_locl.h -- $(OPENSSL_PATH)/crypto/rand/rand_lcl.h -- $(OPENSSL_PATH)/crypto/ocsp/ocsp_lcl.h -- $(OPENSSL_PATH)/crypto/modes/modes_lcl.h -- $(OPENSSL_PATH)/crypto/comp/comp_lcl.h -- $(OPENSSL_PATH)/crypto/rsa/rsa_locl.h -- $(OPENSSL_PATH)/crypto/x509/x509_lcl.h -+ $(OPENSSL_PATH)/crypto/ocsp/ocsp_local.h -+ $(OPENSSL_PATH)/crypto/md5/md5_local.h -+ $(OPENSSL_PATH)/crypto/aes/aes_local.h -+ $(OPENSSL_PATH)/crypto/store/store_local.h -+ $(OPENSSL_PATH)/crypto/objects/obj_dat.h -+ $(OPENSSL_PATH)/crypto/objects/obj_local.h -+ $(OPENSSL_PATH)/crypto/objects/obj_xref.h -+ $(OPENSSL_PATH)/crypto/hmac/hmac_local.h - $(OPENSSL_PATH)/crypto/async/arch/async_null.h - $(OPENSSL_PATH)/crypto/async/arch/async_posix.h - $(OPENSSL_PATH)/crypto/async/arch/async_win.h -- $(OPENSSL_PATH)/crypto/sm3/sm3_locl.h -- $(OPENSSL_PATH)/crypto/des/des_locl.h -- $(OPENSSL_PATH)/crypto/des/spr.h -- $(OPENSSL_PATH)/crypto/siphash/siphash_local.h -- $(OPENSSL_PATH)/crypto/aes/aes_locl.h -- $(OPENSSL_PATH)/crypto/async/async_locl.h - $(OPENSSL_PATH)/crypto/x509v3/ext_dat.h -- $(OPENSSL_PATH)/crypto/x509v3/pcy_int.h -+ $(OPENSSL_PATH)/crypto/x509v3/pcy_local.h - $(OPENSSL_PATH)/crypto/x509v3/standard_exts.h - $(OPENSSL_PATH)/crypto/x509v3/v3_admis.h -- $(OPENSSL_PATH)/crypto/objects/obj_dat.h -- $(OPENSSL_PATH)/crypto/objects/obj_lcl.h -- $(OPENSSL_PATH)/crypto/objects/obj_xref.h -+ $(OPENSSL_PATH)/crypto/conf/conf_def.h -+ $(OPENSSL_PATH)/crypto/conf/conf_local.h -+ $(OPENSSL_PATH)/crypto/comp/comp_local.h -+ $(OPENSSL_PATH)/crypto/sha/sha_local.h -+ $(OPENSSL_PATH)/crypto/x509/x509_local.h -+ $(OPENSSL_PATH)/crypto/sm3/sm3_local.h -+ $(OPENSSL_PATH)/crypto/bio/bio_local.h -+ $(OPENSSL_PATH)/crypto/siphash/siphash_local.h - # Autogenerated files list ends here - buildinf.h - rand_pool_noise.h -diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/OpensslLib/rand_pool.c -index 9f3983f7..9e0179b0 100644 ---- a/CryptoPkg/Library/OpensslLib/rand_pool.c -+++ b/CryptoPkg/Library/OpensslLib/rand_pool.c -@@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent - - **/ - --#include "internal/rand_int.h" -+#include "crypto/rand.h" - #include - - #include --- -2.19.1 - diff --git a/0019-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch b/0002-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch similarity index 100% rename from 0019-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch rename to 0002-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch diff --git a/0020-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch b/0003-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch similarity index 100% rename from 0020-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch rename to 0003-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch diff --git a/0003-OvmfPkg-Tcg2ConfigPei-introduce-a-signalling-PPI-to-.patch b/0003-OvmfPkg-Tcg2ConfigPei-introduce-a-signalling-PPI-to-.patch deleted file mode 100644 index 670aaa0306d199a44cf227ac64b45f38e43ac44a..0000000000000000000000000000000000000000 --- a/0003-OvmfPkg-Tcg2ConfigPei-introduce-a-signalling-PPI-to-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From bf5008f94fd887f7f9c1daf1a09f47c0733d38ed Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:06 +0100 -Subject: [PATCH 03/13] OvmfPkg/Tcg2ConfigPei: introduce a signalling PPI to - depex on - -On ARM systems, the TPM does not live at a fixed address, and so we -need the platform to discover it first. So introduce a PPI that signals -that the TPM address has been discovered and recorded in the appropriate -PCD, and make Tcg2ConfigPei depex on it when built for ARM or AARCH64. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - OvmfPkg/OvmfPkg.dec | 5 +++++ - OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf | 6 +++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec -index 4c5b651..7c27f01 100644 ---- a/OvmfPkg/OvmfPkg.dec -+++ b/OvmfPkg/OvmfPkg.dec -@@ -87,6 +87,11 @@ - gEfiLegacyBiosGuid = {0x2E3044AC, 0x879F, 0x490F, {0x97, 0x60, 0xBB, 0xDF, 0xAF, 0x69, 0x5F, 0x50}} - gEfiLegacyDevOrderVariableGuid = {0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52}} - -+[Ppis] -+ # PPI whose presence in the PPI database signals that the TPM base address -+ # has been discovered and recorded -+ gOvmfTpmDiscoveredPpiGuid = {0xb9a61ad0, 0x2802, 0x41f3, {0xb5, 0x13, 0x96, 0x51, 0xce, 0x6b, 0xd5, 0x75}} -+ - [Protocols] - gVirtioDeviceProtocolGuid = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}} - gXenBusProtocolGuid = {0x3d3ca290, 0xb9a5, 0x11e3, {0xb7, 0x5d, 0xb8, 0xac, 0x6f, 0x7d, 0x65, 0xe6}} -diff --git a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -index e34cd62..6673ce0 100644 ---- a/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -+++ b/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -@@ -25,6 +25,7 @@ - [Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec -+ OvmfPkg/OvmfPkg.dec - SecurityPkg/SecurityPkg.dec - - [LibraryClasses] -@@ -43,5 +44,8 @@ - [Pcd] - gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES - --[Depex] -+[Depex.IA32, Depex.X64] - TRUE -+ -+[Depex.ARM, Depex.AARCH64] -+ gOvmfTpmDiscoveredPpiGuid --- -2.18.2 - diff --git a/0004-ArmVirtPkg-PlatformPeiLib-make-PcdLib-dependency-exp.patch b/0004-ArmVirtPkg-PlatformPeiLib-make-PcdLib-dependency-exp.patch deleted file mode 100644 index 33ef20c8eb52ff3bebc94cb6f56f2bf8f0f6d500..0000000000000000000000000000000000000000 --- a/0004-ArmVirtPkg-PlatformPeiLib-make-PcdLib-dependency-exp.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 4b9b1a6908eae0440b0d230d3ac39c6ff2a3f15f Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:07 +0100 -Subject: [PATCH 04/13] ArmVirtPkg/PlatformPeiLib: make PcdLib dependency - explicit in .INF - -We currently include PcdLib.h in PlatformPeiLib, without declaring -this dependency in its .INF description. Since all the PCDs we use -resolve to fixed type in practice, this does not really matter at -the moment, but since we will be adding dynamic PCD references in -a subsequent patch, let's make the PcdLib dependency explicit, so -that its dispatch is guaranteed to be ordered correctly with respect -to the provider of the dynamic PCD PPI. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -index 46db117..1ef04d1 100644 ---- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -+++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -@@ -29,6 +29,7 @@ - DebugLib - HobLib - FdtLib -+ PcdLib - - [FixedPcd] - gArmTokenSpaceGuid.PcdFvSize --- -2.18.2 - diff --git a/0021-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch b/0004-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch similarity index 100% rename from 0021-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch rename to 0004-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch diff --git a/0005-ArmVirtPkg-PlatformPeiLib-discover-the-TPM-base-addr.patch b/0005-ArmVirtPkg-PlatformPeiLib-discover-the-TPM-base-addr.patch deleted file mode 100644 index c80e7dbe59789ec36136eb58d62e5131e155af27..0000000000000000000000000000000000000000 --- a/0005-ArmVirtPkg-PlatformPeiLib-discover-the-TPM-base-addr.patch +++ /dev/null @@ -1,318 +0,0 @@ -From f1bb8ca123be4d0194a9f65b93a9c65c85861b50 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:08 +0100 -Subject: [PATCH 05/13] ArmVirtPkg/PlatformPeiLib: discover the TPM base - address from the DT - -Introduce a boolean PCD that tells us whether TPM support is enabled -in the build, and if it is, record the TPM base address in the existing -routine that traverses the device tree in the platform PEIM. - -If a TPM is found, install the gOvmfTpmDiscoveredPpiGuid signalling PPI -that will unlock the dispatch of OvmfPkg's Tcg2ConfigPei. If TPM2 -support is enabled in the build but no TPM2 device is found, install the -gPeiTpmInitializationDonePpiGuid PPI, which is normally installed by -Tcg2ConfigPei if no TPM2 is found, but in our case Tcg2ConfigPei will -never run so let's do it here instead. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Acked-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtPkg.dec | 6 ++ - ArmVirtPkg/ArmVirtQemu.dsc | 5 + - ArmVirtPkg/ArmVirtQemuKernel.dsc | 6 ++ - ArmVirtPkg/ArmVirtXen.dsc | 6 ++ - .../Library/PlatformPeiLib/PlatformPeiLib.c | 101 ++++++++++++++++-- - .../Library/PlatformPeiLib/PlatformPeiLib.inf | 19 +++- - 6 files changed, 129 insertions(+), 14 deletions(-) - -diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec -index a019cc2..0619efc 100644 ---- a/ArmVirtPkg/ArmVirtPkg.dec -+++ b/ArmVirtPkg/ArmVirtPkg.dec -@@ -36,6 +36,12 @@ - [Protocols] - gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } } - -+[PcdsFeatureFlag] -+ # -+ # Feature Flag PCD that defines whether TPM2 support is enabled -+ # -+ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|FALSE|BOOLEAN|0x00000004 -+ - [PcdsFixedAtBuild, PcdsPatchableInModule] - # - # This is the physical address where the device tree is expected to be stored -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 7ae6702..984df5c 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -237,6 +237,11 @@ - gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 - gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE - -+ # -+ # TPM2 support -+ # -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0 -+ - [PcdsDynamicHii] - gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS - -diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc -index 3b0f049..8243876 100644 ---- a/ArmVirtPkg/ArmVirtQemuKernel.dsc -+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc -@@ -172,6 +172,12 @@ - gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3 - - [PcdsPatchableInModule.common] -+ # we need to provide a resolution for this PCD that supports PcdSet64() -+ # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c, -+ # even though that call will be compiled out on this platform as it does -+ # not (and cannot) support the TPM2 driver stack -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0 -+ - # - # This will be overridden in the code - # -diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc -index 1b42a9a..8a6ace2 100644 ---- a/ArmVirtPkg/ArmVirtXen.dsc -+++ b/ArmVirtPkg/ArmVirtXen.dsc -@@ -95,6 +95,12 @@ - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE - - [PcdsPatchableInModule.common] -+ # we need to provide a resolution for this PCD that supports PcdSet64() -+ # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c, -+ # even though that call will be compiled out on this platform as it does -+ # not (and cannot) support the TPM2 driver stack -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0 -+ - # - # This will be overridden in the code - # -diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c -index 0a14695..eabd800 100644 ---- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c -+++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c -@@ -1,7 +1,7 @@ - /** @file - * - * Copyright (c) 2011-2014, ARM Limited. All rights reserved. --* Copyright (c) 2014, Linaro Limited. All rights reserved. -+* Copyright (c) 2014-2020, Linaro Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-2-Clause-Patent - * -@@ -13,11 +13,24 @@ - #include - #include - #include -+#include - #include - - #include - #include - -+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = { -+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, -+ &gOvmfTpmDiscoveredPpiGuid, -+ NULL -+}; -+ -+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = { -+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, -+ &gPeiTpmInitializationDonePpiGuid, -+ NULL -+}; -+ - EFI_STATUS - EFIAPI - PlatformPeim ( -@@ -31,14 +44,18 @@ PlatformPeim ( - UINT64 *FdtHobData; - UINT64 *UartHobData; - INT32 Node, Prev; -+ INT32 Parent, Depth; - CONST CHAR8 *Compatible; - CONST CHAR8 *CompItem; - CONST CHAR8 *NodeStatus; - INT32 Len; -+ INT32 RangesLen; - INT32 StatusLen; - CONST UINT64 *RegProp; -+ CONST UINT32 *RangesProp; - UINT64 UartBase; -- -+ UINT64 TpmBase; -+ EFI_STATUS Status; - - Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); - ASSERT (Base != NULL); -@@ -58,18 +75,18 @@ PlatformPeim ( - ASSERT (UartHobData != NULL); - *UartHobData = 0; - -- // -- // Look for a UART node -- // -- for (Prev = 0;; Prev = Node) { -- Node = fdt_next_node (Base, Prev, NULL); -+ TpmBase = 0; -+ -+ for (Prev = Depth = 0;; Prev = Node) { -+ Node = fdt_next_node (Base, Prev, &Depth); - if (Node < 0) { - break; - } - -- // -- // Check for UART node -- // -+ if (Depth == 1) { -+ Parent = Node; -+ } -+ - Compatible = fdt_getprop (Base, Node, "compatible", &Len); - - // -@@ -93,10 +110,74 @@ PlatformPeim ( - - *UartHobData = UartBase; - break; -+ } else if (FeaturePcdGet (PcdTpm2SupportEnabled) && -+ AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0) { -+ -+ RegProp = fdt_getprop (Base, Node, "reg", &Len); -+ ASSERT (Len == 8 || Len == 16); -+ if (Len == 8) { -+ TpmBase = fdt32_to_cpu (RegProp[0]); -+ } else if (Len == 16) { -+ TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp)); -+ } -+ -+ if (Depth > 1) { -+ // -+ // QEMU/mach-virt may put the TPM on the platform bus, in which case -+ // we have to take its 'ranges' property into account to translate the -+ // MMIO address. This consists of a -+ // tuple, where the child base and the size use the same number of -+ // cells as the 'reg' property above, and the parent base uses 2 cells -+ // -+ RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen); -+ ASSERT (RangesProp != NULL); -+ -+ // -+ // a plain 'ranges' attribute without a value implies a 1:1 mapping -+ // -+ if (RangesLen != 0) { -+ // -+ // assume a single translated range with 2 cells for the parent base -+ // -+ if (RangesLen != Len + 2 * sizeof (UINT32)) { -+ DEBUG ((DEBUG_WARN, -+ "%a: 'ranges' property has unexpected size %d\n", -+ __FUNCTION__, RangesLen)); -+ break; -+ } -+ -+ if (Len == 8) { -+ TpmBase -= fdt32_to_cpu (RangesProp[0]); -+ } else { -+ TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp)); -+ } -+ -+ // -+ // advance RangesProp to the parent bus address -+ // -+ RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2); -+ TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp)); -+ } -+ } -+ break; - } - } - } - -+ if (FeaturePcdGet (PcdTpm2SupportEnabled)) { -+ if (TpmBase != 0) { -+ DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase)); -+ -+ Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase); -+ ASSERT_EFI_ERROR (Status); -+ -+ Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi); -+ } else { -+ Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi); -+ } -+ ASSERT_EFI_ERROR (Status); -+ } -+ - BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize)); - - return EFI_SUCCESS; -diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -index 1ef04d1..5dae4df 100644 ---- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -+++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf -@@ -1,7 +1,7 @@ - #/** @file - # - # Copyright (c) 2011-2015, ARM Limited. All rights reserved. --# Copyright (c) 2014, Linaro Limited. All rights reserved. -+# Copyright (c) 2014-2020, Linaro Limited. All rights reserved. - # - # SPDX-License-Identifier: BSD-2-Clause-Patent - # -@@ -11,7 +11,7 @@ - INF_VERSION = 0x00010005 - BASE_NAME = PlatformPeiLib - FILE_GUID = 59C11815-F8DA-4F49-B4FB-EC1E41ED1F06 -- MODULE_TYPE = SEC -+ MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = PlatformPeiLib - -@@ -21,15 +21,21 @@ - [Packages] - ArmPkg/ArmPkg.dec - ArmVirtPkg/ArmVirtPkg.dec -- MdePkg/MdePkg.dec -- MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ MdePkg/MdePkg.dec -+ OvmfPkg/OvmfPkg.dec -+ SecurityPkg/SecurityPkg.dec -+ -+[FeaturePcd] -+ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled - - [LibraryClasses] - DebugLib - HobLib - FdtLib - PcdLib -+ PeiServicesLib - - [FixedPcd] - gArmTokenSpaceGuid.PcdFvSize -@@ -38,6 +44,11 @@ - [Pcd] - gArmTokenSpaceGuid.PcdFvBaseAddress - gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_PRODUCES -+ -+[Ppis] -+ gOvmfTpmDiscoveredPpiGuid ## SOMETIMES_PRODUCES -+ gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES - - [Guids] - gEarlyPL011BaseAddressGuid --- -2.18.2 - diff --git a/0022-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch b/0005-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch similarity index 100% rename from 0022-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch rename to 0005-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch diff --git a/0006-ArmVirtPkg-implement-ArmVirtPsciResetSystemPeiLib.patch b/0006-ArmVirtPkg-implement-ArmVirtPsciResetSystemPeiLib.patch deleted file mode 100644 index e6458bcefaf04e10fc697fc6c8fe33e40f4fa195..0000000000000000000000000000000000000000 --- a/0006-ArmVirtPkg-implement-ArmVirtPsciResetSystemPeiLib.patch +++ /dev/null @@ -1,311 +0,0 @@ -From be6f854c61807ab26d7cc6db797876ed00d54469 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:09 +0100 -Subject: [PATCH 06/13] ArmVirtPkg: implement ArmVirtPsciResetSystemPeiLib - -Implement a ArmVirtPkg specific version of the PSCI ResetSystemLib that -is usable in the PEI phase, as the existing one relies on the FDT client -protocol, making it unsuitable. - -Note that accessing the device tree passed by QEMU via its initial base -address is guaranteed to be safe at any time during the PEI phase, so we -can defer discovery of the PSCI method until the time the reset library -is actually invoked (which is rarely) - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Acked-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - .../ArmVirtPsciResetSystemPeiLib.c | 232 ++++++++++++++++++ - .../ArmVirtPsciResetSystemPeiLib.inf | 39 +++ - 2 files changed, 271 insertions(+) - create mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c - create mode 100644 ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf - -diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c -new file mode 100644 -index 0000000..9cfd55d ---- /dev/null -+++ b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c -@@ -0,0 +1,232 @@ -+/** @file -+ Reset System lib using PSCI hypervisor or secure monitor calls -+ -+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
-+ Copyright (c) 2013, ARM Ltd. All rights reserved.
-+ Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
-+ Copyright (c) 2019, Intel Corporation. All rights reserved.
-+ -+ SPDX-License-Identifier: BSD-2-Clause-Patent -+ -+**/ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+typedef enum { -+ PsciMethodUnknown, -+ PsciMethodSmc, -+ PsciMethodHvc, -+} PSCI_METHOD; -+ -+STATIC -+PSCI_METHOD -+DiscoverPsciMethod ( -+ VOID -+ ) -+{ -+ VOID *DeviceTreeBase; -+ INT32 Node, Prev; -+ INT32 Len; -+ CONST CHAR8 *Compatible; -+ CONST CHAR8 *CompatibleItem; -+ CONST VOID *Prop; -+ -+ DeviceTreeBase = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); -+ ASSERT (fdt_check_header (DeviceTreeBase) == 0); -+ -+ // -+ // Enumerate all FDT nodes looking for the PSCI node and capture the method -+ // -+ for (Prev = 0;; Prev = Node) { -+ Node = fdt_next_node (DeviceTreeBase, Prev, NULL); -+ if (Node < 0) { -+ break; -+ } -+ -+ Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len); -+ if (Compatible == NULL) { -+ continue; -+ } -+ -+ // -+ // Iterate over the NULL-separated items in the compatible string -+ // -+ for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len; -+ CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) { -+ -+ if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) { -+ continue; -+ } -+ -+ Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL); -+ if (!Prop) { -+ DEBUG ((DEBUG_ERROR, "%a: Missing PSCI method property\n", -+ __FUNCTION__)); -+ return PsciMethodUnknown; -+ } -+ -+ if (AsciiStrnCmp (Prop, "hvc", 3) == 0) { -+ return PsciMethodHvc; -+ } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) { -+ return PsciMethodSmc; -+ } else { -+ DEBUG ((DEBUG_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__, -+ Prop)); -+ return PsciMethodUnknown; -+ } -+ } -+ } -+ return PsciMethodUnknown; -+} -+ -+STATIC -+VOID -+PerformPsciAction ( -+ IN UINTN Arg0 -+ ) -+{ -+ ARM_SMC_ARGS ArmSmcArgs; -+ ARM_HVC_ARGS ArmHvcArgs; -+ -+ ArmSmcArgs.Arg0 = Arg0; -+ ArmHvcArgs.Arg0 = Arg0; -+ -+ switch (DiscoverPsciMethod ()) { -+ case PsciMethodHvc: -+ ArmCallHvc (&ArmHvcArgs); -+ break; -+ -+ case PsciMethodSmc: -+ ArmCallSmc (&ArmSmcArgs); -+ break; -+ -+ default: -+ DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__)); -+ ASSERT (FALSE); -+ } -+} -+ -+/** -+ This function causes a system-wide reset (cold reset), in which -+ all circuitry within the system returns to its initial state. This type of reset -+ is asynchronous to system operation and operates without regard to -+ cycle boundaries. -+ -+ If this function returns, it means that the system does not support cold reset. -+**/ -+VOID -+EFIAPI -+ResetCold ( -+ VOID -+ ) -+{ -+ // Send a PSCI 0.2 SYSTEM_RESET command -+ PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET); -+} -+ -+/** -+ This function causes a system-wide initialization (warm reset), in which all processors -+ are set to their initial state. Pending cycles are not corrupted. -+ -+ If this function returns, it means that the system does not support warm reset. -+**/ -+VOID -+EFIAPI -+ResetWarm ( -+ VOID -+ ) -+{ -+ // Map a warm reset into a cold reset -+ ResetCold (); -+} -+ -+/** -+ This function causes the system to enter a power state equivalent -+ to the ACPI G2/S5 or G3 states. -+ -+ If this function returns, it means that the system does not support shutdown reset. -+**/ -+VOID -+EFIAPI -+ResetShutdown ( -+ VOID -+ ) -+{ -+ // Send a PSCI 0.2 SYSTEM_OFF command -+ PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF); -+} -+ -+/** -+ This function causes a systemwide reset. The exact type of the reset is -+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed -+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData -+ the platform must pick a supported reset type to perform.The platform may -+ optionally log the parameters from any non-normal reset that occurs. -+ -+ @param[in] DataSize The size, in bytes, of ResetData. -+ @param[in] ResetData The data buffer starts with a Null-terminated string, -+ followed by the EFI_GUID. -+**/ -+VOID -+EFIAPI -+ResetPlatformSpecific ( -+ IN UINTN DataSize, -+ IN VOID *ResetData -+ ) -+{ -+ // Map the platform specific reset as reboot -+ ResetCold (); -+} -+ -+/** -+ The ResetSystem function resets the entire platform. -+ -+ @param[in] ResetType The type of reset to perform. -+ @param[in] ResetStatus The status code for the reset. -+ @param[in] DataSize The size, in bytes, of ResetData. -+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown -+ the data buffer starts with a Null-terminated string, optionally -+ followed by additional binary data. The string is a description -+ that the caller may use to further indicate the reason for the -+ system reset. -+**/ -+VOID -+EFIAPI -+ResetSystem ( -+ IN EFI_RESET_TYPE ResetType, -+ IN EFI_STATUS ResetStatus, -+ IN UINTN DataSize, -+ IN VOID *ResetData OPTIONAL -+ ) -+{ -+ switch (ResetType) { -+ case EfiResetWarm: -+ ResetWarm (); -+ break; -+ -+ case EfiResetCold: -+ ResetCold (); -+ break; -+ -+ case EfiResetShutdown: -+ ResetShutdown (); -+ return; -+ -+ case EfiResetPlatformSpecific: -+ ResetPlatformSpecific (DataSize, ResetData); -+ return; -+ -+ default: -+ return; -+ } -+} -diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf -new file mode 100644 -index 0000000..b480cae ---- /dev/null -+++ b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf -@@ -0,0 +1,39 @@ -+#/** @file -+# Reset System lib using PSCI hypervisor or secure monitor calls -+# -+# Copyright (c) 2008, Apple Inc. All rights reserved.
-+# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.
-+# -+# SPDX-License-Identifier: BSD-2-Clause-Patent -+# -+# -+#**/ -+ -+[Defines] -+ INF_VERSION = 1.27 -+ BASE_NAME = ArmVirtPsciResetSystemPeiLib -+ FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c -+ MODULE_TYPE = BASE -+ VERSION_STRING = 1.0 -+ LIBRARY_CLASS = ResetSystemLib|PEIM -+ -+[Sources] -+ ArmVirtPsciResetSystemPeiLib.c -+ -+[Packages] -+ ArmPkg/ArmPkg.dec -+ ArmVirtPkg/ArmVirtPkg.dec -+ EmbeddedPkg/EmbeddedPkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ MdePkg/MdePkg.dec -+ -+[LibraryClasses] -+ ArmSmcLib -+ ArmHvcLib -+ BaseLib -+ DebugLib -+ FdtLib -+ HobLib -+ -+[Pcd] -+ gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress --- -2.18.2 - diff --git a/0023-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch b/0006-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch similarity index 100% rename from 0023-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch rename to 0006-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch diff --git a/0007-ArmVirtPkg-ArmVirtQemu-add-ResetSystem-PEIM-for-upco.patch b/0007-ArmVirtPkg-ArmVirtQemu-add-ResetSystem-PEIM-for-upco.patch deleted file mode 100644 index f934745516d06daf820c312e8fe1d710c38b4e29..0000000000000000000000000000000000000000 --- a/0007-ArmVirtPkg-ArmVirtQemu-add-ResetSystem-PEIM-for-upco.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 1cb4d8d12542e95274881c7fce1c95816bd883ff Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:10 +0100 -Subject: [PATCH 07/13] ArmVirtPkg/ArmVirtQemu: add ResetSystem PEIM for - upcoming TPM2 support - -As a first step in gradually adding TPM2 support to ArmVirtQemu, add -the TPM2_ENABLE configurable to the [Defines] section, and if it is -set, add the ResetSystem PEIM to the build, along with the library -class references that we will need to support it: -- wire ArmVirtPsciResetSystemPeiLib into the ResetSystem PEIM itself, - which will be in charge of performing the actual reset -- add PeiResetSystemLib as the common ResetSystemLib resolution for - PEIM class modules, so that other PEIMs will invoke the PPI - published by the ResetSystem PEIM. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtQemu.dsc | 14 ++++++++++++++ - ArmVirtPkg/ArmVirtQemu.fdf | 4 ++++ - 2 files changed, 18 insertions(+) - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 984df5c..3bbc79c 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -29,6 +29,7 @@ - # - DEFINE TTY_TERMINAL = FALSE - DEFINE SECURE_BOOT_ENABLE = FALSE -+ DEFINE TPM2_ENABLE = FALSE - - # - # Network definition -@@ -77,6 +78,10 @@ - [LibraryClasses.common.PEIM] - ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf - -+!if $(TPM2_ENABLE) == TRUE -+ ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf -+!endif -+ - [LibraryClasses.common.DXE_DRIVER] - ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - -@@ -100,6 +105,8 @@ - - gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE - -+ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE) -+ - [PcdsFixedAtBuild.common] - !if $(ARCH) == AARCH64 - gArmTokenSpaceGuid.PcdVFPEnabled|1 -@@ -266,6 +273,13 @@ - - MdeModulePkg/Universal/Variable/Pei/VariablePei.inf - -+!if $(TPM2_ENABLE) == TRUE -+ MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf { -+ -+ ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf -+ } -+!endif -+ - MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { - - NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf -diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf -index 2c8936a..69fa501 100644 ---- a/ArmVirtPkg/ArmVirtQemu.fdf -+++ b/ArmVirtPkg/ArmVirtQemu.fdf -@@ -113,6 +113,10 @@ READ_LOCK_STATUS = TRUE - INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf - INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf - -+!if $(TPM2_ENABLE) == TRUE -+ INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf -+!endif -+ - FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { - SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { - SECTION FV_IMAGE = FVMAIN --- -2.18.2 - diff --git a/0024-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch b/0007-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch similarity index 100% rename from 0024-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch rename to 0007-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch diff --git a/0008-ArmVirtPkg-ArmVirtQemu-enable-TPM2-support-in-the-PE.patch b/0008-ArmVirtPkg-ArmVirtQemu-enable-TPM2-support-in-the-PE.patch deleted file mode 100644 index 2d513d801c5fce7399916fa28cf76e2200681d5d..0000000000000000000000000000000000000000 --- a/0008-ArmVirtPkg-ArmVirtQemu-enable-TPM2-support-in-the-PE.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 806d668dee96ddbb81737675b9f074e04334fb13 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:11 +0100 -Subject: [PATCH 08/13] ArmVirtPkg/ArmVirtQemu: enable TPM2 support in the PEI - phase - -Incorporate the PEI components and the associated library class -resolutions and PCD declarations to enable TPM2 support in the -PEI phase. - -This patch ports (parts of) the following OvmfPkg commits to -ArmVirtQemu: -- 6cf1880fb5b6 ("OvmfPkg: add customized Tcg2ConfigPei clone", - 2018-03-09) -- 4672a4892867 ("OvmfPkg: include Tcg2Pei module", 2018-03-09) -- b9130c866dc0 ("OvmfPkg: link Sha384 and Sha512 support into Tcg2Pei - and Tcg2Dxe", 2018-08-16) -- 5d3ef15da7c3 ("OvmfPkg: link SM3 support into Tcg2Pei and Tcg2Dxe", - 2019-07-19) - -gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask defaults to 0x0 so -that the TPM init code adopts the currently active PCR banks as -the ones that are enabled by default. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtQemu.dsc | 20 ++++++++++++++++++++ - ArmVirtPkg/ArmVirtQemu.fdf | 2 ++ - 2 files changed, 22 insertions(+) - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 3bbc79c..44138e5 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -75,11 +75,17 @@ - PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf - PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf - -+!if $(TPM2_ENABLE) == TRUE -+ Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf -+!endif -+ - [LibraryClasses.common.PEIM] - ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf - - !if $(TPM2_ENABLE) == TRUE -+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf - ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf -+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf - !endif - - [LibraryClasses.common.DXE_DRIVER] -@@ -248,6 +254,10 @@ - # TPM2 support - # - gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0 -+!if $(TPM2_ENABLE) == TRUE -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0 -+!endif - - [PcdsDynamicHii] - gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS -@@ -278,6 +288,16 @@ - - ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf - } -+ OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -+ SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { -+ -+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf -+ } - !endif - - MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { -diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf -index 69fa501..8488300 100644 ---- a/ArmVirtPkg/ArmVirtQemu.fdf -+++ b/ArmVirtPkg/ArmVirtQemu.fdf -@@ -115,6 +115,8 @@ READ_LOCK_STATUS = TRUE - - !if $(TPM2_ENABLE) == TRUE - INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf -+ INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -+ INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf - !endif - - FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { --- -2.18.2 - diff --git a/0025-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch b/0008-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch similarity index 100% rename from 0025-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch rename to 0008-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch diff --git a/0009-ArmVirtPkg-avoid-DxeTpmMeasurementLib-in-shared-.DSC.patch b/0009-ArmVirtPkg-avoid-DxeTpmMeasurementLib-in-shared-.DSC.patch deleted file mode 100644 index 8f96125df8ff011d81a5ffc3186b294beda26e32..0000000000000000000000000000000000000000 --- a/0009-ArmVirtPkg-avoid-DxeTpmMeasurementLib-in-shared-.DSC.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 785f0c94c6fa7bfbf307d2e5faa90964dca155a9 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Thu, 27 Feb 2020 15:12:32 +0100 -Subject: [PATCH 09/13] ArmVirtPkg; avoid DxeTpmMeasurementLib in shared .DSC - -DxeTpmMeasurementLib should only be used on platforms that implement -measured boot, which we will do in a future patch, but only for -ArmVirtQemu, as the remaining ones are fundamentally incompatible, -given that they do not implement a PEI phase. - -So use TpmMeasurementLibNull as the default resolution for all -ArmVirtPkg platforms, regardless of how they are built. - -This mirrors commit 1ec05b81e59f ("OvmfPkg: use DxeTpmMeasurementLib -if and only if TPM2_ENABLE", 2019-07-04). - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirt.dsc.inc | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc -index 10037c9..398aa7b 100644 ---- a/ArmVirtPkg/ArmVirt.dsc.inc -+++ b/ArmVirtPkg/ArmVirt.dsc.inc -@@ -165,15 +165,14 @@ - # Secure Boot dependencies - # - !if $(SECURE_BOOT_ENABLE) == TRUE -- TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf - AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf - - # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree - PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf - !else -- TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf - !endif -+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf - UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf - --- -2.18.2 - diff --git a/0026-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch b/0009-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch similarity index 100% rename from 0026-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch rename to 0009-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch diff --git a/0010-ArmVirtPkg-unshare-TpmMeasurementLib-resolution-betw.patch b/0010-ArmVirtPkg-unshare-TpmMeasurementLib-resolution-betw.patch deleted file mode 100644 index 65affb292a3ac73b851164dae1711b7a64b42f4c..0000000000000000000000000000000000000000 --- a/0010-ArmVirtPkg-unshare-TpmMeasurementLib-resolution-betw.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 454595840418dce7e227a70ff297b1d11593e768 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Thu, 27 Feb 2020 15:24:21 +0100 -Subject: [PATCH 10/13] ArmVirtPkg: unshare TpmMeasurementLib resolution - between platforms - -In preparation of conditializing the choice of resolution based on -TPM2_ENABLE for ArmVirtQemu, move the TpmMeasurementLib out of the -shared .DSC include and into the individual DSCs. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirt.dsc.inc | 1 - - ArmVirtPkg/ArmVirtQemu.dsc | 1 + - ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 + - ArmVirtPkg/ArmVirtXen.dsc | 1 + - 4 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc -index 398aa7b..0a28d3a 100644 ---- a/ArmVirtPkg/ArmVirt.dsc.inc -+++ b/ArmVirtPkg/ArmVirt.dsc.inc -@@ -172,7 +172,6 @@ - !else - AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf - !endif -- TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf - UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 44138e5..83c4dea 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -74,6 +74,7 @@ - PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf - PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf -+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - - !if $(TPM2_ENABLE) == TRUE - Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf -diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc -index 8243876..7bd50e4 100644 ---- a/ArmVirtPkg/ArmVirtQemuKernel.dsc -+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc -@@ -73,6 +73,7 @@ - PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf - PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf -+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - - [LibraryClasses.common.DXE_DRIVER] - ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf -diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc -index 8a6ace2..2a4ef8d 100644 ---- a/ArmVirtPkg/ArmVirtXen.dsc -+++ b/ArmVirtPkg/ArmVirtXen.dsc -@@ -47,6 +47,7 @@ - BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf - PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf - CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf -+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - - [LibraryClasses.common.UEFI_DRIVER] - UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf --- -2.18.2 - diff --git a/0027-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch b/0010-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch similarity index 100% rename from 0027-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch rename to 0010-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch diff --git a/0011-ArmVirtPkg-ArmVirtQemu-enable-the-DXE-phase-TPM2-sup.patch b/0011-ArmVirtPkg-ArmVirtQemu-enable-the-DXE-phase-TPM2-sup.patch deleted file mode 100644 index ae03320f750bf1beb51296e71b619de62af58106..0000000000000000000000000000000000000000 --- a/0011-ArmVirtPkg-ArmVirtQemu-enable-the-DXE-phase-TPM2-sup.patch +++ /dev/null @@ -1,115 +0,0 @@ -From d77e86c43972cd56b37d8f4b34c253f82aa65f54 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:12 +0100 -Subject: [PATCH 11/13] ArmVirtPkg/ArmVirtQemu: enable the DXE phase TPM2 - support module - -Enable the TPM2 support module in the DXE phase, and the associated -libraries and PCDs that it requires. This will be wired into the -measured boot support code in a subsequent patch. - -Note that Tcg2Dxe.inf is added to ArmVirtQemuFvMain.fdf.inc, which -is shared with other platforms in ArmVirtPkg, but as those will not -set the TPM2_ENABLE define, this change does not affect them. - -This patch ports (parts of) the following OvmfPkg commits to -ArmVirtQemu: - -- 0c0a50d6b3ff ("OvmfPkg: include Tcg2Dxe module", 2018-03-09) - -- b9777bb42e4f ("OvmfPkg: add Tcg2PhysicalPresenceLibQemu", 2018-05-22) - -- only to match OVMF's current lib class resolutions - -- 1ec05b81e59f ("OvmfPkg: use DxeTpmMeasurementLib if and only if - TPM2_ENABLE", 2019-07-04) - -- b9130c866dc0 ("OvmfPkg: link Sha384 and Sha512 support into Tcg2Pei - and Tcg2Dxe", 2018-08-16) - -- 5d3ef15da7c3 ("OvmfPkg: link SM3 support into Tcg2Pei and Tcg2Dxe", - 2019-07-19) - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtQemu.dsc | 26 +++++++++++++++++++++++++- - ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 7 +++++++ - 2 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 83c4dea..291210a 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -74,10 +74,13 @@ - PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf - PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf - PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf -- TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - - !if $(TPM2_ENABLE) == TRUE - Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf -+ Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf -+ TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf -+!else -+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf - !endif - - [LibraryClasses.common.PEIM] -@@ -92,6 +95,10 @@ - [LibraryClasses.common.DXE_DRIVER] - ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - -+!if $(TPM2_ENABLE) == TRUE -+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf -+!endif -+ - [LibraryClasses.common.UEFI_DRIVER] - UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf - -@@ -470,6 +477,23 @@ - MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf - MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf - -+ # -+ # TPM2 support -+ # -+!if $(TPM2_ENABLE) == TRUE -+ SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { -+ -+ HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf -+ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf -+ NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf -+ NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf -+ } -+!endif -+ - # - # ACPI Support - # -diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -index 31f615a..047e99c 100644 ---- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -@@ -173,6 +173,13 @@ READ_LOCK_STATUS = TRUE - INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf - INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf - -+ # -+ # TPM2 support -+ # -+!if $(TPM2_ENABLE) == TRUE -+ INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf -+!endif -+ - # - # TianoCore logo (splash screen) - # --- -2.18.2 - diff --git a/0028-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch b/0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch similarity index 100% rename from 0028-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch rename to 0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch diff --git a/0012-ArmVirtPkg-ArmVirtQemu-enable-the-TPM2-configuration.patch b/0012-ArmVirtPkg-ArmVirtQemu-enable-the-TPM2-configuration.patch deleted file mode 100644 index bf95bc0c5f1232c9b271e9482f775e06ae6daa4a..0000000000000000000000000000000000000000 --- a/0012-ArmVirtPkg-ArmVirtQemu-enable-the-TPM2-configuration.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c3b182fe9189137280a5397426cc08b1110aac39 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:13 +0100 -Subject: [PATCH 12/13] ArmVirtPkg/ArmVirtQemu: enable the TPM2 configuration - module - -Enable the DXE phase component that publishes the HII pages and -associated logic to enable TPM2 parameters to be configured by -the user via the setup menu. - -This patch ports (parts of) the following commits to ArmVirtQemu: - -- 3103389043bd ("OvmfPkg: Add TCG2 Configuration menu to the Device - Manager menu", 2019-02-11) - -- cf3ad972a210 ("OvmfPkg: reorganize TPM2 support in DSC/FDF files", - 2020-01-09) - -- f55477fe2d62 ("OvmfPkg: use HII type PCDs for TPM2 config related - variables", 2020-01-09) - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtQemu.dsc | 9 +++++++++ - ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 3 +++ - 2 files changed, 12 insertions(+) - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 291210a..93b982a 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -30,6 +30,7 @@ - DEFINE TTY_TERMINAL = FALSE - DEFINE SECURE_BOOT_ENABLE = FALSE - DEFINE TPM2_ENABLE = FALSE -+ DEFINE TPM2_CONFIG_ENABLE = FALSE - - # - # Network definition -@@ -270,6 +271,11 @@ - [PcdsDynamicHii] - gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS - -+!if $(TPM2_CONFIG_ENABLE) == TRUE -+ gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS -+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS -+!endif -+ - ################################################################################ - # - # Components Section - list of all EDK II Modules needed by this Platform -@@ -492,6 +498,9 @@ - NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf - NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf - } -+!if $(TPM2_CONFIG_ENABLE) == TRUE -+ SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf -+!endif - !endif - - # -diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -index 047e99c..2fa69ce 100644 ---- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc -@@ -178,6 +178,9 @@ READ_LOCK_STATUS = TRUE - # - !if $(TPM2_ENABLE) == TRUE - INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf -+!if $(TPM2_CONFIG_ENABLE) == TRUE -+ INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf -+!endif - !endif - - # --- -2.18.2 - diff --git a/0012-SecurityPkg-TPM-Import-PeiDxeTpmPlatformHierarchyLib.patch b/0012-SecurityPkg-TPM-Import-PeiDxeTpmPlatformHierarchyLib.patch new file mode 100644 index 0000000000000000000000000000000000000000..0fce38aa7846e709b0eb6b946b7514a824780139 --- /dev/null +++ b/0012-SecurityPkg-TPM-Import-PeiDxeTpmPlatformHierarchyLib.patch @@ -0,0 +1,378 @@ +From 6642e762e1cedae30a08e28c456de2372bda7766 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:20:57 +0800 +Subject: [PATCH 1/8] SecurityPkg/TPM: Import PeiDxeTpmPlatformHierarchyLib.c + from edk2-platforms + +Import PeiDxeTpmPlatformHierarchyLib from edk2-platforms without any +modifications. + +Signed-off-by: Stefan Berger +--- + .../Include/Library/TpmPlatformHierarchyLib.h | 27 ++ + .../PeiDxeTpmPlatformHierarchyLib.c | 266 ++++++++++++++++++ + .../PeiDxeTpmPlatformHierarchyLib.inf | 45 +++ + 3 files changed, 338 insertions(+) + create mode 100644 SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h + create mode 100644 SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c + create mode 100644 SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf + +diff --git a/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h +new file mode 100644 +index 0000000000..a872fa09dc +--- /dev/null ++++ b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h +@@ -0,0 +1,27 @@ ++/** @file ++ TPM Platform Hierarchy configuration library. ++ ++ This library provides functions for customizing the TPM's Platform Hierarchy ++ Authorization Value (platformAuth) and Platform Hierarchy Authorization ++ Policy (platformPolicy) can be defined through this function. ++ ++Copyright (c) 2019, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef _TPM_PLATFORM_HIERARCHY_LIB_H_ ++#define _TPM_PLATFORM_HIERARCHY_LIB_H_ ++ ++/** ++ This service will perform the TPM Platform Hierarchy configuration at the SmmReadyToLock event. ++ ++**/ ++VOID ++EFIAPI ++ConfigureTpmPlatformHierarchy ( ++ VOID ++ ); ++ ++#endif +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +new file mode 100644 +index 0000000000..9812ab99ab +--- /dev/null ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +@@ -0,0 +1,266 @@ ++/** @file ++ TPM Platform Hierarchy configuration library. ++ ++ This library provides functions for customizing the TPM's Platform Hierarchy ++ Authorization Value (platformAuth) and Platform Hierarchy Authorization ++ Policy (platformPolicy) can be defined through this function. ++ ++ Copyright (c) 2019, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++ @par Specification Reference: ++ https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance/ ++**/ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// ++// The authorization value may be no larger than the digest produced by the hash ++// algorithm used for context integrity. ++// ++#define MAX_NEW_AUTHORIZATION_SIZE SHA512_DIGEST_SIZE ++ ++UINT16 mAuthSize; ++ ++/** ++ Generate high-quality entropy source through RDRAND. ++ ++ @param[in] Length Size of the buffer, in bytes, to fill with. ++ @param[out] Entropy Pointer to the buffer to store the entropy data. ++ ++ @retval EFI_SUCCESS Entropy generation succeeded. ++ @retval EFI_NOT_READY Failed to request random data. ++ ++**/ ++EFI_STATUS ++EFIAPI ++RdRandGenerateEntropy ( ++ IN UINTN Length, ++ OUT UINT8 *Entropy ++ ) ++{ ++ EFI_STATUS Status; ++ UINTN BlockCount; ++ UINT64 Seed[2]; ++ UINT8 *Ptr; ++ ++ Status = EFI_NOT_READY; ++ BlockCount = Length / 64; ++ Ptr = (UINT8 *)Entropy; ++ ++ // ++ // Generate high-quality seed for DRBG Entropy ++ // ++ while (BlockCount > 0) { ++ Status = GetRandomNumber128 (Seed); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ CopyMem (Ptr, Seed, 64); ++ ++ BlockCount--; ++ Ptr = Ptr + 64; ++ } ++ ++ // ++ // Populate the remained data as request. ++ // ++ Status = GetRandomNumber128 (Seed); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ CopyMem (Ptr, Seed, (Length % 64)); ++ ++ return Status; ++} ++ ++/** ++ This function returns the maximum size of TPM2B_AUTH; this structure is used for an authorization value ++ and limits an authValue to being no larger than the largest digest produced by a TPM. ++ ++ @param[out] AuthSize Tpm2 Auth size ++ ++ @retval EFI_SUCCESS Auth size returned. ++ @retval EFI_DEVICE_ERROR Can not return platform auth due to device error. ++ ++**/ ++EFI_STATUS ++EFIAPI ++GetAuthSize ( ++ OUT UINT16 *AuthSize ++ ) ++{ ++ EFI_STATUS Status; ++ TPML_PCR_SELECTION Pcrs; ++ UINTN Index; ++ UINT16 DigestSize; ++ ++ Status = EFI_SUCCESS; ++ ++ while (mAuthSize == 0) { ++ ++ mAuthSize = SHA1_DIGEST_SIZE; ++ ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION)); ++ Status = Tpm2GetCapabilityPcrs (&Pcrs); ++ ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs fail!\n")); ++ break; ++ } ++ ++ DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - %08x\n", Pcrs.count)); ++ ++ for (Index = 0; Index < Pcrs.count; Index++) { ++ DEBUG ((DEBUG_ERROR, "alg - %x\n", Pcrs.pcrSelections[Index].hash)); ++ ++ switch (Pcrs.pcrSelections[Index].hash) { ++ case TPM_ALG_SHA1: ++ DigestSize = SHA1_DIGEST_SIZE; ++ break; ++ case TPM_ALG_SHA256: ++ DigestSize = SHA256_DIGEST_SIZE; ++ break; ++ case TPM_ALG_SHA384: ++ DigestSize = SHA384_DIGEST_SIZE; ++ break; ++ case TPM_ALG_SHA512: ++ DigestSize = SHA512_DIGEST_SIZE; ++ break; ++ case TPM_ALG_SM3_256: ++ DigestSize = SM3_256_DIGEST_SIZE; ++ break; ++ default: ++ DigestSize = SHA1_DIGEST_SIZE; ++ break; ++ } ++ ++ if (DigestSize > mAuthSize) { ++ mAuthSize = DigestSize; ++ } ++ } ++ break; ++ } ++ ++ *AuthSize = mAuthSize; ++ return Status; ++} ++ ++/** ++ Set PlatformAuth to random value. ++**/ ++VOID ++RandomizePlatformAuth ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UINT16 AuthSize; ++ UINT8 *Rand; ++ UINTN RandSize; ++ TPM2B_AUTH NewPlatformAuth; ++ ++ // ++ // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null ++ // ++ ++ GetAuthSize (&AuthSize); ++ ++ ZeroMem (NewPlatformAuth.buffer, AuthSize); ++ NewPlatformAuth.size = AuthSize; ++ ++ // ++ // Allocate one buffer to store random data. ++ // ++ RandSize = MAX_NEW_AUTHORIZATION_SIZE; ++ Rand = AllocatePool (RandSize); ++ ++ RdRandGenerateEntropy (RandSize, Rand); ++ CopyMem (NewPlatformAuth.buffer, Rand, AuthSize); ++ ++ FreePool (Rand); ++ ++ // ++ // Send Tpm2HierarchyChangeAuth command with the new Auth value ++ // ++ Status = Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM, NULL, &NewPlatformAuth); ++ DEBUG ((DEBUG_INFO, "Tpm2HierarchyChangeAuth Result: - %r\n", Status)); ++ ZeroMem (NewPlatformAuth.buffer, AuthSize); ++ ZeroMem (Rand, RandSize); ++} ++ ++/** ++ Disable the TPM platform hierarchy. ++ ++ @retval EFI_SUCCESS The TPM was disabled successfully. ++ @retval Others An error occurred attempting to disable the TPM platform hierarchy. ++ ++**/ ++EFI_STATUS ++DisableTpmPlatformHierarchy ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ ++ // Make sure that we have use of the TPM. ++ Status = Tpm2RequestUseTpm (); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a:%a() - Tpm2RequestUseTpm Failed! %r\n", gEfiCallerBaseName, __FUNCTION__, Status)); ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } ++ ++ // Let's do what we can to shut down the hierarchies. ++ ++ // Disable the PH NV. ++ // IMPORTANT NOTE: We *should* be able to disable the PH NV here, but TPM parts have ++ // been known to store the EK cert in the PH NV. If we disable it, the ++ // EK cert will be unreadable. ++ ++ // Disable the PH. ++ Status = Tpm2HierarchyControl ( ++ TPM_RH_PLATFORM, // AuthHandle ++ NULL, // AuthSession ++ TPM_RH_PLATFORM, // Hierarchy ++ NO // State ++ ); ++ DEBUG ((DEBUG_VERBOSE, "%a:%a() - Disable PH = %r\n", gEfiCallerBaseName, __FUNCTION__, Status)); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a:%a() - Disable PH Failed! %r\n", gEfiCallerBaseName, __FUNCTION__, Status)); ++ ASSERT_EFI_ERROR (Status); ++ } ++ ++ return Status; ++} ++ ++/** ++ This service defines the configuration of the Platform Hierarchy Authorization Value (platformAuth) ++ and Platform Hierarchy Authorization Policy (platformPolicy) ++ ++**/ ++VOID ++EFIAPI ++ConfigureTpmPlatformHierarchy ( ++ ) ++{ ++ if (PcdGetBool (PcdRandomizePlatformHierarchy)) { ++ // ++ // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null ++ // ++ RandomizePlatformAuth (); ++ } else { ++ // ++ // Disable the hierarchy entirely (do not randomize it) ++ // ++ DisableTpmPlatformHierarchy (); ++ } ++} +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +new file mode 100644 +index 0000000000..b7a7fb0a08 +--- /dev/null ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +@@ -0,0 +1,45 @@ ++### @file ++# ++# TPM Platform Hierarchy configuration library. ++# ++# This library provides functions for customizing the TPM's Platform Hierarchy ++# Authorization Value (platformAuth) and Platform Hierarchy Authorization ++# Policy (platformPolicy) can be defined through this function. ++# ++# Copyright (c) 2019, Intel Corporation. All rights reserved.
++# Copyright (c) Microsoft Corporation.
++# ++# SPDX-License-Identifier: BSD-2-Clause-Patent ++# ++### ++ ++[Defines] ++ INF_VERSION = 0x00010005 ++ BASE_NAME = PeiDxeTpmPlatformHierarchyLib ++ FILE_GUID = 7794F92C-4E8E-4E57-9E4A-49A0764C7D73 ++ MODULE_TYPE = PEIM ++ VERSION_STRING = 1.0 ++ LIBRARY_CLASS = TpmPlatformHierarchyLib|PEIM DXE_DRIVER ++ ++[LibraryClasses] ++ BaseLib ++ BaseMemoryLib ++ DebugLib ++ MemoryAllocationLib ++ PcdLib ++ RngLib ++ Tpm2CommandLib ++ Tpm2DeviceLib ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ SecurityPkg/SecurityPkg.dec ++ CryptoPkg/CryptoPkg.dec ++ MinPlatformPkg/MinPlatformPkg.dec ++ ++[Sources] ++ PeiDxeTpmPlatformHierarchyLib.c ++ ++[Pcd] ++ gMinPlatformPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy +-- +2.27.0 + diff --git a/0013-ArmVirtPkg-ArmVirtQemu-enable-TPM2-based-measured-bo.patch b/0013-ArmVirtPkg-ArmVirtQemu-enable-TPM2-based-measured-bo.patch deleted file mode 100644 index da79bcfa5d33bb6135cd4e1e0f78e3f479c8f11b..0000000000000000000000000000000000000000 --- a/0013-ArmVirtPkg-ArmVirtQemu-enable-TPM2-based-measured-bo.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d9c8dd64dd827cea4a533d012f344d0db6569127 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 26 Feb 2020 20:05:14 +0100 -Subject: [PATCH 13/13] ArmVirtPkg/ArmVirtQemu: enable TPM2 based measured boot - -Now that all the TPM2 related plumbing is in place, we can add the -final piece that performs the measurements of loaded images into -the appropriate PCRs. - -This patch ports commit d5a002aba0aa ("OvmfPkg: plug -DxeTpm2MeasureBootLib into SecurityStubDxe", 2018-03-09) to ArmVirtQemu. - -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2560 -Signed-off-by: Ard Biesheuvel -Reviewed-by: Laszlo Ersek -Signed-off-by: jiangfangjie ---- - ArmVirtPkg/ArmVirtQemu.dsc | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc -index 93b982a..a07d546 100644 ---- a/ArmVirtPkg/ArmVirtQemu.dsc -+++ b/ArmVirtPkg/ArmVirtQemu.dsc -@@ -348,6 +348,9 @@ - MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { - - NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf -+!if $(TPM2_ENABLE) == TRUE -+ NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf -+!endif - } - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf - OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf --- -2.18.2 - diff --git a/0013-SecurityPkg-TPM-Fix-bugs-in-imported-PeiDxeTpmPlatfo.patch b/0013-SecurityPkg-TPM-Fix-bugs-in-imported-PeiDxeTpmPlatfo.patch new file mode 100644 index 0000000000000000000000000000000000000000..e250097ddf91b67f558b84c7bfcf794841df7b51 --- /dev/null +++ b/0013-SecurityPkg-TPM-Fix-bugs-in-imported-PeiDxeTpmPlatfo.patch @@ -0,0 +1,121 @@ +From da8e34ff10bff3bff14c0bc5ee1f2e3f3d72428f Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:20:58 +0800 +Subject: [PATCH 2/8] SecurityPkg/TPM: Fix bugs in imported + PeiDxeTpmPlatformHierarchyLib + +Fix some bugs in the original PeiDxeTpmPlatformHierarchyLib.c. + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + .../PeiDxeTpmPlatformHierarchyLib.c | 23 +++++-------------- + .../PeiDxeTpmPlatformHierarchyLib.inf | 5 ++-- + 2 files changed, 8 insertions(+), 20 deletions(-) + +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +index 9812ab99ab..d82a0ae1bd 100644 +--- a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -27,7 +26,6 @@ + // The authorization value may be no larger than the digest produced by the hash + // algorithm used for context integrity. + // +-#define MAX_NEW_AUTHORIZATION_SIZE SHA512_DIGEST_SIZE + + UINT16 mAuthSize; + +@@ -54,7 +52,7 @@ RdRandGenerateEntropy ( + UINT8 *Ptr; + + Status = EFI_NOT_READY; +- BlockCount = Length / 64; ++ BlockCount = Length / sizeof(Seed); + Ptr = (UINT8 *)Entropy; + + // +@@ -65,10 +63,10 @@ RdRandGenerateEntropy ( + if (EFI_ERROR (Status)) { + return Status; + } +- CopyMem (Ptr, Seed, 64); ++ CopyMem (Ptr, Seed, sizeof(Seed)); + + BlockCount--; +- Ptr = Ptr + 64; ++ Ptr = Ptr + sizeof(Seed); + } + + // +@@ -78,7 +76,7 @@ RdRandGenerateEntropy ( + if (EFI_ERROR (Status)) { + return Status; + } +- CopyMem (Ptr, Seed, (Length % 64)); ++ CopyMem (Ptr, Seed, (Length % sizeof(Seed))); + + return Status; + } +@@ -164,8 +162,6 @@ RandomizePlatformAuth ( + { + EFI_STATUS Status; + UINT16 AuthSize; +- UINT8 *Rand; +- UINTN RandSize; + TPM2B_AUTH NewPlatformAuth; + + // +@@ -174,19 +170,13 @@ RandomizePlatformAuth ( + + GetAuthSize (&AuthSize); + +- ZeroMem (NewPlatformAuth.buffer, AuthSize); + NewPlatformAuth.size = AuthSize; + + // +- // Allocate one buffer to store random data. ++ // Create the random bytes in the destination buffer + // +- RandSize = MAX_NEW_AUTHORIZATION_SIZE; +- Rand = AllocatePool (RandSize); +- +- RdRandGenerateEntropy (RandSize, Rand); +- CopyMem (NewPlatformAuth.buffer, Rand, AuthSize); + +- FreePool (Rand); ++ RdRandGenerateEntropy (NewPlatformAuth.size, NewPlatformAuth.buffer); + + // + // Send Tpm2HierarchyChangeAuth command with the new Auth value +@@ -194,7 +184,6 @@ RandomizePlatformAuth ( + Status = Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM, NULL, &NewPlatformAuth); + DEBUG ((DEBUG_INFO, "Tpm2HierarchyChangeAuth Result: - %r\n", Status)); + ZeroMem (NewPlatformAuth.buffer, AuthSize); +- ZeroMem (Rand, RandSize); + } + + /** +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +index b7a7fb0a08..7bf666794f 100644 +--- a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +@@ -1,6 +1,5 @@ +-### @file +-# +-# TPM Platform Hierarchy configuration library. ++## @file ++# TPM Platform Hierarchy configuration library. + # + # This library provides functions for customizing the TPM's Platform Hierarchy + # Authorization Value (platformAuth) and Platform Hierarchy Authorization +-- +2.27.0 + diff --git a/0014-MdeModulePkg-Core-Dxe-assert-SectionInstance-invariant-in-FindChildNode.patch b/0014-MdeModulePkg-Core-Dxe-assert-SectionInstance-invariant-in-FindChildNode.patch deleted file mode 100755 index 84987252924eedadcb9e77c5112c8eddfbab4151..0000000000000000000000000000000000000000 --- a/0014-MdeModulePkg-Core-Dxe-assert-SectionInstance-invariant-in-FindChildNode.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 4ea70df0973caf3763aa306e8d6571fc37aa35e5 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Mon, 28 Sep 2020 16:29:01 +0200 -Subject: [PATCH v2 1/2] MdeModulePkg/Core/Dxe: assert SectionInstance - invariant in FindChildNode() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -FindChildNode() has two callers: GetSection(), and FindChildNode() itself. - -- At the GetSection() call site, a positive (i.e., nonzero) - SectionInstance is passed. This is because GetSection() takes a - zero-based (UINTN) SectionInstance, and then passes - Instance=(SectionInstance+1) to FindChildNode(). - -- For reaching the recursive FindChildNode() call site, a section type - mismatch, or a section instance mismatch, is necessary. This means, - respectively, that SectionInstance will either not have been decreased, - or not to zero anyway, at the recursive FindChildNode() call site. - -Add two ASSERT()s to FindChildNode(), for expressing the (SectionSize>0) -invariant. - -In turn, the invariant provides the explanation why, after the recursive -call, a zero SectionInstance implies success. Capture it in a comment. - -Cc: Dandan Bi -Cc: Hao A Wu -Cc: Jian J Wang -Cc: Liming Gao -Cc: Philippe Mathieu-Daudé -Signed-off-by: Laszlo Ersek ---- - -Notes: - v2: - - no change - - MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c | 23 +++++++++++++++----- - 1 file changed, 17 insertions(+), 6 deletions(-) - -diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -index d678166db475..d7f7ef427422 100644 ---- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -+++ b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -@@ -952,8 +952,8 @@ CreateChildNode ( - search. - @param SearchType Indicates the type of section to search for. - @param SectionInstance Indicates which instance of section to find. -- This is an in/out parameter to deal with -- recursions. -+ This is an in/out parameter and it is 1-based, -+ to deal with recursions. - @param SectionDefinitionGuid Guid of section definition - @param FoundChild Output indicating the child node that is found. - @param FoundStream Output indicating which section stream the child -@@ -988,6 +988,8 @@ FindChildNode ( - EFI_STATUS ErrorStatus; - EFI_STATUS Status; - -+ ASSERT (*SectionInstance > 0); -+ - CurrentChildNode = NULL; - ErrorStatus = EFI_NOT_FOUND; - -@@ -1037,6 +1039,11 @@ FindChildNode ( - } - } - -+ // -+ // Type mismatch, or we haven't found the desired instance yet. -+ // -+ ASSERT (*SectionInstance > 0); -+ - if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) { - // - // If the current node is an encapsulating node, recurse into it... -@@ -1050,16 +1057,20 @@ FindChildNode ( - &RecursedFoundStream, - AuthenticationStatus - ); -- // -- // If the status is not EFI_SUCCESS, just save the error code and continue -- // to find the request child node in the rest stream. -- // - if (*SectionInstance == 0) { -+ // -+ // The recursive FindChildNode() call decreased (*SectionInstance) to -+ // zero. -+ // - ASSERT_EFI_ERROR (Status); - *FoundChild = RecursedChildNode; - *FoundStream = RecursedFoundStream; - return EFI_SUCCESS; - } else { -+ // -+ // If the status is not EFI_SUCCESS, just save the error code and -+ // continue to find the request child node in the rest stream. -+ // - ErrorStatus = Status; - } - } else if ((CurrentChildNode->Type == EFI_SECTION_GUID_DEFINED) && (SearchType != EFI_SECTION_GUID_DEFINED)) { --- -2.19.1.3.g30247aa5d201 - diff --git a/0014-SecrutiyPkg-Tcg-Import-Tcg2PlatformDxe-from-edk2-pla.patch b/0014-SecrutiyPkg-Tcg-Import-Tcg2PlatformDxe-from-edk2-pla.patch new file mode 100644 index 0000000000000000000000000000000000000000..480ab1dfb06c05118568fa074c7d675be915a88c --- /dev/null +++ b/0014-SecrutiyPkg-Tcg-Import-Tcg2PlatformDxe-from-edk2-pla.patch @@ -0,0 +1,161 @@ +From 4f998a6c11ca05dc19bafe54ecd43ed74bd2cb3c Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:20:59 +0800 +Subject: [PATCH 3/8] SecrutiyPkg/Tcg: Import Tcg2PlatformDxe from + edk2-platforms + +Import Tcg2PlatformDxe from edk2-platforms without any modifications. + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + .../Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.c | 85 +++++++++++++++++++ + .../Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf | 44 ++++++++++ + 2 files changed, 129 insertions(+) + create mode 100644 SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.c + create mode 100644 SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf + +diff --git a/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.c b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.c +new file mode 100644 +index 0000000000..150cf748ff +--- /dev/null ++++ b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.c +@@ -0,0 +1,85 @@ ++/** @file ++ Platform specific TPM2 component for configuring the Platform Hierarchy. ++ ++ Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ This callback function will run at the SmmReadyToLock event. ++ ++ Configuration of the TPM's Platform Hierarchy Authorization Value (platformAuth) ++ and Platform Hierarchy Authorization Policy (platformPolicy) can be defined through this function. ++ ++ @param Event Pointer to this event ++ @param Context Event hanlder private data ++ **/ ++VOID ++EFIAPI ++SmmReadyToLockEventCallBack ( ++ IN EFI_EVENT Event, ++ IN VOID *Context ++ ) ++{ ++ EFI_STATUS Status; ++ VOID *Interface; ++ ++ // ++ // Try to locate it because EfiCreateProtocolNotifyEvent will trigger it once when registration. ++ // Just return if it is not found. ++ // ++ Status = gBS->LocateProtocol ( ++ &gEfiDxeSmmReadyToLockProtocolGuid, ++ NULL, ++ &Interface ++ ); ++ if (EFI_ERROR (Status)) { ++ return ; ++ } ++ ++ ConfigureTpmPlatformHierarchy (); ++ ++ gBS->CloseEvent (Event); ++} ++ ++/** ++ The driver's entry point. Will register a function for callback during SmmReadyToLock event to ++ configure the TPM's platform authorization. ++ ++ @param[in] ImageHandle The firmware allocated handle for the EFI image. ++ @param[in] SystemTable A pointer to the EFI System Table. ++ ++ @retval EFI_SUCCESS The entry point is executed successfully. ++ @retval other Some error occurs when executing this entry point. ++**/ ++EFI_STATUS ++EFIAPI ++Tcg2PlatformDxeEntryPoint ( ++ IN EFI_HANDLE ImageHandle, ++ IN EFI_SYSTEM_TABLE *SystemTable ++ ) ++{ ++ VOID *Registration; ++ EFI_EVENT Event; ++ ++ Event = EfiCreateProtocolNotifyEvent ( ++ &gEfiDxeSmmReadyToLockProtocolGuid, ++ TPL_CALLBACK, ++ SmmReadyToLockEventCallBack, ++ NULL, ++ &Registration ++ ); ++ ++ ASSERT (Event != NULL); ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf +new file mode 100644 +index 0000000000..af29c1cd98 +--- /dev/null ++++ b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf +@@ -0,0 +1,44 @@ ++### @file ++# Platform specific TPM2 component. ++# ++# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
++# ++# SPDX-License-Identifier: BSD-2-Clause-Patent ++# ++### ++ ++[Defines] ++ INF_VERSION = 0x00010017 ++ BASE_NAME = Tcg2PlatformDxe ++ FILE_GUID = 5CAB08D5-AD8F-4d8b-B828-D17A8D9FE977 ++ VERSION_STRING = 1.0 ++ MODULE_TYPE = DXE_DRIVER ++ ENTRY_POINT = Tcg2PlatformDxeEntryPoint ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 IPF ++# ++ ++[LibraryClasses] ++ BaseLib ++ UefiBootServicesTableLib ++ UefiDriverEntryPoint ++ DebugLib ++ UefiLib ++ TpmPlatformHierarchyLib ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ MinPlatformPkg/MinPlatformPkg.dec ++ SecurityPkg/SecurityPkg.dec ++ ++[Sources] ++ Tcg2PlatformDxe.c ++ ++[Protocols] ++ gEfiDxeSmmReadyToLockProtocolGuid ## SOMETIMES_CONSUMES ## NOTIFY ++ ++[Depex] ++ gEfiTcg2ProtocolGuid +-- +2.27.0 + diff --git a/0015-MdeModulePkg-Core-Dxe-limit-FwVol-encapsulation-section-recursion.patch b/0015-MdeModulePkg-Core-Dxe-limit-FwVol-encapsulation-section-recursion.patch deleted file mode 100755 index 5960c3de43333dfb956ee784ec6eb5b01d287cb7..0000000000000000000000000000000000000000 --- a/0015-MdeModulePkg-Core-Dxe-limit-FwVol-encapsulation-section-recursion.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 5d02b0176fb8584e44c1b8f2bc1f934e23b017ed Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Mon, 28 Sep 2020 15:02:02 +0200 -Subject: [PATCH v2 2/2] MdeModulePkg/Core/Dxe: limit FwVol encapsulation - section recursion -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The DXE Core sets up a protocol notify function in its entry point, for -instances of the Firmware Volume Block2 Protocol: - - DxeMain() [DxeMain/DxeMain.c] - FwVolDriverInit() [FwVol/FwVol.c] - -Assume that a 3rd party UEFI driver or application installs an FVB -instance, with crafted contents. The notification function runs: - - NotifyFwVolBlock() [FwVol/FwVol.c] - -installing an instance of the Firmware Volume 2 Protocol on the handle. - -(Alternatively, assume that a 3rd party application calls -gDS->ProcessFirmwareVolume(), which may also produce a Firmware Volume 2 -Protocol instance.) - -The EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() member performs "a -depth-first, left-to-right search algorithm through all sections found in -the specified file" (quoting the PI spec), as follows: - - FvReadFileSection() [FwVol/FwVolRead.c] - GetSection() [SectionExtraction/CoreSectionExtraction.c] - FindChildNode() [SectionExtraction/CoreSectionExtraction.c] - FindChildNode() // recursive call - -FindChildNode() is called recursively for encapsulation sections. - -Currently this recursion is not limited. Introduce a new PCD -(fixed-at-build, or patchable-in-module), and make FindChildNode() track -the section nesting depth against that PCD. - -Cc: Dandan Bi -Cc: Hao A Wu -Cc: Jian J Wang -Cc: Liming Gao -Cc: Philippe Mathieu-Daudé -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1743 -Signed-off-by: Laszlo Ersek ---- - -Notes: - v2: - - change the DEC default of the new PCD - (PcdFwVolDxeMaxEncapsulationDepth) from 8 to 16 (0x10) [Liming] - - MdeModulePkg/MdeModulePkg.dec | 6 ++++ - MdeModulePkg/MdeModulePkg.uni | 6 ++++ - MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + - MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c | 33 ++++++++++++++++++-- - 4 files changed, 44 insertions(+), 2 deletions(-) - -diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec -index cb30a7975849..eac19a6edcc5 100644 ---- a/MdeModulePkg/MdeModulePkg.dec -+++ b/MdeModulePkg/MdeModulePkg.dec -@@ -1505,6 +1505,12 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] - # @Prompt Enable Capsule On Disk support. - gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleOnDiskSupport|FALSE|BOOLEAN|0x0000002d - -+ ## Maximum permitted encapsulation levels of sections in a firmware volume, -+ # in the DXE phase. Minimum value is 1. Sections nested more deeply are -+ # rejected. -+ # @Prompt Maximum permitted FwVol section nesting depth (exclusive). -+ gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth|0x10|UINT32|0x00000030 -+ - [PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] - ## This PCD defines the Console output row. The default value is 25 according to UEFI spec. - # This PCD could be set to 0 then console output would be at max column and max row. -diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni -index b8c867379a86..9b1be3220fad 100644 ---- a/MdeModulePkg/MdeModulePkg.uni -+++ b/MdeModulePkg/MdeModulePkg.uni -@@ -1153,6 +1153,12 @@ - "Note:
" - "If Both Capsule In Ram and Capsule On Disk are provisioned at the same time, the Capsule On Disk will be bypassed." - -+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdFwVolDxeMaxEncapsulationDepth_PROMPT #language en-US "Maximum permitted FwVol section nesting depth (exclusive)." -+ -+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdFwVolDxeMaxEncapsulationDepth_HELP #language en-US "Maximum permitted encapsulation levels of sections in a firmware volume,
" -+ "in the DXE phase. Minimum value is 1. Sections nested more deeply are
" -+ "rejected." -+ - #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCapsuleInRamSupport_PROMPT #language en-US "Enable Capsule In Ram support" - - #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdCapsuleInRamSupport_HELP #language en-US "Capsule In Ram is to use memory to deliver the capsules that will be processed after system reset.

" -diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf -index 1d4b11dc7318..e4bca895773d 100644 ---- a/MdeModulePkg/Core/Dxe/DxeMain.inf -+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf -@@ -185,6 +185,7 @@ [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES -+ gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES - - # [Hob] - # RESOURCE_DESCRIPTOR ## CONSUMES -diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -index d7f7ef427422..908617d1ca5c 100644 ---- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -+++ b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c -@@ -955,6 +955,9 @@ CreateChildNode ( - This is an in/out parameter and it is 1-based, - to deal with recursions. - @param SectionDefinitionGuid Guid of section definition -+ @param Depth Nesting depth of encapsulation sections. -+ Callers different from FindChildNode() are -+ responsible for passing in a zero Depth. - @param FoundChild Output indicating the child node that is found. - @param FoundStream Output indicating which section stream the child - was found in. If this stream was generated as a -@@ -968,6 +971,9 @@ CreateChildNode ( - @retval EFI_NOT_FOUND Requested child node does not exist. - @retval EFI_PROTOCOL_ERROR a required GUIDED section extraction protocol - does not exist -+ @retval EFI_ABORTED Recursion aborted because Depth has been -+ greater than or equal to -+ PcdFwVolDxeMaxEncapsulationDepth. - - **/ - EFI_STATUS -@@ -976,6 +982,7 @@ FindChildNode ( - IN EFI_SECTION_TYPE SearchType, - IN OUT UINTN *SectionInstance, - IN EFI_GUID *SectionDefinitionGuid, -+ IN UINT32 Depth, - OUT CORE_SECTION_CHILD_NODE **FoundChild, - OUT CORE_SECTION_STREAM_NODE **FoundStream, - OUT UINT32 *AuthenticationStatus -@@ -990,6 +997,10 @@ FindChildNode ( - - ASSERT (*SectionInstance > 0); - -+ if (Depth >= PcdGet32 (PcdFwVolDxeMaxEncapsulationDepth)) { -+ return EFI_ABORTED; -+ } -+ - CurrentChildNode = NULL; - ErrorStatus = EFI_NOT_FOUND; - -@@ -1053,6 +1064,7 @@ FindChildNode ( - SearchType, - SectionInstance, - SectionDefinitionGuid, -+ Depth + 1, - &RecursedChildNode, - &RecursedFoundStream, - AuthenticationStatus -@@ -1067,9 +1079,17 @@ FindChildNode ( - *FoundStream = RecursedFoundStream; - return EFI_SUCCESS; - } else { -+ if (Status == EFI_ABORTED) { -+ // -+ // If the recursive call was aborted due to nesting depth, stop -+ // looking for the requested child node. The skipped subtree could -+ // throw off the instance counting. -+ // -+ return Status; -+ } - // -- // If the status is not EFI_SUCCESS, just save the error code and -- // continue to find the request child node in the rest stream. -+ // Save the error code and continue to find the requested child node in -+ // the rest of the stream. - // - ErrorStatus = Status; - } -@@ -1272,11 +1292,20 @@ GetSection ( - *SectionType, - &Instance, - SectionDefinitionGuid, -+ 0, // encapsulation depth - &ChildNode, - &ChildStreamNode, - &ExtractedAuthenticationStatus - ); - if (EFI_ERROR (Status)) { -+ if (Status == EFI_ABORTED) { -+ DEBUG ((DEBUG_ERROR, "%a: recursion aborted due to nesting depth\n", -+ __FUNCTION__)); -+ // -+ // Map "aborted" to "not found". -+ // -+ Status = EFI_NOT_FOUND; -+ } - goto GetSection_Done; - } - --- -2.19.1.3.g30247aa5d201 - diff --git a/0015-SecurityPkg-Tcg-Make-Tcg2PlatformDxe-buildable-and-f.patch b/0015-SecurityPkg-Tcg-Make-Tcg2PlatformDxe-buildable-and-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6bcac817d23eaa48c3c01ac443823cf3e1d4ddb --- /dev/null +++ b/0015-SecurityPkg-Tcg-Make-Tcg2PlatformDxe-buildable-and-f.patch @@ -0,0 +1,63 @@ +From edaa95dc147509a6c84225d70476c7dd9179cb57 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:21:00 +0800 +Subject: [PATCH 4/8] SecurityPkg/Tcg: Make Tcg2PlatformDxe buildable and fix + style issues + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h | 4 ++-- + .../PeiDxeTpmPlatformHierarchyLib.c | 2 +- + SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf | 3 +-- + 3 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h +index a872fa09dc..8d61a4867b 100644 +--- a/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h ++++ b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h +@@ -11,8 +11,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ + +-#ifndef _TPM_PLATFORM_HIERARCHY_LIB_H_ +-#define _TPM_PLATFORM_HIERARCHY_LIB_H_ ++#ifndef TPM_PLATFORM_HIERARCHY_LIB_H_ ++#define TPM_PLATFORM_HIERARCHY_LIB_H_ + + /** + This service will perform the TPM Platform Hierarchy configuration at the SmmReadyToLock event. +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +index d82a0ae1bd..0bb04a20fc 100644 +--- a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c +@@ -233,7 +233,7 @@ DisableTpmPlatformHierarchy ( + + /** + This service defines the configuration of the Platform Hierarchy Authorization Value (platformAuth) +- and Platform Hierarchy Authorization Policy (platformPolicy) ++ and Platform Hierarchy Authorization Policy (platformPolicy). + + **/ + VOID +diff --git a/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf +index af29c1cd98..635302fe6f 100644 +--- a/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf ++++ b/SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf +@@ -1,4 +1,4 @@ +-### @file ++## @file + # Platform specific TPM2 component. + # + # Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
+@@ -31,7 +31,6 @@ + [Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec +- MinPlatformPkg/MinPlatformPkg.dec + SecurityPkg/SecurityPkg.dec + + [Sources] +-- +2.27.0 + diff --git a/0016-ArmPkg-CompilerIntrinsicsLib-provide-atomics-intrins.patch b/0016-ArmPkg-CompilerIntrinsicsLib-provide-atomics-intrins.patch deleted file mode 100644 index f8fbca19193aeef7137bb848c1641217dfeaf092..0000000000000000000000000000000000000000 --- a/0016-ArmPkg-CompilerIntrinsicsLib-provide-atomics-intrins.patch +++ /dev/null @@ -1,190 +0,0 @@ -From ca407c7246bf405da6d9b1b9d93e5e7f17b4b1f9 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Wed, 20 May 2020 13:44:48 +0200 -Subject: [PATCH] ArmPkg/CompilerIntrinsicsLib: provide atomics intrinsics - -Gary reports the GCC 10 will emit calls to atomics intrinsics routines -unless -mno-outline-atomics is specified. This means GCC-10 introduces -new intrinsics, and even though it would be possible to work around this -by specifying the command line option, this would require a new GCC10 -toolchain profile to be created, which we prefer to avoid. - -So instead, add the new intrinsics to our library so they are provided -when necessary. - -Signed-off-by: Ard Biesheuvel -Tested-by: Gary Lin -Acked-by: Laszlo Ersek -Reviewed-by: Leif Lindholm -Reviewed-by: Philippe Mathieu-Daude ---- - .../CompilerIntrinsicsLib/AArch64/Atomics.S | 142 ++++++++++++++++++ - .../CompilerIntrinsicsLib.inf | 3 + - 2 files changed, 145 insertions(+) - create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S - -diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S -new file mode 100644 -index 0000000000..3792020ab8 ---- /dev/null -+++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S -@@ -0,0 +1,142 @@ -+#------------------------------------------------------------------------------ -+# -+# Copyright (c) 2020, Arm, Limited. All rights reserved.
-+# -+# SPDX-License-Identifier: BSD-2-Clause-Patent -+# -+#------------------------------------------------------------------------------ -+ -+ /* -+ * Provide the GCC intrinsics that are required when using GCC 9 or -+ * later with the -moutline-atomics options (which became the default -+ * in GCC 10) -+ */ -+ .arch armv8-a -+ -+ .macro reg_alias, pfx, sz -+ r0_\sz .req \pfx\()0 -+ r1_\sz .req \pfx\()1 -+ tmp0_\sz .req \pfx\()16 -+ tmp1_\sz .req \pfx\()17 -+ .endm -+ -+ /* -+ * Define register aliases of the right type for each size -+ * (xN for 8 bytes, wN for everything smaller) -+ */ -+ reg_alias w, 1 -+ reg_alias w, 2 -+ reg_alias w, 4 -+ reg_alias x, 8 -+ -+ .macro fn_start, name:req -+ .section .text.\name -+ .globl \name -+ .type \name, %function -+\name\(): -+ .endm -+ -+ .macro fn_end, name:req -+ .size \name, . - \name -+ .endm -+ -+ /* -+ * Emit an atomic helper for \model with operands of size \sz, using -+ * the operation specified by \insn (which is the LSE name), and which -+ * can be implemented using the generic load-locked/store-conditional -+ * (LL/SC) sequence below, using the arithmetic operation given by -+ * \opc. -+ */ -+ .macro emit_ld_sz, sz:req, insn:req, opc:req, model:req, s, a, l -+ fn_start __aarch64_\insn\()\sz\()\model -+ mov tmp0_\sz, r0_\sz -+0: ld\a\()xr\s r0_\sz, [x1] -+ .ifnc \insn, swp -+ \opc tmp1_\sz, r0_\sz, tmp0_\sz -+ st\l\()xr\s w15, tmp1_\sz, [x1] -+ .else -+ st\l\()xr\s w15, tmp0_\sz, [x1] -+ .endif -+ cbnz w15, 0b -+ ret -+ fn_end __aarch64_\insn\()\sz\()\model -+ .endm -+ -+ /* -+ * Emit atomic helpers for \model for operand sizes in the -+ * set {1, 2, 4, 8}, for the instruction pattern given by -+ * \insn. (This is the LSE name, but this implementation uses -+ * the generic LL/SC sequence using \opc as the arithmetic -+ * operation on the target.) -+ */ -+ .macro emit_ld, insn:req, opc:req, model:req, a, l -+ emit_ld_sz 1, \insn, \opc, \model, b, \a, \l -+ emit_ld_sz 2, \insn, \opc, \model, h, \a, \l -+ emit_ld_sz 4, \insn, \opc, \model, , \a, \l -+ emit_ld_sz 8, \insn, \opc, \model, , \a, \l -+ .endm -+ -+ /* -+ * Emit the compare and swap helper for \model and size \sz -+ * using LL/SC instructions. -+ */ -+ .macro emit_cas_sz, sz:req, model:req, uxt:req, s, a, l -+ fn_start __aarch64_cas\sz\()\model -+ \uxt tmp0_\sz, r0_\sz -+0: ld\a\()xr\s r0_\sz, [x2] -+ cmp r0_\sz, tmp0_\sz -+ bne 1f -+ st\l\()xr\s w15, r1_\sz, [x2] -+ cbnz w15, 0b -+1: ret -+ fn_end __aarch64_cas\sz\()\model -+ .endm -+ -+ /* -+ * Emit compare-and-swap helpers for \model for operand sizes in the -+ * set {1, 2, 4, 8, 16}. -+ */ -+ .macro emit_cas, model:req, a, l -+ emit_cas_sz 1, \model, uxtb, b, \a, \l -+ emit_cas_sz 2, \model, uxth, h, \a, \l -+ emit_cas_sz 4, \model, mov , , \a, \l -+ emit_cas_sz 8, \model, mov , , \a, \l -+ -+ /* -+ * We cannot use the parameterized sequence for 16 byte CAS, so we -+ * need to define it explicitly. -+ */ -+ fn_start __aarch64_cas16\model -+ mov x16, x0 -+ mov x17, x1 -+0: ld\a\()xp x0, x1, [x4] -+ cmp x0, x16 -+ ccmp x1, x17, #0, eq -+ bne 1f -+ st\l\()xp w15, x16, x17, [x4] -+ cbnz w15, 0b -+1: ret -+ fn_end __aarch64_cas16\model -+ .endm -+ -+ /* -+ * Emit the set of GCC outline atomic helper functions for -+ * the memory ordering model given by \model: -+ * - relax unordered loads and stores -+ * - acq load-acquire, unordered store -+ * - rel unordered load, store-release -+ * - acq_rel load-acquire, store-release -+ */ -+ .macro emit_model, model:req, a, l -+ emit_ld ldadd, add, \model, \a, \l -+ emit_ld ldclr, bic, \model, \a, \l -+ emit_ld ldeor, eor, \model, \a, \l -+ emit_ld ldset, orr, \model, \a, \l -+ emit_ld swp, mov, \model, \a, \l -+ emit_cas \model, \a, \l -+ .endm -+ -+ emit_model _relax -+ emit_model _acq, a -+ emit_model _rel,, l -+ emit_model _acq_rel, a, l -diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf -index d5bad94677..fcf48c6781 100644 ---- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf -+++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf -@@ -79,6 +79,9 @@ - Arm/ldivmod.asm | MSFT - Arm/llsr.asm | MSFT - -+[Sources.AARCH64] -+ AArch64/Atomics.S | GCC -+ - [Packages] - MdePkg/MdePkg.dec - ArmPkg/ArmPkg.dec --- -2.27.0 - diff --git a/0016-SecurityPkg-Introduce-new-PCD-PcdRandomizePlatformHi.patch b/0016-SecurityPkg-Introduce-new-PCD-PcdRandomizePlatformHi.patch new file mode 100644 index 0000000000000000000000000000000000000000..6b096da5164edc18eff9184a47d6d4e4ad73965b --- /dev/null +++ b/0016-SecurityPkg-Introduce-new-PCD-PcdRandomizePlatformHi.patch @@ -0,0 +1,53 @@ +From 0282acbc3dee92ee04f1a212ca3f4c77e8b97207 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:21:01 +0800 +Subject: [PATCH 5/8] SecurityPkg: Introduce new PCD + PcdRandomizePlatformHierarchy + +Introduce the new PCD +gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy. +We need it for TpmPlatformHierarchyLib. + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + .../PeiDxeTpmPlatformHierarchyLib.inf | 3 +-- + SecurityPkg/SecurityPkg.dec | 6 ++++++ + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +index 7bf666794f..efe560e7ff 100644 +--- a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf ++++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf +@@ -35,10 +35,9 @@ + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec +- MinPlatformPkg/MinPlatformPkg.dec + + [Sources] + PeiDxeTpmPlatformHierarchyLib.c + + [Pcd] +- gMinPlatformPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy ++ gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy +diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec +index 5335cc5397..276ea6e2dd 100644 +--- a/SecurityPkg/SecurityPkg.dec ++++ b/SecurityPkg/SecurityPkg.dec +@@ -291,6 +291,12 @@ + # @Prompt Physical presence of the platform operator. + gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence|TRUE|BOOLEAN|0x00010001 + ++ ## Indicates whether the TPM2 platform hierarchy will be disabled by using ++ # a random password or by disabling the hierarchy ++ # TRUE - A random password will be used ++ # FALSE - The hierarchy will be disabled ++ gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy|TRUE|BOOLEAN|0x00010024 ++ + [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] + ## Indicates whether TPM physical presence is locked during platform initialization. + # Once it is locked, it can not be unlocked for TPM life time.

+-- +2.27.0 + diff --git a/0017-MdeModulePkg-LzmaCustomDecompressLib-catch-4GB-uncom.patch b/0017-MdeModulePkg-LzmaCustomDecompressLib-catch-4GB-uncom.patch deleted file mode 100644 index 4888c63ce6f33133445e8bea04231ca42d8a13d5..0000000000000000000000000000000000000000 --- a/0017-MdeModulePkg-LzmaCustomDecompressLib-catch-4GB-uncom.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e7bd0dd26db7e56aa8ca70132d6ea916ee6f3db0 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Thu, 19 Nov 2020 12:50:34 +0100 -Subject: [PATCH] MdeModulePkg/LzmaCustomDecompressLib: catch 4GB+ uncompressed - buffer sizes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The LzmaUefiDecompressGetInfo() function -[MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c] currently -silently truncates the UINT64 "DecodedSize" property of the compressed -blob to the UINT32 "DestinationSize" output parameter. - -If "DecodedSize" is 0x1_0000_0100, for example, then the subsequent memory -allocation (for decompression) will likely succeed (allocating 0x100 bytes -only), but then the LzmaUefiDecompress() function (which re-fetches the -uncompressed buffer size from the same LZMA header into a "SizeT" -variable) will overwrite the buffer. - -Catch (DecodedSize > MAX_UINT32) in LzmaUefiDecompressGetInfo() at once. -This should not be a practical limitation. (The issue cannot be fixed for -32-bit systems without spec modifications anyway, given that the -"OutputSize" output parameter of -EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL.ExtractSection() has type UINTN, -not UINT64.) - -Cc: Dandan Bi -Cc: Hao A Wu -Cc: Jian J Wang -Cc: Liming Gao -Cc: Philippe Mathieu-Daudé -Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1816 -Signed-off-by: Laszlo Ersek -Reviewed-by: Liming Gao -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20201119115034.12897-2-lersek@redhat.com> ---- - .../Library/LzmaCustomDecompressLib/LzmaDecompress.c | 7 +++++++ - .../LzmaCustomDecompressLib/LzmaDecompressLibInternal.h | 5 +++++ - 2 files changed, 12 insertions(+) - -diff --git a/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c b/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c -index c58912eb6a..8f7c242dca 100644 ---- a/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c -+++ b/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c -@@ -127,6 +127,10 @@ GetDecodedSizeOfBuf( - in DestinationSize and the size of the scratch - buffer was returned in ScratchSize. - -+ @retval RETURN_UNSUPPORTED DestinationSize cannot be output because the -+ uncompressed buffer size (in bytes) does not fit -+ in a UINT32. Output parameters have not been -+ modified. - **/ - RETURN_STATUS - EFIAPI -@@ -142,6 +146,9 @@ LzmaUefiDecompressGetInfo ( - ASSERT(SourceSize >= LZMA_HEADER_SIZE); - - DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); -+ if (DecodedSize > MAX_UINT32) { -+ return RETURN_UNSUPPORTED; -+ } - - *DestinationSize = (UINT32)DecodedSize; - *ScratchSize = SCRATCH_BUFFER_REQUEST_SIZE; -diff --git a/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompressLibInternal.h b/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompressLibInternal.h -index 26f110ba2a..fbafd5f100 100644 ---- a/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompressLibInternal.h -+++ b/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompressLibInternal.h -@@ -9,6 +9,7 @@ - #ifndef __LZMADECOMPRESSLIB_INTERNAL_H__ - #define __LZMADECOMPRESSLIB_INTERNAL_H__ - -+#include - #include - #include - #include -@@ -45,6 +46,10 @@ - in DestinationSize and the size of the scratch - buffer was returned in ScratchSize. - -+ @retval RETURN_UNSUPPORTED DestinationSize cannot be output because the -+ uncompressed buffer size (in bytes) does not fit -+ in a UINT32. Output parameters have not been -+ modified. - **/ - RETURN_STATUS - EFIAPI --- -2.27.0 - diff --git a/0017-SecurityPkg-Tcg-Import-Tcg2PlatformPei-from-edk2-pla.patch b/0017-SecurityPkg-Tcg-Import-Tcg2PlatformPei-from-edk2-pla.patch new file mode 100644 index 0000000000000000000000000000000000000000..38acd0ec1e1e72ed9cd921d00649bdb6df36a69d --- /dev/null +++ b/0017-SecurityPkg-Tcg-Import-Tcg2PlatformPei-from-edk2-pla.patch @@ -0,0 +1,191 @@ +From ede5db34ee1e35c16cf016b974046b1c499c19a6 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:21:03 +0800 +Subject: [PATCH 6/8] SecurityPkg/Tcg: Import Tcg2PlatformPei from + edk2-platforms + +Import Tcg2PlatformPei from edk2-platforms without any modifications. + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + .../Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c | 107 ++++++++++++++++++ + .../Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf | 52 +++++++++ + 2 files changed, 159 insertions(+) + create mode 100644 SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c + create mode 100644 SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf + +diff --git a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c +new file mode 100644 +index 0000000000..66ec75ad0e +--- /dev/null ++++ b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c +@@ -0,0 +1,107 @@ ++/** @file ++ ++Copyright (c) 2017, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define MAX_NEW_AUTHORIZATION_SIZE SHA512_DIGEST_SIZE ++ ++/** ++ This function handles PlatformInit task at the end of PEI ++ ++ @param[in] PeiServices Pointer to PEI Services Table. ++ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that ++ caused this function to execute. ++ @param[in] Ppi Pointer to the PPI data associated with this function. ++ ++ @retval EFI_SUCCESS The function completes successfully ++ @retval others ++**/ ++EFI_STATUS ++EFIAPI ++PlatformInitEndOfPei ( ++ IN CONST EFI_PEI_SERVICES **PeiServices, ++ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, ++ IN VOID *Ppi ++ ) ++{ ++ VOID *TcgEventLog; ++ ++ // ++ // Try to get TcgEventLog in S3 to see if S3 error is reported. ++ // ++ TcgEventLog = GetFirstGuidHob(&gTcgEventEntryHobGuid); ++ if (TcgEventLog == NULL) { ++ TcgEventLog = GetFirstGuidHob(&gTcgEvent2EntryHobGuid); ++ } ++ ++ if (TcgEventLog == NULL) { ++ // ++ // no S3 error reported ++ // ++ return EFI_SUCCESS; ++ } ++ ++ // ++ // If there is S3 error on TPM_SU_STATE and success on TPM_SU_CLEAR, ++ // configure the TPM Platform Hierarchy. ++ // ++ ConfigureTpmPlatformHierarchy (); ++ ++ return EFI_SUCCESS; ++} ++ ++static EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiNotifyList = { ++ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), ++ &gEfiEndOfPeiSignalPpiGuid, ++ (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitEndOfPei ++}; ++ ++/** ++ Main entry ++ ++ @param[in] FileHandle Handle of the file being invoked. ++ @param[in] PeiServices Pointer to PEI Services table. ++ ++ @retval EFI_SUCCESS Install function successfully. ++ ++**/ ++EFI_STATUS ++EFIAPI ++Tcg2PlatformPeiEntryPoint ( ++ IN EFI_PEI_FILE_HANDLE FileHandle, ++ IN CONST EFI_PEI_SERVICES **PeiServices ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_BOOT_MODE BootMode; ++ ++ Status = PeiServicesGetBootMode (&BootMode); ++ ASSERT_EFI_ERROR(Status); ++ ++ if (BootMode != BOOT_ON_S3_RESUME) { ++ return EFI_SUCCESS; ++ } ++ ++ // ++ // Performing PlatformInitEndOfPei after EndOfPei PPI produced ++ // ++ Status = PeiServicesNotifyPpi (&mEndOfPeiNotifyList); ++ ++ return Status; ++} +diff --git a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf +new file mode 100644 +index 0000000000..579f09b940 +--- /dev/null ++++ b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf +@@ -0,0 +1,52 @@ ++### @file ++# ++# Copyright (c) 2017, Intel Corporation. All rights reserved.
++# ++# SPDX-License-Identifier: BSD-2-Clause-Patent ++# ++### ++ ++[Defines] ++ INF_VERSION = 0x00010017 ++ BASE_NAME = Tcg2PlatformPei ++ FILE_GUID = 47727552-A54B-4A84-8CC1-BFF23E239636 ++ VERSION_STRING = 1.0 ++ MODULE_TYPE = PEIM ++ ENTRY_POINT = Tcg2PlatformPeiEntryPoint ++ ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 IPF EBC ++# ++ ++[LibraryClasses] ++ PcdLib ++ BaseMemoryLib ++ MemoryAllocationLib ++ PeiServicesLib ++ PeimEntryPoint ++ DebugLib ++ Tpm2DeviceLib ++ Tpm2CommandLib ++ TpmPlatformHierarchyLib ++ RngLib ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ SecurityPkg/SecurityPkg.dec ++ MinPlatformPkg/MinPlatformPkg.dec ++ ++[Sources] ++ Tcg2PlatformPei.c ++ ++[Guids] ++ gTcgEventEntryHobGuid ++ gTcgEvent2EntryHobGuid ++ ++[Ppis] ++ gEfiEndOfPeiSignalPpiGuid ++ ++[Depex] ++ gEfiTpmDeviceSelectedGuid ++ +-- +2.27.0 + diff --git a/0018-SecurityPkg-Tcg-Make-Tcg2PlatformPei-buildable-and-f.patch b/0018-SecurityPkg-Tcg-Make-Tcg2PlatformPei-buildable-and-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..3a51c880c88c97e2203214b0a16e06e704fc3232 --- /dev/null +++ b/0018-SecurityPkg-Tcg-Make-Tcg2PlatformPei-buildable-and-f.patch @@ -0,0 +1,63 @@ +From 5134d284aafd4816e265b5c551ee32d6eb43bbc8 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:21:04 +0800 +Subject: [PATCH 7/8] SecurityPkg/Tcg: Make Tcg2PlatformPei buildable and fix + style issues + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c | 11 ++++++----- + SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf | 4 ++-- + 2 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c +index 66ec75ad0e..21d2c1433d 100644 +--- a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c ++++ b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.c +@@ -1,4 +1,5 @@ + /** @file ++ Configure TPM 2 platform hierarchy on TPM state resume failure on S3 resume + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
+@@ -24,12 +25,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + /** + This function handles PlatformInit task at the end of PEI + +- @param[in] PeiServices Pointer to PEI Services Table. +- @param[in] NotifyDesc Pointer to the descriptor for the Notification event that +- caused this function to execute. +- @param[in] Ppi Pointer to the PPI data associated with this function. ++ @param[in] PeiServices Pointer to PEI Services Table. ++ @param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that ++ caused this function to execute. ++ @param[in] Ppi Pointer to the PPI data associated with this function. + +- @retval EFI_SUCCESS The function completes successfully ++ @retval EFI_SUCCESS The function completes successfully + @retval others + **/ + EFI_STATUS +diff --git a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf +index 579f09b940..6f57de025b 100644 +--- a/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf ++++ b/SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf +@@ -1,4 +1,5 @@ +-### @file ++## @file ++# Configure TPM 2 platform hierarchy on TPM state resume failure on S3 resume + # + # Copyright (c) 2017, Intel Corporation. All rights reserved.
+ # +@@ -35,7 +36,6 @@ + [Packages] + MdePkg/MdePkg.dec + SecurityPkg/SecurityPkg.dec +- MinPlatformPkg/MinPlatformPkg.dec + + [Sources] + Tcg2PlatformPei.c +-- +2.27.0 + diff --git a/0019-SecurityPkg-Add-references-to-header-and-inf-files-t.patch b/0019-SecurityPkg-Add-references-to-header-and-inf-files-t.patch new file mode 100644 index 0000000000000000000000000000000000000000..beb2c1fac4bd786b1eeb2204944dd8fe5a3c711e --- /dev/null +++ b/0019-SecurityPkg-Add-references-to-header-and-inf-files-t.patch @@ -0,0 +1,68 @@ +From e031b8396ba1ad059f7c1dc6e28e9fc4ca6aaae9 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 13 Sep 2021 22:21:06 +0800 +Subject: [PATCH 8/8] SecurityPkg: Add references to header and inf files to + SecurityPkg + +Signed-off-by: Stefan Berger +Reviewed-by: Jiewen Yao +--- + SecurityPkg/SecurityPkg.dec | 4 ++++ + SecurityPkg/SecurityPkg.dsc | 12 ++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec +index 276ea6e2dd..beffd08772 100644 +--- a/SecurityPkg/SecurityPkg.dec ++++ b/SecurityPkg/SecurityPkg.dec +@@ -68,6 +68,10 @@ + # + Tcg2PhysicalPresenceLib|Include/Library/Tcg2PhysicalPresenceLib.h + ++ ## @libraryclass Handle TPM 2.0 platform hierarchy configuration ++ # ++ TpmPlatformHierarchyLib|Include/Library/TpmPlatformHierarchyLib.h ++ + ## @libraryclass Provides interfaces about TCG storage generic command. + # + TcgStorageCoreLib|Include/Library/TcgStorageCoreLib.h +diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc +index a2eeadda7a..8d5371295a 100644 +--- a/SecurityPkg/SecurityPkg.dsc ++++ b/SecurityPkg/SecurityPkg.dsc +@@ -211,6 +211,8 @@ + + SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf + ++ SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf ++ + # + # TCG Storage. + # +@@ -272,6 +274,11 @@ + NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf + } + ++ SecurityPkg/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf { ++ ++ TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf ++ } ++ + SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { + + Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf +@@ -288,6 +295,11 @@ + Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf + } + ++ SecurityPkg/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf { ++ ++ TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf ++ } ++ + # + # Hash2 + # +-- +2.27.0 + diff --git a/0020-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch b/0020-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch new file mode 100644 index 0000000000000000000000000000000000000000..a4db4de85ef19faa4fa5ad29d09fd1bd5e043b9b --- /dev/null +++ b/0020-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch @@ -0,0 +1,50 @@ +From 85a19a714c4b4702edc59db0a3419f48fffe2b0a Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 17 Feb 2022 17:38:41 +0800 +Subject: [PATCH] OvmfPkg: VirtioNetDxe: Extend the RxBufferSize to avoid data + truncation + +1822 net card needs at least 1536 bytes for DMA, even we never negotiate +VIRTIO_NET_F_MRG_RXBUF. The original max size of packet is 15144 which would +cause data trucation. Now we extend the RxBufSize to 9014(Jumbo Frame type) +so that we can avoid it. + +Signed-off-by: Jinhua Cao +--- + OvmfPkg/Include/IndustryStandard/Virtio095Net.h | 7 +++++++ + OvmfPkg/VirtioNetDxe/SnpInitialize.c | 3 ++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/OvmfPkg/Include/IndustryStandard/Virtio095Net.h b/OvmfPkg/Include/IndustryStandard/Virtio095Net.h +index 9c0ed5ed24..28f5cc0899 100644 +--- a/OvmfPkg/Include/IndustryStandard/Virtio095Net.h ++++ b/OvmfPkg/Include/IndustryStandard/Virtio095Net.h +@@ -88,4 +88,11 @@ typedef struct { + #define VIRTIO_NET_S_LINK_UP BIT0 + #define VIRTIO_NET_S_ANNOUNCE BIT1 + ++// ++// 1822 net card needs at least 1536 bytes for DMA, even we never negotiate ++// VIRTIO_NET_F_MRG_RXBUF. The original max size of packet is 15144 which would ++// cause data trucation. Now we extend the RxBufSize to 9014(Jumbo Frame type) ++// so that we can avoid it. ++#define VIRTIO_RXBUF_JUMBO_PADDING 7500 ++ + #endif // _VIRTIO_0_9_5_NET_H_ +diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c +index bb3b552d68..6febfea3bb 100644 +--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c ++++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c +@@ -337,7 +337,8 @@ VirtioNetInitRx ( + // and Ethernet payload). + // + RxBufSize = VirtioNetReqSize + +- (Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize); ++ (Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize) + ++ VIRTIO_RXBUF_JUMBO_PADDING; + + // + // Limit the number of pending RX packets if the queue is big. The division +-- +2.27.0 + diff --git a/0021-UefiCpuPkg-Move-MigrateGdt-from-DiscoverMemory-to-Te.patch b/0021-UefiCpuPkg-Move-MigrateGdt-from-DiscoverMemory-to-Te.patch new file mode 100644 index 0000000000000000000000000000000000000000..082e0577963b69e51739f45b56711cb74c169ac3 --- /dev/null +++ b/0021-UefiCpuPkg-Move-MigrateGdt-from-DiscoverMemory-to-Te.patch @@ -0,0 +1,191 @@ +From f6ec1dd34fb6b9757b5ead465ee2ea20c182b0ac Mon Sep 17 00:00:00 2001 +From: Guomin Jiang +Date: Wed, 13 Jan 2021 18:08:09 +0800 +Subject: [PATCH] UefiCpuPkg: Move MigrateGdt from DiscoverMemory to + TempRamDone. (CVE-2019-11098) + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1614 +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3160 + +The GDT still in flash with commit 60b12e69fb1c8c7180fdda92f008248b9ec83db1 +after TempRamDone + +So move the action to TempRamDone event to avoid reading GDT from flash. + +Signed-off-by: Guomin Jiang +Cc: Eric Dong +Cc: Ray Ni +Cc: Laszlo Ersek +Cc: Rahul Kumar +Cc: Debkumar De +Cc: Harry Han +Cc: Catharine West +Reviewed-by: Ray Ni +--- + UefiCpuPkg/CpuMpPei/CpuMpPei.c | 37 -------------------------- + UefiCpuPkg/CpuMpPei/CpuMpPei.inf | 1 - + UefiCpuPkg/CpuMpPei/CpuPaging.c | 8 ------ + UefiCpuPkg/SecCore/SecCore.inf | 1 + + UefiCpuPkg/SecCore/SecMain.c | 45 ++++++++++++++++++++++++++++++++ + 5 files changed, 46 insertions(+), 46 deletions(-) + +diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c +index 40729a09b9..3c1bad6470 100644 +--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c ++++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c +@@ -429,43 +429,6 @@ GetGdtr ( + AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer); + } + +-/** +- Migrates the Global Descriptor Table (GDT) to permanent memory. +- +- @retval EFI_SUCCESS The GDT was migrated successfully. +- @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory. +- +-**/ +-EFI_STATUS +-MigrateGdt ( +- VOID +- ) +-{ +- EFI_STATUS Status; +- UINTN GdtBufferSize; +- IA32_DESCRIPTOR Gdtr; +- VOID *GdtBuffer; +- +- AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr); +- GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1; +- +- Status = PeiServicesAllocatePool ( +- GdtBufferSize, +- &GdtBuffer +- ); +- ASSERT (GdtBuffer != NULL); +- if (EFI_ERROR (Status)) { +- return EFI_OUT_OF_RESOURCES; +- } +- +- GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR)); +- CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1); +- Gdtr.Base = (UINTN) GdtBuffer; +- AsmWriteGdtr (&Gdtr); +- +- return EFI_SUCCESS; +-} +- + /** + Initializes CPU exceptions handlers for the sake of stack switch requirement. + +diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +index ba829d816e..7444bdb968 100644 +--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf ++++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf +@@ -67,7 +67,6 @@ + gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES +- gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES + + [Depex] + TRUE +diff --git a/UefiCpuPkg/CpuMpPei/CpuPaging.c b/UefiCpuPkg/CpuMpPei/CpuPaging.c +index 50ad4277af..3e261d6657 100644 +--- a/UefiCpuPkg/CpuMpPei/CpuPaging.c ++++ b/UefiCpuPkg/CpuMpPei/CpuPaging.c +@@ -605,17 +605,9 @@ MemoryDiscoveredPpiNotifyCallback ( + { + EFI_STATUS Status; + BOOLEAN InitStackGuard; +- BOOLEAN InterruptState; + EDKII_MIGRATED_FV_INFO *MigratedFvInfo; + EFI_PEI_HOB_POINTERS Hob; + +- if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) { +- InterruptState = SaveAndDisableInterrupts (); +- Status = MigrateGdt (); +- ASSERT_EFI_ERROR (Status); +- SetInterruptState (InterruptState); +- } +- + // + // Paging must be setup first. Otherwise the exception TSS setup during MP + // initialization later will not contain paging information and then fail +diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf +index 545781d6b4..ded83beb52 100644 +--- a/UefiCpuPkg/SecCore/SecCore.inf ++++ b/UefiCpuPkg/SecCore/SecCore.inf +@@ -77,6 +77,7 @@ + + [Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES ++ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES + + [UserExtensions.TianoCore."ExtraFiles"] + SecCoreExtra.uni +diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c +index 155be49a60..2416c4ce56 100644 +--- a/UefiCpuPkg/SecCore/SecMain.c ++++ b/UefiCpuPkg/SecCore/SecMain.c +@@ -35,6 +35,43 @@ EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { + } + }; + ++/** ++ Migrates the Global Descriptor Table (GDT) to permanent memory. ++ ++ @retval EFI_SUCCESS The GDT was migrated successfully. ++ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory. ++ ++**/ ++EFI_STATUS ++MigrateGdt ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UINTN GdtBufferSize; ++ IA32_DESCRIPTOR Gdtr; ++ VOID *GdtBuffer; ++ ++ AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr); ++ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1; ++ ++ Status = PeiServicesAllocatePool ( ++ GdtBufferSize, ++ &GdtBuffer ++ ); ++ ASSERT (GdtBuffer != NULL); ++ if (EFI_ERROR (Status)) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR)); ++ CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1); ++ Gdtr.Base = (UINTN) GdtBuffer; ++ AsmWriteGdtr (&Gdtr); ++ ++ return EFI_SUCCESS; ++} ++ + // + // These are IDT entries pointing to 10:FFFFFFE4h. + // +@@ -409,6 +446,14 @@ SecTemporaryRamDone ( + // + State = SaveAndDisableInterrupts (); + ++ // ++ // Migrate GDT before NEM near down ++ // ++ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) { ++ Status = MigrateGdt (); ++ ASSERT_EFI_ERROR (Status); ++ } ++ + // + // Disable Temporary RAM after Stack and Heap have been migrated at this point. + // +-- +2.27.0 + diff --git a/0022-MdeModulePkg-PiSmmCore-SmmEntryPoint-underflow-CVE-2.patch b/0022-MdeModulePkg-PiSmmCore-SmmEntryPoint-underflow-CVE-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..00641eee61f1493958703eb612d00952d957a8d1 --- /dev/null +++ b/0022-MdeModulePkg-PiSmmCore-SmmEntryPoint-underflow-CVE-2.patch @@ -0,0 +1,208 @@ +From cab1f02565d3b29081dd21afb074f35fdb4e1fd6 Mon Sep 17 00:00:00 2001 +From: Miki Demeter +Date: Thu, 27 Oct 2022 16:20:54 -0700 +Subject: [PATCH] MdeModulePkg/PiSmmCore:SmmEntryPoint underflow(CVE-2021-38578) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3387 + +Added use of SafeIntLib to validate values are not causing overflows or +underflows in user controlled values when calculating buffer sizes. + +Signed-off-by: Miki Demeter +Reviewed-by: Michael D Kinney +Cc: Jian J Wang +Cc: Liming Gao +Reviewed-by: Liming Gao +--- + MdeModulePkg/Core/PiSmmCore/PiSmmCore.c | 41 ++++++++++++++++++----- + MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 1 + + MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 1 + + MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 31 +++++++++++++---- + MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | 1 + + 5 files changed, 60 insertions(+), 15 deletions(-) + +diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +index 9e5c6cbe33..875c7c0258 100644 +--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c ++++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +@@ -609,6 +609,7 @@ SmmEndOfS3ResumeHandler ( + @param[in] Size2 Size of Buff2 + + @retval TRUE Buffers overlap in memory. ++ @retval TRUE Math error. Prevents potential math over and underflows. + @retval FALSE Buffer doesn't overlap. + + **/ +@@ -620,11 +621,24 @@ InternalIsBufferOverlapped ( + IN UINTN Size2 + ) + { ++ UINTN End1; ++ UINTN End2; ++ BOOLEAN IsOverUnderflow1; ++ BOOLEAN IsOverUnderflow2; ++ ++ // Check for over or underflow ++ IsOverUnderflow1 = EFI_ERROR (SafeUintnAdd ((UINTN)Buff1, Size1, &End1)); ++ IsOverUnderflow2 = EFI_ERROR (SafeUintnAdd ((UINTN)Buff2, Size2, &End2)); ++ ++ if (IsOverUnderflow1 || IsOverUnderflow2) { ++ return TRUE; ++ } ++ + // + // If buff1's end is less than the start of buff2, then it's ok. + // Also, if buff1's start is beyond buff2's end, then it's ok. + // +- if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) { ++ if ((End1 <= (UINTN)Buff2) || ((UINTN)Buff1 >= End2)) { + return FALSE; + } + +@@ -651,6 +665,7 @@ SmmEntryPoint ( + EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader; + BOOLEAN InLegacyBoot; + BOOLEAN IsOverlapped; ++ BOOLEAN IsOverUnderflow; + VOID *CommunicationBuffer; + UINTN BufferSize; + +@@ -699,23 +714,31 @@ SmmEntryPoint ( + (UINT8 *) gSmmCorePrivate, + sizeof (*gSmmCorePrivate) + ); +- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) || IsOverlapped) { ++ // ++ // Check for over or underflows ++ // ++ IsOverUnderflow = EFI_ERROR (SafeUintnSub (BufferSize, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data), &BufferSize)); ++ ++ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) || ++ IsOverlapped || IsOverUnderflow) ++ { + // + // If CommunicationBuffer is not in valid address scope, + // or there is overlap between gSmmCorePrivate and CommunicationBuffer, ++ // or there is over or underflow, + // return EFI_INVALID_PARAMETER + // + gSmmCorePrivate->CommunicationBuffer = NULL; + gSmmCorePrivate->ReturnStatus = EFI_ACCESS_DENIED; + } else { + CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer; +- BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); +- Status = SmiManage ( +- &CommunicateHeader->HeaderGuid, +- NULL, +- CommunicateHeader->Data, +- &BufferSize +- ); ++ // BufferSize was updated by the SafeUintnSub() call above. ++ Status = SmiManage ( ++ &CommunicateHeader->HeaderGuid, ++ NULL, ++ CommunicateHeader->Data, ++ &BufferSize ++ ); + // + // Update CommunicationBuffer, BufferSize and ReturnStatus + // Communicate service finished, reset the pointer to CommBuffer to NULL +diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +index 71422b9dfc..b8a490a8c3 100644 +--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h ++++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + #include "PiSmmCorePrivateData.h" + #include "HeapGuard.h" +diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +index c8bfae3860..3df44b38f1 100644 +--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf ++++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +@@ -60,6 +60,7 @@ + PerformanceLib + HobLib + SmmMemLib ++ SafeIntLib + + [Protocols] + gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister +diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +index 4f00cebaf5..fbba868fd0 100644 +--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c ++++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +@@ -34,8 +34,8 @@ + #include + #include + #include +- + #include "PiSmmCorePrivateData.h" ++#include + + #define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC) + +@@ -1354,6 +1354,7 @@ SmmSplitSmramEntry ( + @param[in] ReservedRangeToCompare Pointer to EFI_SMM_RESERVED_SMRAM_REGION to compare. + + @retval TRUE There is overlap. ++ @retval TRUE Math error. + @retval FALSE There is no overlap. + + **/ +@@ -1353,11 +1354,29 @@ SmmIsSmramOverlap ( + IN EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare + ) + { +- UINT64 RangeToCompareEnd; +- UINT64 ReservedRangeToCompareEnd; +- +- RangeToCompareEnd = RangeToCompare->CpuStart + RangeToCompare->PhysicalSize; +- ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart + ReservedRangeToCompare->SmramReservedSize; ++ UINT64 RangeToCompareEnd; ++ UINT64 ReservedRangeToCompareEnd; ++ BOOLEAN IsOverUnderflow1; ++ BOOLEAN IsOverUnderflow2; ++ ++ // Check for over or underflow. ++ IsOverUnderflow1 = EFI_ERROR ( ++ SafeUint64Add ( ++ (UINT64)RangeToCompare->CpuStart, ++ RangeToCompare->PhysicalSize, ++ &RangeToCompareEnd ++ ) ++ ); ++ IsOverUnderflow2 = EFI_ERROR ( ++ SafeUint64Add ( ++ (UINT64)ReservedRangeToCompare->SmramReservedStart, ++ ReservedRangeToCompare->SmramReservedSize, ++ &ReservedRangeToCompareEnd ++ ) ++ ); ++ if (IsOverUnderflow1 || IsOverUnderflow2) { ++ return TRUE; ++ } + + if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart) && + (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) { +diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +index 6109d6b544..ddeb39cee2 100644 +--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf ++++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +@@ -46,6 +46,7 @@ + DxeServicesLib + PcdLib + ReportStatusCodeLib ++ SafeIntLib + + [Protocols] + gEfiSmmBase2ProtocolGuid ## PRODUCES +-- +2.27.0 + diff --git a/0023-PATCH-Avoid-dangling-ptrs-in-header-and-data-params-.patch b/0023-PATCH-Avoid-dangling-ptrs-in-header-and-data-params-.patch new file mode 100644 index 0000000000000000000000000000000000000000..99ddb6f8caf3c7085de4267e094aa52856d60ba6 --- /dev/null +++ b/0023-PATCH-Avoid-dangling-ptrs-in-header-and-data-params-.patch @@ -0,0 +1,43 @@ +From a114dc3c9af48a8f8ed22e738944a9c3e830a088 Mon Sep 17 00:00:00 2001 +From Shao Denghui +Date: Mon, 20 Feb 2023 21:59:31 +0800 +Subject: [PATCH] [PATCH] Avoid dangling ptrs in header and data params for + PEM_read_bio_ex In the event of a failure in PEM_read_bio_ex() we free the + buffers we allocated for the header and data buffers. However we were not + clearing the ptrs stored in *header and *data. Since, on success, the caller + is responsible for freeing these ptrs this can potentially lead to a double + free if the caller frees them even on failure. + +Thanks to Dawei Wang for reporting this issue. + +Based on a proposed patch by Kurt Roeckx. + +CVE-2022-4450 + +Reference: https://github.com/openssl/openssl/commit/ee6243f3947107d655f6dee96f63861561a5aaeb + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz + +Signed-off-by: Shao Denghui +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c +index 64baf71..6c7c4fe 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c +@@ -940,7 +940,9 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, + *data = pem_malloc(len, flags); + if (*header == NULL || *data == NULL) { + pem_free(*header, flags, 0); ++ *header = NULL; + pem_free(*data, flags, 0); ++ *data = NULL; + goto end; + } + BIO_read(headerB, *header, headerlen); +-- +2.27.0 + diff --git a/0024-PATCH-pk7_doit.c-Check-return-of-BIO_set_md-calls.patch b/0024-PATCH-pk7_doit.c-Check-return-of-BIO_set_md-calls.patch new file mode 100644 index 0000000000000000000000000000000000000000..9852ad6fce9b023892b7d279ce37febdabd9dda1 --- /dev/null +++ b/0024-PATCH-pk7_doit.c-Check-return-of-BIO_set_md-calls.patch @@ -0,0 +1,57 @@ +From 7dd5a23212e3c7bf25a9cd7689681beb89b2d20f Mon Sep 17 00:00:00 2001 +From Shao Denghui +Date: Tue, 21 Feb 2023 20:12:59 +0800 +Subject: [PATCH] [PATCH] pk7_doit.c: Check return of BIO_set_md() calls + +These calls invoke EVP_DigestInit() which can fail for digests +with implicit fetches. Subsequent EVP_DigestUpdate() from BIO_write() +or EVP_DigestFinal() from BIO_read() will segfault on NULL +dereference. This can be triggered by an attacker providing +PKCS7 data digested with MD4 for example if the legacy provider +is not loaded. + +If BIO_set_md() fails the md BIO cannot be used. + +CVE-2023-0401 + +Reference: https://github.com/openssl/openssl/commit/6eebe6c0238178356114a96a7858f36b24172847 + +Reviewed-by: Paul Dale +Reviewed-by: Richard Levitte + +Signed-off-by: Shao Denghui +--- + .../Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c +index f63fbc5..bbfcf27 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c +@@ -67,7 +67,10 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) + goto err; + } + +- BIO_set_md(btmp, md); ++ if (BIO_set_md(btmp, md) <= 0) { ++ PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); ++ goto err; ++ } + if (*pbio == NULL) + *pbio = btmp; + else if (!BIO_push(*pbio, btmp)) { +@@ -454,7 +457,10 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) + goto err; + } + +- BIO_set_md(btmp, evp_md); ++ if (BIO_set_md(btmp, evp_md) <= 0) { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); ++ goto err; ++ } + if (out == NULL) + out = btmp; + else +-- +2.27.0 + diff --git a/0025-Fix-a-UAF-resulting-from-a-bug-in-BIO_new_NDEF.patch b/0025-Fix-a-UAF-resulting-from-a-bug-in-BIO_new_NDEF.patch new file mode 100644 index 0000000000000000000000000000000000000000..0c517923a0764e7447b3a81a5c23a08c0666c589 --- /dev/null +++ b/0025-Fix-a-UAF-resulting-from-a-bug-in-BIO_new_NDEF.patch @@ -0,0 +1,106 @@ +From 93bb2a5f1df1617502c24f287ea4e5ca351aef95 Mon Sep 17 00:00:00 2001 +From: chenhuiying +Date: Sat, 25 Feb 2023 15:05:15 +0800 +Subject: [PATCH] Fix a UAF resulting from a bug in BIO_new_NDEF + +If the aux->asn1_cb() call fails in BIO_new_NDEF then the "out" BIO will +be part of an invalid BIO chain. This causes a "use after free" when the +BIO is eventually freed. + +Based on an original patch by Viktor Dukhovni and an idea from Theo +Buehler. + +Thanks to Octavio Galland for reporting this issue. + +REF: https://github.com/openssl/openssl/commit/c3829dd8825c654652201e16f8a0a0c46ee3f344 +Signed-off-by: chenhuiying +--- + .../OpensslLib/openssl/crypto/asn1/bio_ndef.c | 39 +++++++++++++++---- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c +index 6222c99..cf52468 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c +@@ -49,12 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); + static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg); + ++/* ++ * On success, the returned BIO owns the input BIO as part of its BIO chain. ++ * On failure, NULL is returned and the input BIO is owned by the caller. ++ * ++ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() ++ */ + BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) + { + NDEF_SUPPORT *ndef_aux = NULL; + BIO *asn_bio = NULL; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; ++ BIO *pop_bio = NULL; + + if (!aux || !aux->asn1_cb) { + ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); +@@ -69,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) + out = BIO_push(asn_bio, out); + if (out == NULL) + goto err; ++ pop_bio = asn_bio; + +- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); +- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); ++ if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0 ++ || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0 ++ || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0) ++ goto err; + + /* +- * Now let callback prepends any digest, cipher etc BIOs ASN1 structure +- * needs. ++ * Now let the callback prepend any digest, cipher, etc., that the BIO's ++ * ASN1 structure needs. + */ + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + +- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) ++ /* ++ * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the ++ * middle of some partially built, but not returned BIO chain. ++ */ ++ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) { ++ /* ++ * ndef_aux is now owned by asn_bio so we must not free it in the err ++ * clean up block ++ */ ++ ndef_aux = NULL; + goto err; ++ } ++ ++ /* ++ * We must not fail now because the callback has prepended additional ++ * BIOs to the chain ++ */ + + ndef_aux->val = val; + ndef_aux->it = it; +@@ -91,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) + ndef_aux->boundary = sarg.boundary; + ndef_aux->out = out; + +- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); +- + return sarg.ndef_bio; + + err: ++ /* BIO_pop() is NULL safe */ ++ (void)BIO_pop(pop_bio); + BIO_free(asn_bio); + OPENSSL_free(ndef_aux); + return NULL; +-- +2.27.0 + diff --git a/0026-Check-CMS-failure-during-BIO-setup-with-stream-is-ha.patch b/0026-Check-CMS-failure-during-BIO-setup-with-stream-is-ha.patch new file mode 100644 index 0000000000000000000000000000000000000000..f42b4369200dadc8faec4fac0f9971f5753149ed --- /dev/null +++ b/0026-Check-CMS-failure-during-BIO-setup-with-stream-is-ha.patch @@ -0,0 +1,79 @@ +From cb81a80d059f41b0930fcc36c36a155244f3873a Mon Sep 17 00:00:00 2001 +From: chenhuiying +Date: Sat, 25 Feb 2023 16:18:41 +0800 +Subject: [PATCH] Check CMS failure during BIO setup with -stream is handled correctly + +Test for the issue fixed in the previous commit + +REF:https://github.com/openssl/openssl/commit/f040f2577891d2bdb7610566c172233844cf673a +Signed-off-by: chenhuiying +--- + .../openssl/test/recipes/80-test_cms.t | 15 +++++++++++++-- + .../openssl/test/smime-certs/badrsa.pem | 18 ++++++++++++++++++ + 2 files changed, 31 insertions(+), 2 deletions(-) + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/badrsa.pem + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cms.t b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cms.t +index 5dc6a3a..ec11bfc 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cms.t ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cms.t +@@ -13,7 +13,7 @@ use warnings; + use POSIX; + use File::Spec::Functions qw/catfile/; + use File::Compare qw/compare_text/; +-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file/; ++use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file with/; + use OpenSSL::Test::Utils; + + setup("test_cms"); +@@ -27,7 +27,7 @@ my $smcont = srctop_file("test", "smcont.txt"); + my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) + = disabled qw/des dh dsa ec ec2m rc2 zlib/; + +-plan tests => 6; ++plan tests => 7; + + my @smime_pkcs7_tests = ( + +@@ -584,3 +584,14 @@ sub check_availability { + + return ""; + } ++ ++# Check that we get the expected failure return code ++with({ exit_checker => sub { return shift == 6; } }, ++ sub { ++ ok(run(app(['openssl', 'cms', '-encrypt', ++ '-in', srctop_file("test", "smcont.txt"), ++ '-stream', '-recip', ++ srctop_file("test/smime-certs", "badrsa.pem"), ++ ])), ++ "Check failure during BIO setup with -stream is handled correctly"); ++ }); +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/badrsa.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/badrsa.pem +new file mode 100644 +index 0000000..f824fc2 +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/badrsa.pem +@@ -0,0 +1,18 @@ ++-----BEGIN CERTIFICATE----- ++MIIDbTCCAlWgAwIBAgIToTV4Z0iuK08vZP20oTh//hC8BDANBgkqhkiG9w0BAQ0FADAtMSswKQYD ++VfcDEyJTYW1wbGUgTEFNUFMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTE5MTEyMDA2NTQxOFoY ++DzIwNTIwOTI3MDY1NDE4WjAZMRcwFQYDVQQDEw5BbGljZSBMb3ZlbGFjZTCCASIwDQYJKoZIhvcN ++AQEBBQADggEPADCCAQoCggEBALT0iehYOBY+TZp/T5K2KNI05Hwr+E3wP6XTvyi6WWyTgBK9LCOw ++I2juwdRrjFBmXkk7pWpjXwsA3A5GOtz0FpfgyC7OxsVcF7q4WHWZWleYXFKlQHJD73nQwXP968+A ++/3rBX7PhO0DBbZnfitOLPgPEwjTtdg0VQQ6Wz+CRQ/YbHPKaw7aRphZO63dKvIKp4cQVtkWQHi6s ++yTjGsgkLcLNau5LZDQUdsGV+SAo3nBdWCRYV+I65x8Kf4hCxqqmjV3d/2NKRu0BXnDe/N+iDz3X0 ++zEoj0fqXgq4SWcC0nsG1lyyXt1TL270I6ATKRGJWiQVCCpDtc0NT6vdJ45bCSxgCAwEAAaOBlzCB ++lDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE2FsaWNlQHNtaW1lLmV4YW1wbGUwEwYDVR0lBAww ++CgYIKwYBBQUHAwQwDwYDVR0PAQH/BAUDAwfAADAdBgNVHQ4EFgQUu/bMsi0dBhIcl64papAQ0yBm ++ZnMwHwYDVR0jBBgwFoAUeF8OWnjYa+RUcD2z3ez38fL6wEcwDQYJKoZIhvcNAQENBQADggEBABbW ++eonR6TMTckehDKNOabwaCIcekahAIL6l9tTzUX5ew6ufiAPlC6I/zQlmUaU0iSyFDG1NW14kNbFt ++5CAokyLhMtE4ASHBIHbiOp/ZSbUBTVYJZB61ot7w1/ol5QECSs08b8zrxIncf+t2DHGuVEy/Qq1d ++rBz8d4ay8zpqAE1tUyL5Da6ZiKUfWwZQXSI/JlbjQFzYQqTRDnzHWrg1xPeMTO1P2/cplFaseTiv ++yk4cYwOp/W9UAWymOZXF8WcJYCIUXkdcG/nEZxr057KlScrJmFXOoh7Y+8ON4iWYYcAfiNgpUFo/ ++j8BAwrKKaFvdlZS9k1Ypb2+UQY75mKJE9Bg= ++-----END CERTIFICATE----- +-- +2.27.0 + diff --git a/0027-Correctly-compare-EdiPartyName-in-GENERAL_NAME_cmp.patch b/0027-Correctly-compare-EdiPartyName-in-GENERAL_NAME_cmp.patch new file mode 100644 index 0000000000000000000000000000000000000000..e670922a93780088a750eb54a88f4fed5dfd496d --- /dev/null +++ b/0027-Correctly-compare-EdiPartyName-in-GENERAL_NAME_cmp.patch @@ -0,0 +1,102 @@ +From fe9395b9fe1507236eafd147dc0cd4a8c9bf1fe6 Mon Sep 17 00:00:00 2001 +From: chenhuiying +Date: Sat, 25 Feb 2023 17:54:23 +0800 +Subject: [PATCH] Correctly compare EdiPartyName in GENERAL_NAME_cmp() + +If a GENERAL_NAME field contained EdiPartyName data then it was +incorrectly being handled as type "other". This could lead to a +segmentation fault. + +Many thanks to David Benjamin from Google for reporting this issue. + +CVE-2020-1971 + +reference: https://github.com/openssl/openssl/commit/f960d81215ebf3f65e03d4d5d857fb9b666d6920 +Signed-off-by: chenhuiying +--- + .../openssl/crypto/x509v3/v3_genn.c | 45 +++++++++++++++++-- + 1 file changed, 42 insertions(+), 3 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c +index 23e3bc4..23778e2 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c +@@ -57,6 +57,37 @@ GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) + (char *)a); + } + ++static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) ++{ ++ int res; ++ ++ if (a == NULL || b == NULL) { ++ /* ++ * Shouldn't be possible in a valid GENERAL_NAME, but we handle it ++ * anyway. OTHERNAME_cmp treats NULL != NULL so we do the same here ++ */ ++ return -1; ++ } ++ if (a->nameAssigner == NULL && b->nameAssigner != NULL) ++ return -1; ++ if (a->nameAssigner != NULL && b->nameAssigner == NULL) ++ return 1; ++ /* If we get here then both have nameAssigner set, or both unset */ ++ if (a->nameAssigner != NULL) { ++ res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner); ++ if (res != 0) ++ return res; ++ } ++ /* ++ * partyName is required, so these should never be NULL. We treat it in ++ * the same way as the a == NULL || b == NULL case above ++ */ ++ if (a->partyName == NULL || b->partyName == NULL) ++ return -1; ++ ++ return ASN1_STRING_cmp(a->partyName, b->partyName); ++} ++ + /* Returns 0 if they are equal, != 0 otherwise. */ + int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + { +@@ -66,8 +97,11 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + return -1; + switch (a->type) { + case GEN_X400: ++ result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); ++ break; ++ + case GEN_EDIPARTY: +- result = ASN1_TYPE_cmp(a->d.other, b->d.other); ++ result = edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); + break; + + case GEN_OTHERNAME: +@@ -114,8 +148,11 @@ void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) + { + switch (type) { + case GEN_X400: ++ a->d.x400Address = value; ++ break; ++ + case GEN_EDIPARTY: +- a->d.other = value; ++ a->d.ediPartyName = value; + break; + + case GEN_OTHERNAME: +@@ -149,8 +186,10 @@ void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: ++ return a->d.x400Address; ++ + case GEN_EDIPARTY: +- return a->d.other; ++ return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; +-- +2.27.0 + diff --git a/0028-CVE-2023-0286-Fix-GENERAL_NAME_cmp-for-x400Address-1.patch b/0028-CVE-2023-0286-Fix-GENERAL_NAME_cmp-for-x400Address-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..24e3c8a9b64f3a28bbb093777d01ffc32b709b79 --- /dev/null +++ b/0028-CVE-2023-0286-Fix-GENERAL_NAME_cmp-for-x400Address-1.patch @@ -0,0 +1,41 @@ +From 7553d2119f3c899f779eaacafff63feaa843814a Mon Sep 17 00:00:00 2001 +From: s00803682 +Date: Sat, 25 Feb 2023 18:22:13 +0800 +Subject: [PATCH] CVE-2023-0286: Fix GENERAL_NAME_cmp for x400Address (1.1.1) + +REF: https://github.com/openssl/openssl/commit/2c6c9d439b484e1ba9830d8454a34fa4f80fdfe9 +Signed-off-by: chenhuiying +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c | 2 +- + CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c +index 23778e2..12ce733 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c +@@ -97,7 +97,7 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + return -1; + switch (a->type) { + case GEN_X400: +- result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); ++ result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); + break; + + case GEN_EDIPARTY: +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h +index 6c6eca3..b80438d 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h +@@ -136,7 +136,7 @@ typedef struct GENERAL_NAME_st { + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; +- ASN1_TYPE *x400Address; ++ ASN1_STRING *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; +-- +2.27.0 + diff --git a/0029-BaseTools-fix-ucs-2-lookup-on-python-3.9.patch b/0029-BaseTools-fix-ucs-2-lookup-on-python-3.9.patch deleted file mode 100644 index a643451ad98757dcc9e16799627cc3de5662ec28..0000000000000000000000000000000000000000 --- a/0029-BaseTools-fix-ucs-2-lookup-on-python-3.9.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 5df044496a30e4fa62b71513f3ae87400ceff4c4 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Wed, 12 Aug 2020 01:28:17 +0800 -Subject: [PATCH] BaseTools: fix ucs-2 lookup on python 3.9 - -python3.9 changed/fixed codec.register behavior to always replace -hyphen with underscore for passed in codec names: - - https://bugs.python.org/issue37751 - -So the custom Ucs2Search needs to be adapted to handle 'ucs_2' in -addition to existing 'ucs-2' for back compat. - -This fixes test failures on python3.9, example: - -====================================================================== -FAIL: testUtf16InUniFile (CheckUnicodeSourceFiles.Tests) ----------------------------------------------------------------------- -Traceback (most recent call last): - File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 375, in PreProcess - FileIn = UniFileClassObject.OpenUniFile(LongFilePath(File.Path)) - File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 303, in OpenUniFile - UniFileClassObject.VerifyUcs2Data(FileIn, FileName, Encoding) - File "/builddir/build/BUILD/edk2-edk2-stable202002/BaseTools/Source/Python/AutoGen/UniClassObject.py", line 312, in VerifyUcs2Data - Ucs2Info = codecs.lookup('ucs-2') -LookupError: unknown encoding: ucs-2 - -Signed-off-by: Cole Robinson -Reviewed-by: Yuwei Chen -Reviewed-by: Bob Feng -Signed-off-by: Jinhua Cao ---- - BaseTools/Source/Python/AutoGen/UniClassObject.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/BaseTools/Source/Python/AutoGen/UniClassObject.py b/BaseTools/Source/Python/AutoGen/UniClassObject.py -index b2895f7e5c..883c2356e0 100644 ---- a/BaseTools/Source/Python/AutoGen/UniClassObject.py -+++ b/BaseTools/Source/Python/AutoGen/UniClassObject.py -@@ -152,7 +152,7 @@ class Ucs2Codec(codecs.Codec): - - TheUcs2Codec = Ucs2Codec() - def Ucs2Search(name): -- if name == 'ucs-2': -+ if name in ['ucs-2', 'ucs_2']: - return codecs.CodecInfo( - name=name, - encode=TheUcs2Codec.encode, --- -2.27.0 - diff --git a/0029-Fix-Timing-Oracle-in-RSA-decryption.patch b/0029-Fix-Timing-Oracle-in-RSA-decryption.patch new file mode 100644 index 0000000000000000000000000000000000000000..3e5762570fe5b1469ef1a90eb502db1baeec5265 --- /dev/null +++ b/0029-Fix-Timing-Oracle-in-RSA-decryption.patch @@ -0,0 +1,834 @@ +From df422474e4e7e2f380840eeb9d6e466312fe0879 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 20 Jan 2023 15:26:54 +0000 +Subject: [PATCH] Fix Timing Oracle in RSA decryption + +A timing based side channel exists in the OpenSSL RSA Decryption +implementation which could be sufficient to recover a plaintext across +a network in a Bleichenbacher style attack. To achieve a successful +decryption an attacker would have to be able to send a very large number +of trial messages for decryption. The vulnerability affects all RSA +padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE. + +Patch written by Dmitry Belyavsky and Hubert Kario + +CVE-2022-4304 + +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Tomas Mraz + +reference: https://github.com/openssl/openssl/pull/20284 +Signed-off-by: yexiao +--- + CryptoPkg/Library/OpensslLib/OpensslLib.inf | 1 + + .../Library/OpensslLib/OpensslLibCrypto.inf | 1 + + .../OpensslLib/openssl/crypto/bn/bn_blind.c | 14 - + .../OpensslLib/openssl/crypto/bn/bn_err.c | 2 + + .../OpensslLib/openssl/crypto/bn/bn_local.h | 14 + + .../OpensslLib/openssl/crypto/bn/build.info | 3 +- + .../openssl/crypto/bn/rsa_sup_mul.c | 614 ++++++++++++++++++ + .../OpensslLib/openssl/crypto/err/openssl.txt | 3 +- + .../OpensslLib/openssl/crypto/rsa/rsa_ossl.c | 17 +- + .../OpensslLib/openssl/include/crypto/bn.h | 5 + + .../openssl/include/openssl/bnerr.h | 1 + + 11 files changed, 655 insertions(+), 20 deletions(-) + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsa_sup_mul.c + +diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +index b00bb74..ec5be59 100644 +--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf ++++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf +@@ -155,6 +155,7 @@ + $(OPENSSL_PATH)/crypto/bn/bn_sqr.c + $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c + $(OPENSSL_PATH)/crypto/bn/bn_srp.c ++ $(OPENSSL_PATH)/crypto/bn/rsa_sup_mul.c + $(OPENSSL_PATH)/crypto/bn/bn_word.c + $(OPENSSL_PATH)/crypto/bn/bn_x931p.c + $(OPENSSL_PATH)/crypto/buffer/buf_err.c +diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf +index 3557711..ee68e48 100644 +--- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf ++++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf +@@ -155,6 +155,7 @@ + $(OPENSSL_PATH)/crypto/bn/bn_sqr.c + $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c + $(OPENSSL_PATH)/crypto/bn/bn_srp.c ++ $(OPENSSL_PATH)/crypto/bn/rsa_sup_mul.c + $(OPENSSL_PATH)/crypto/bn/bn_word.c + $(OPENSSL_PATH)/crypto/bn/bn_x931p.c + $(OPENSSL_PATH)/crypto/buffer/buf_err.c +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c +index 76fc7eb..6e9d239 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c +@@ -13,20 +13,6 @@ + + #define BN_BLINDING_COUNTER 32 + +-struct bn_blinding_st { +- BIGNUM *A; +- BIGNUM *Ai; +- BIGNUM *e; +- BIGNUM *mod; /* just a reference */ +- CRYPTO_THREAD_ID tid; +- int counter; +- unsigned long flags; +- BN_MONT_CTX *m_ctx; +- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +- CRYPTO_RWLOCK *lock; +-}; +- + BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) + { + BN_BLINDING *ret = NULL; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c +index dd87c15..3dd8d9a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c +@@ -73,6 +73,8 @@ static const ERR_STRING_DATA BN_str_functs[] = { + {ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"}, + {ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"}, + {ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"}, ++ {ERR_PACK(ERR_LIB_BN, BN_F_OSSL_BN_RSA_DO_UNBLIND, 0), ++ "ossl_bn_rsa_do_unblind"}, + {0, NULL} + }; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_local.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_local.h +index 8ad69cc..0965135 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_local.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_local.h +@@ -263,6 +263,20 @@ struct bn_gencb_st { + } cb; + }; + ++struct bn_blinding_st { ++ BIGNUM *A; ++ BIGNUM *Ai; ++ BIGNUM *e; ++ BIGNUM *mod; /* just a reference */ ++ CRYPTO_THREAD_ID tid; ++ int counter; ++ unsigned long flags; ++ BN_MONT_CTX *m_ctx; ++ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, ++ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); ++ CRYPTO_RWLOCK *lock; ++}; ++ + /*- + * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions + * +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info +index b9ed532..c9fe2fd 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info +@@ -5,7 +5,8 @@ SOURCE[../../libcrypto]=\ + bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \ + {- $target{bn_asm_src} -} \ + bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \ +- bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c ++ bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c \ ++ rsa_sup_mul.c + + INCLUDE[bn_exp.o]=.. + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsa_sup_mul.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsa_sup_mul.c +new file mode 100644 +index 0000000..acafefd +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsa_sup_mul.c +@@ -0,0 +1,614 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "internal/numbers.h" ++#include "internal/constant_time.h" ++#include "bn_local.h" ++ ++# if BN_BYTES == 8 ++typedef uint64_t limb_t; ++# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16 ++/* nonstandard; implemented by gcc on 64-bit platforms */ ++typedef __uint128_t limb2_t; ++# define HAVE_LIMB2_T ++# endif ++# define LIMB_BIT_SIZE 64 ++# define LIMB_BYTE_SIZE 8 ++# elif BN_BYTES == 4 ++typedef uint32_t limb_t; ++typedef uint64_t limb2_t; ++# define LIMB_BIT_SIZE 32 ++# define LIMB_BYTE_SIZE 4 ++# define HAVE_LIMB2_T ++# else ++# error "Not supported" ++# endif ++ ++/* ++ * For multiplication we're using schoolbook multiplication, ++ * so if we have two numbers, each with 6 "digits" (words) ++ * the multiplication is calculated as follows: ++ * A B C D E F ++ * x I J K L M N ++ * -------------- ++ * N*F ++ * N*E ++ * N*D ++ * N*C ++ * N*B ++ * N*A ++ * M*F ++ * M*E ++ * M*D ++ * M*C ++ * M*B ++ * M*A ++ * L*F ++ * L*E ++ * L*D ++ * L*C ++ * L*B ++ * L*A ++ * K*F ++ * K*E ++ * K*D ++ * K*C ++ * K*B ++ * K*A ++ * J*F ++ * J*E ++ * J*D ++ * J*C ++ * J*B ++ * J*A ++ * I*F ++ * I*E ++ * I*D ++ * I*C ++ * I*B ++ * + I*A ++ * ========================== ++ * N*B N*D N*F ++ * + N*A N*C N*E ++ * + M*B M*D M*F ++ * + M*A M*C M*E ++ * + L*B L*D L*F ++ * + L*A L*C L*E ++ * + K*B K*D K*F ++ * + K*A K*C K*E ++ * + J*B J*D J*F ++ * + J*A J*C J*E ++ * + I*B I*D I*F ++ * + I*A I*C I*E ++ * ++ * 1+1 1+3 1+5 ++ * 1+0 1+2 1+4 ++ * 0+1 0+3 0+5 ++ * 0+0 0+2 0+4 ++ * ++ * 0 1 2 3 4 5 6 ++ * which requires n^2 multiplications and 2n full length additions ++ * as we can keep every other result of limb multiplication in two separate ++ * limbs ++ */ ++ ++#if defined HAVE_LIMB2_T ++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) ++{ ++ limb2_t t; ++ /* ++ * this is idiomatic code to tell compiler to use the native mul ++ * those three lines will actually compile to single instruction ++ */ ++ ++ t = (limb2_t)a * b; ++ *hi = t >> LIMB_BIT_SIZE; ++ *lo = (limb_t)t; ++} ++#elif (BN_BYTES == 8) && (defined _MSC_VER) ++/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */ ++#pragma intrinsic(_umul128) ++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) ++{ ++ *lo = _umul128(a, b, hi); ++} ++#else ++/* ++ * if the compiler doesn't have either a 128bit data type nor a "return ++ * high 64 bits of multiplication" ++ */ ++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b) ++{ ++ limb_t a_low = (limb_t)(uint32_t)a; ++ limb_t a_hi = a >> 32; ++ limb_t b_low = (limb_t)(uint32_t)b; ++ limb_t b_hi = b >> 32; ++ ++ limb_t p0 = a_low * b_low; ++ limb_t p1 = a_low * b_hi; ++ limb_t p2 = a_hi * b_low; ++ limb_t p3 = a_hi * b_hi; ++ ++ uint32_t cy = (uint32_t)(((p0 >> 32) + (uint32_t)p1 + (uint32_t)p2) >> 32); ++ ++ *lo = p0 + (p1 << 32) + (p2 << 32); ++ *hi = p3 + (p1 >> 32) + (p2 >> 32) + cy; ++} ++#endif ++ ++/* add two limbs with carry in, return carry out */ ++static ossl_inline limb_t _add_limb(limb_t *ret, limb_t a, limb_t b, limb_t carry) ++{ ++ limb_t carry1, carry2, t; ++ /* ++ * `c = a + b; if (c < a)` is idiomatic code that makes compilers ++ * use add with carry on assembly level ++ */ ++ ++ *ret = a + carry; ++ if (*ret < a) ++ carry1 = 1; ++ else ++ carry1 = 0; ++ ++ t = *ret; ++ *ret = t + b; ++ if (*ret < t) ++ carry2 = 1; ++ else ++ carry2 = 0; ++ ++ return carry1 + carry2; ++} ++ ++/* ++ * add two numbers of the same size, return overflow ++ * ++ * add a to b, place result in ret; all arrays need to be n limbs long ++ * return overflow from addition (0 or 1) ++ */ ++static ossl_inline limb_t add(limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t c = 0; ++ ossl_ssize_t i; ++ ++ for(i = n - 1; i > -1; i--) ++ c = _add_limb(&ret[i], a[i], b[i], c); ++ ++ return c; ++} ++ ++/* ++ * return number of limbs necessary for temporary values ++ * when multiplying numbers n limbs large ++ */ ++static ossl_inline size_t mul_limb_numb(size_t n) ++{ ++ return 2 * n * 2; ++} ++ ++/* ++ * multiply two numbers of the same size ++ * ++ * multiply a by b, place result in ret; a and b need to be n limbs long ++ * ret needs to be 2*n limbs long, tmp needs to be mul_limb_numb(n) limbs ++ * long ++ */ ++static void limb_mul(limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp) ++{ ++ limb_t *r_odd, *r_even; ++ size_t i, j, k; ++ ++ r_odd = tmp; ++ r_even = &tmp[2 * n]; ++ ++ memset(ret, 0, 2 * n * sizeof(limb_t)); ++ ++ for (i = 0; i < n; i++) { ++ for (k = 0; k < i + n + 1; k++) { ++ r_even[k] = 0; ++ r_odd[k] = 0; ++ } ++ for (j = 0; j < n; j++) { ++ /* ++ * place results from even and odd limbs in separate arrays so that ++ * we don't have to calculate overflow every time we get individual ++ * limb multiplication result ++ */ ++ if (j % 2 == 0) ++ _mul_limb(&r_even[i + j], &r_even[i + j + 1], a[i], b[j]); ++ else ++ _mul_limb(&r_odd[i + j], &r_odd[i + j + 1], a[i], b[j]); ++ } ++ /* ++ * skip the least significant limbs when adding multiples of ++ * more significant limbs (they're zero anyway) ++ */ ++ add(ret, ret, r_even, n + i + 1); ++ add(ret, ret, r_odd, n + i + 1); ++ } ++} ++ ++/* modifies the value in place by performing a right shift by one bit */ ++static ossl_inline void rshift1(limb_t *val, size_t n) ++{ ++ limb_t shift_in = 0, shift_out = 0; ++ size_t i; ++ ++ for (i = 0; i < n; i++) { ++ shift_out = val[i] & 1; ++ val[i] = shift_in << (LIMB_BIT_SIZE - 1) | (val[i] >> 1); ++ shift_in = shift_out; ++ } ++} ++ ++/* extend the LSB of flag to all bits of limb */ ++static ossl_inline limb_t mk_mask(limb_t flag) ++{ ++ flag |= flag << 1; ++ flag |= flag << 2; ++ flag |= flag << 4; ++ flag |= flag << 8; ++ flag |= flag << 16; ++#if (LIMB_BYTE_SIZE == 8) ++ flag |= flag << 32; ++#endif ++ return flag; ++} ++ ++/* ++ * copy from either a or b to ret based on flag ++ * when flag == 0, then copies from b ++ * when flag == 1, then copies from a ++ */ ++static ossl_inline void cselect(limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ /* ++ * would be more efficient with non volatile mask, but then gcc ++ * generates code with jumps ++ */ ++ volatile limb_t mask; ++ size_t i; ++ ++ mask = mk_mask(flag); ++ for (i = 0; i < n; i++) { ++#if (LIMB_BYTE_SIZE == 8) ++ ret[i] = constant_time_select_64(mask, a[i], b[i]); ++#else ++ ret[i] = constant_time_select_32(mask, a[i], b[i]); ++#endif ++ } ++} ++ ++static limb_t _sub_limb(limb_t *ret, limb_t a, limb_t b, limb_t borrow) ++{ ++ limb_t borrow1, borrow2, t; ++ /* ++ * while it doesn't look constant-time, this is idiomatic code ++ * to tell compilers to use the carry bit from subtraction ++ */ ++ ++ *ret = a - borrow; ++ if (*ret > a) ++ borrow1 = 1; ++ else ++ borrow1 = 0; ++ ++ t = *ret; ++ *ret = t - b; ++ if (*ret > t) ++ borrow2 = 1; ++ else ++ borrow2 = 0; ++ ++ return borrow1 + borrow2; ++} ++ ++/* ++ * place the result of a - b into ret, return the borrow bit. ++ * All arrays need to be n limbs long ++ */ ++static limb_t sub(limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t borrow = 0; ++ ossl_ssize_t i; ++ ++ for (i = n - 1; i > -1; i--) ++ borrow = _sub_limb(&ret[i], a[i], b[i], borrow); ++ ++ return borrow; ++} ++ ++/* return the number of limbs necessary to allocate for the mod() tmp operand */ ++static ossl_inline size_t mod_limb_numb(size_t anum, size_t modnum) ++{ ++ return (anum + modnum) * 3; ++} ++ ++/* ++ * calculate a % mod, place the result in ret ++ * size of a is defined by anum, size of ret and mod is modnum, ++ * size of tmp is returned by mod_limb_numb() ++ */ ++static void mod(limb_t *ret, limb_t *a, size_t anum, limb_t *mod, ++ size_t modnum, limb_t *tmp) ++{ ++ limb_t *atmp, *modtmp, *rettmp; ++ limb_t res; ++ size_t i; ++ ++ memset(tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE); ++ ++ atmp = tmp; ++ modtmp = &tmp[anum + modnum]; ++ rettmp = &tmp[(anum + modnum) * 2]; ++ ++ for (i = modnum; i 0; i--, rp--) { ++ v = _mul_add_limb(rp, mod, modnum, rp[modnum - 1] * ni0, tmp2); ++ v = v + carry + rp[-1]; ++ carry |= (v != rp[-1]); ++ carry &= (v <= rp[-1]); ++ rp[-1] = v; ++ } ++ ++ /* perform the final reduction by mod... */ ++ carry -= sub(ret, rp, mod, modnum); ++ ++ /* ...conditionally */ ++ cselect(carry, ret, rp, ret, modnum); ++} ++ ++/* allocated buffer should be freed afterwards */ ++static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs) ++{ ++ int i; ++ int real_limbs = (BN_num_bytes(bn) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE; ++ limb_t *ptr = buf + (limbs - real_limbs); ++ ++ for (i = 0; i < real_limbs; i++) ++ ptr[i] = bn->d[real_limbs - i - 1]; ++} ++ ++#if LIMB_BYTE_SIZE == 8 ++static ossl_inline uint64_t be64(uint64_t host) ++{ ++ const union { ++ long one; ++ char little; ++ } is_endian = { 1 }; ++ ++ if (is_endian.little) { ++ uint64_t big = 0; ++ ++ big |= (host & 0xff00000000000000) >> 56; ++ big |= (host & 0x00ff000000000000) >> 40; ++ big |= (host & 0x0000ff0000000000) >> 24; ++ big |= (host & 0x000000ff00000000) >> 8; ++ big |= (host & 0x00000000ff000000) << 8; ++ big |= (host & 0x0000000000ff0000) << 24; ++ big |= (host & 0x000000000000ff00) << 40; ++ big |= (host & 0x00000000000000ff) << 56; ++ return big; ++ } else { ++ return host; ++ } ++} ++ ++#else ++/* Not all platforms have htobe32(). */ ++static ossl_inline uint32_t be32(uint32_t host) ++{ ++ const union { ++ long one; ++ char little; ++ } is_endian = { 1 }; ++ ++ if (is_endian.little) { ++ uint32_t big = 0; ++ ++ big |= (host & 0xff000000) >> 24; ++ big |= (host & 0x00ff0000) >> 8; ++ big |= (host & 0x0000ff00) << 8; ++ big |= (host & 0x000000ff) << 24; ++ return big; ++ } else { ++ return host; ++ } ++} ++#endif ++ ++/* ++ * We assume that intermediate, possible_arg2, blinding, and ctx are used ++ * similar to BN_BLINDING_invert_ex() arguments. ++ * to_mod is RSA modulus. ++ * buf and num is the serialization buffer and its length. ++ * ++ * Here we use classic/Montgomery multiplication and modulo. After the calculation finished ++ * we serialize the new structure instead of BIGNUMs taking endianness into account. ++ */ ++int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate, ++ const BN_BLINDING *blinding, ++ const BIGNUM *possible_arg2, ++ const BIGNUM *to_mod, BN_CTX *ctx, ++ unsigned char *buf, int num) ++{ ++ limb_t *l_im = NULL, *l_mul = NULL, *l_mod = NULL; ++ limb_t *l_ret = NULL, *l_tmp = NULL, l_buf; ++ size_t l_im_count = 0, l_mul_count = 0, l_size = 0, l_mod_count = 0; ++ size_t l_tmp_count = 0; ++ int ret = 0; ++ size_t i; ++ unsigned char *tmp; ++ const BIGNUM *arg1 = intermediate; ++ const BIGNUM *arg2 = (possible_arg2 == NULL) ? blinding->Ai : possible_arg2; ++ ++ l_im_count = (BN_num_bytes(arg1) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE; ++ l_mul_count = (BN_num_bytes(arg2) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE; ++ l_mod_count = (BN_num_bytes(to_mod) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE; ++ ++ l_size = l_im_count > l_mul_count ? l_im_count : l_mul_count; ++ l_im = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE); ++ l_mul = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE); ++ l_mod = OPENSSL_zalloc(l_mod_count * LIMB_BYTE_SIZE); ++ ++ if ((l_im == NULL) || (l_mul == NULL) || (l_mod == NULL)) ++ goto err; ++ ++ BN_to_limb(arg1, l_im, l_size); ++ BN_to_limb(arg2, l_mul, l_size); ++ BN_to_limb(to_mod, l_mod, l_mod_count); ++ ++ l_ret = OPENSSL_malloc(2 * l_size * LIMB_BYTE_SIZE); ++ ++ if (blinding->m_ctx != NULL) { ++ l_tmp_count = mul_limb_numb(l_size) > mod_montgomery_limb_numb(l_mod_count) ? ++ mul_limb_numb(l_size) : mod_montgomery_limb_numb(l_mod_count); ++ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE); ++ } else { ++ l_tmp_count = mul_limb_numb(l_size) > mod_limb_numb(2 * l_size, l_mod_count) ? ++ mul_limb_numb(l_size) : mod_limb_numb(2 * l_size, l_mod_count); ++ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE); ++ } ++ ++ if ((l_ret == NULL) || (l_tmp == NULL)) ++ goto err; ++ ++ if (blinding->m_ctx != NULL) { ++ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp); ++ mod_montgomery(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, ++ blinding->m_ctx->n0[0], l_tmp); ++ } else { ++ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp); ++ mod(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, l_tmp); ++ } ++ ++ /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */ ++ if (num < BN_num_bytes(to_mod)) { ++ BNerr(BN_F_OSSL_BN_RSA_DO_UNBLIND, ERR_R_PASSED_INVALID_ARGUMENT); ++ goto err; ++ } ++ ++ memset(buf, 0, num); ++ tmp = buf + num - BN_num_bytes(to_mod); ++ for (i = 0; i < l_mod_count; i++) { ++#if LIMB_BYTE_SIZE == 8 ++ l_buf = be64(l_ret[i]); ++#else ++ l_buf = be32(l_ret[i]); ++#endif ++ if (i == 0) { ++ int delta = LIMB_BYTE_SIZE - ((l_mod_count * LIMB_BYTE_SIZE) - num); ++ ++ memcpy(tmp, ((char *)&l_buf) + LIMB_BYTE_SIZE - delta, delta); ++ tmp += delta; ++ } else { ++ memcpy(tmp, &l_buf, LIMB_BYTE_SIZE); ++ tmp += LIMB_BYTE_SIZE; ++ } ++ } ++ ret = num; ++ ++ err: ++ OPENSSL_free(l_im); ++ OPENSSL_free(l_mul); ++ OPENSSL_free(l_mod); ++ OPENSSL_free(l_tmp); ++ OPENSSL_free(l_ret); ++ ++ return ret; ++} +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +index 35512f9..03d1640 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +@@ -1,4 +1,4 @@ +-# Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. ++# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. + # + # Licensed under the OpenSSL license (the "License"). You may not use + # this file except in compliance with the License. You can obtain a copy +@@ -231,6 +231,7 @@ BN_F_BN_RSHIFT:146:BN_rshift + BN_F_BN_SET_WORDS:144:bn_set_words + BN_F_BN_STACK_PUSH:148:BN_STACK_push + BN_F_BN_USUB:115:BN_usub ++BN_F_OSSL_BN_RSA_DO_UNBLIND:151:ossl_bn_rsa_do_unblind + BUF_F_BUF_MEM_GROW:100:BUF_MEM_grow + BUF_F_BUF_MEM_GROW_CLEAN:105:BUF_MEM_grow_clean + BUF_F_BUF_MEM_NEW:101:BUF_MEM_new +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c +index b52a66f..6c3c0cf 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c +@@ -465,11 +465,20 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, + BN_free(d); + } + +- if (blinding) +- if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) ++ if (blinding) { ++ /* ++ * ossl_bn_rsa_do_unblind() combines blinding inversion and ++ * 0-padded BN BE serialization ++ */ ++ j = ossl_bn_rsa_do_unblind(ret, blinding, unblind, rsa->n, ctx, ++ buf, num); ++ if (j == 0) + goto err; +- +- j = BN_bn2binpad(ret, buf, num); ++ } else { ++ j = BN_bn2binpad(ret, buf, num); ++ if (j < 0) ++ goto err; ++ } + + switch (padding) { + case RSA_PKCS1_PADDING: +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h +index 60afda1..b5f36fb 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h +@@ -86,5 +86,10 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n); + int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n); + int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + const BIGNUM *d, BN_CTX *ctx); ++int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate, ++ const BN_BLINDING *blinding, ++ const BIGNUM *possible_arg2, ++ const BIGNUM *to_mod, BN_CTX *ctx, ++ unsigned char *buf, int num); + + #endif +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/bnerr.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/bnerr.h +index 9f3c7cf..a0752ce 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/bnerr.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/bnerr.h +@@ -72,6 +72,7 @@ int ERR_load_BN_strings(void); + # define BN_F_BN_SET_WORDS 144 + # define BN_F_BN_STACK_PUSH 148 + # define BN_F_BN_USUB 115 ++# define BN_F_OSSL_BN_RSA_DO_UNBLIND 151 + + /* + * BN reason codes. +-- +2.33.0 + diff --git a/0030-BaseTools-Work-around-array.array.tostring-removal-i.patch b/0030-BaseTools-Work-around-array.array.tostring-removal-i.patch deleted file mode 100644 index aaff9cf24e72b8a5175853ded8aaf8831f9fdf1f..0000000000000000000000000000000000000000 --- a/0030-BaseTools-Work-around-array.array.tostring-removal-i.patch +++ /dev/null @@ -1,51 +0,0 @@ -From d935684f89d972f3b9ff8fabe18fffefe75b2ed6 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Wed, 12 Aug 2020 01:28:18 +0800 -Subject: [PATCH] BaseTools: Work around array.array.tostring() removal in - python 3.9 - -In python3, array.array.tostring() was a compat alias for tobytes(). -tostring() was removed in python 3.9. - -Convert this to use tolist() which should be valid for all python -versions. - -This fixes this build error on python3.9: - -(Python 3.9.0b5 on linux) Traceback (most recent call last): - File "/root/edk2/edk2-edk2-stable202002/BaseTools/BinWrappers/PosixLike/../../Source/Python/Trim/Trim.py", line 593, in Main - GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile) - File "/root/edk2/edk2-edk2-stable202002/BaseTools/BinWrappers/PosixLike/../../Source/Python/Trim/Trim.py", line 449, in GenerateVfrBinSec - VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList) - File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 88, in GetVariableOffset - return _parseForGCC(lines, efifilepath, varnames) - File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 151, in _parseForGCC - efisecs = PeImageClass(efifilepath).SectionHeaderList - File "/root/edk2/edk2-edk2-stable202002/BaseTools/Source/Python/Common/Misc.py", line 1638, in __init__ - if ByteArray.tostring() != b'PE\0\0': -AttributeError: 'array.array' object has no attribute 'tostring' - -Signed-off-by: Cole Robinson -Reviewed-by: Yuwei Chen -Reviewed-by: Bob Feng -Signed-off-by: Jinhua Cao ---- - BaseTools/Source/Python/Common/Misc.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py -index da5fb380f0..751b2c24f0 100755 ---- a/BaseTools/Source/Python/Common/Misc.py -+++ b/BaseTools/Source/Python/Common/Misc.py -@@ -1635,7 +1635,7 @@ class PeImageClass(): - ByteArray = array.array('B') - ByteArray.fromfile(PeObject, 4) - # PE signature should be 'PE\0\0' -- if ByteArray.tostring() != b'PE\0\0': -+ if ByteArray.tolist() != [ord('P'), ord('E'), 0, 0]: - self.ErrorInfo = self.FileName + ' has no valid PE signature PE00' - return - --- -2.27.0 - diff --git a/0030-brotli-Fix-VLA-parameter-warning-893.patch b/0030-brotli-Fix-VLA-parameter-warning-893.patch new file mode 100644 index 0000000000000000000000000000000000000000..9f6974efeb9fe81234db1bea1dac0ca36a95e85b --- /dev/null +++ b/0030-brotli-Fix-VLA-parameter-warning-893.patch @@ -0,0 +1,89 @@ +From 0a3944c8c99b8d10cc4325f721b7c273d2b41f7b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Adri=C3=A1n=20Herrera=20Arcila?= +Date: Wed, 23 Jun 2021 08:53:59 +0100 +Subject: [PATCH] Fix VLA parameter warning (#893) + +Make VLA buffer types consistent in declarations and definitions. +Resolves build crash when using -Werror due to "vla-parameter" warning. + +Signed-off-by: Adrian Herrera + +reference: https://github.com/google/brotli/pull/893 +Signed-off-by: Jiabo Feng +--- + BaseTools/Source/C/BrotliCompress/brotli/c/dec/decode.c | 6 ++++-- + BaseTools/Source/C/BrotliCompress/brotli/c/enc/encode.c | 5 +++-- + .../Library/BrotliCustomDecompressLib/brotli/c/dec/decode.c | 6 ++++-- + .../Library/BrotliCustomDecompressLib/brotli/c/enc/encode.c | 5 +++-- + 4 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/dec/decode.c b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/dec/decode.c +index ae5a3d3..7eee968 100644 +--- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/dec/decode.c ++++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/dec/decode.c +@@ -2030,8 +2030,10 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands( + } + + BrotliDecoderResult BrotliDecoderDecompress( +- size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size, +- uint8_t* decoded_buffer) { ++ size_t encoded_size, ++ const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)], ++ size_t* decoded_size, ++ uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]) { + BrotliDecoderState s; + BrotliDecoderResult result; + size_t total_out = 0; +diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/enc/encode.c b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/enc/encode.c +index 8d90937..0c49c64 100644 +--- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/enc/encode.c ++++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli/c/enc/encode.c +@@ -1470,8 +1470,9 @@ static size_t MakeUncompressedStream( + + BROTLI_BOOL BrotliEncoderCompress( + int quality, int lgwin, BrotliEncoderMode mode, size_t input_size, +- const uint8_t* input_buffer, size_t* encoded_size, +- uint8_t* encoded_buffer) { ++ const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)], ++ size_t* encoded_size, ++ uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]) { + BrotliEncoderState* s; + size_t out_size = *encoded_size; + const uint8_t* input_start = input_buffer; + +diff --git a/BaseTools/Source/C/BrotliCompress/brotli/c/dec/decode.c b/BaseTools/Source/C/BrotliCompress/brotli/c/dec/decode.c +index ae5a3d3..7eee968 100644 +--- a/BaseTools/Source/C/BrotliCompress/brotli/c/dec/decode.c ++++ b/BaseTools/Source/C/BrotliCompress/brotli/c/dec/decode.c +@@ -2030,8 +2030,10 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands( + } + + BrotliDecoderResult BrotliDecoderDecompress( +- size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size, +- uint8_t* decoded_buffer) { ++ size_t encoded_size, ++ const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)], ++ size_t* decoded_size, ++ uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]) { + BrotliDecoderState s; + BrotliDecoderResult result; + size_t total_out = 0; +diff --git a/BaseTools/Source/C/BrotliCompress/brotli/c/enc/encode.c b/BaseTools/Source/C/BrotliCompress/brotli/c/enc/encode.c +index 8d90937..0c49c64 100644 +--- a/BaseTools/Source/C/BrotliCompress/brotli/c/enc/encode.c ++++ b/BaseTools/Source/C/BrotliCompress/brotli/c/enc/encode.c +@@ -1470,8 +1470,9 @@ static size_t MakeUncompressedStream( + + BROTLI_BOOL BrotliEncoderCompress( + int quality, int lgwin, BrotliEncoderMode mode, size_t input_size, +- const uint8_t* input_buffer, size_t* encoded_size, +- uint8_t* encoded_buffer) { ++ const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)], ++ size_t* encoded_size, ++ uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]) { + BrotliEncoderState* s; + size_t out_size = *encoded_size; + const uint8_t* input_start = input_buffer; +-- +2.41.0 + diff --git a/0031-MdeModulePkg-UsbBusDxe-fix-NOOPT-build-error.patch b/0031-MdeModulePkg-UsbBusDxe-fix-NOOPT-build-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..bde72b36e08ff9e3d261be6a2ac1074f65088f63 --- /dev/null +++ b/0031-MdeModulePkg-UsbBusDxe-fix-NOOPT-build-error.patch @@ -0,0 +1,48 @@ +From ae8272ef787d80950803c521a13a308651bdc62e Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 20 Dec 2021 22:32:38 +0800 +Subject: [PATCH] MdeModulePkg/UsbBusDxe: fix NOOPT build error + +gcc-11 (fedora 35): + +/home/kraxel/projects/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c: In function ?UsbIoBulkTransfer?: +/home/kraxel/projects/edk2/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c:277:12: error: ?UsbHcBulkTransfer? accessing 80 bytes in a region of size 8 [-Werror=stringop-overflow=] + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Hao A Wu + +reference: https://github.com/tianocore/edk2/pull/2347 +Signed-off-by: Jiabo Feng +--- + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c | 2 +- + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c +index 12d08c0b74..740e7babb0 100644 +--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c ++++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c +@@ -285,7 +285,7 @@ UsbHcBulkTransfer ( + IN UINT8 DevSpeed, + IN UINTN MaxPacket, + IN UINT8 BufferNum, +- IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], ++ IN OUT VOID *Data[], + IN OUT UINTN *DataLength, + IN OUT UINT8 *DataToggle, + IN UINTN TimeOut, +diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h +index 04cf36d3c8..d93370a6c2 100644 +--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h ++++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h +@@ -149,7 +149,7 @@ UsbHcBulkTransfer ( + IN UINT8 DevSpeed, + IN UINTN MaxPacket, + IN UINT8 BufferNum, +- IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], ++ IN OUT VOID *Data[], + IN OUT UINTN *DataLength, + IN OUT UINT8 *DataToggle, + IN UINTN TimeOut, +-- +2.41.0 diff --git a/0032-BaseTools-GenEfs-GenSec-fix-gcc12-warning.patch b/0032-BaseTools-GenEfs-GenSec-fix-gcc12-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..59197006c1b85166acd7401bcaf896bdb61d9161 --- /dev/null +++ b/0032-BaseTools-GenEfs-GenSec-fix-gcc12-warning.patch @@ -0,0 +1,50 @@ +From 7b005f344e533cd913c3ca05b266f9872df886d1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 24 Mar 2022 20:04:34 +0800 +Subject: [PATCH 1/3] BaseTools: fix gcc12 warning + +GenFfs.c:545:5: error: pointer ?InFileHandle? used after ?fclose? [-Werror=use-after-free] + 545 | Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GenFfs.c:544:5: note: call to ?fclose? here + 544 | fclose (InFileHandle); + | ^~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Bob Feng + +reference: https://github.com/tianocore/edk2/pull/2694 +Signed-off-by: Jiabo Feng +--- + BaseTools/Source/C/GenFfs/GenFfs.c | 2 +- + BaseTools/Source/C/GenSec/GenSec.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c +index 949025c333..d78d62ab36 100644 +--- a/BaseTools/Source/C/GenFfs/GenFfs.c ++++ b/BaseTools/Source/C/GenFfs/GenFfs.c +@@ -542,7 +542,7 @@ GetAlignmentFromFile(char *InFile, UINT32 *Alignment) + PeFileBuffer = (UINT8 *) malloc (PeFileSize); + if (PeFileBuffer == NULL) { + fclose (InFileHandle); +- Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle); ++ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); + return EFI_OUT_OF_RESOURCES; + } + fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); +diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c +index d54a4f9e0a..b1d05367ec 100644 +--- a/BaseTools/Source/C/GenSec/GenSec.c ++++ b/BaseTools/Source/C/GenSec/GenSec.c +@@ -1062,7 +1062,7 @@ GetAlignmentFromFile(char *InFile, UINT32 *Alignment) + PeFileBuffer = (UINT8 *) malloc (PeFileSize); + if (PeFileBuffer == NULL) { + fclose (InFileHandle); +- Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle); ++ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); + return EFI_OUT_OF_RESOURCES; + } + fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); +-- +2.41.0 \ No newline at end of file diff --git a/0033-BaseTools-LzmaCompress-fix-gcc12-warning.patch b/0033-BaseTools-LzmaCompress-fix-gcc12-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..2ceedd5f6686319219a31455b9eac4a3d3282ac8 --- /dev/null +++ b/0033-BaseTools-LzmaCompress-fix-gcc12-warning.patch @@ -0,0 +1,53 @@ +From 85021f8cf22d1bd4114803c6c610dea5ef0059f1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 24 Mar 2022 20:04:35 +0800 +Subject: [PATCH 2/3] BaseTools: fix gcc12 warning + +Sdk/C/LzmaEnc.c: In function ?LzmaEnc_CodeOneMemBlock?: +Sdk/C/LzmaEnc.c:2828:19: error: storing the address of local variable ?outStream? in ?*p.rc.outStream? [-Werror=dangling-pointer=] + 2828 | p->rc.outStream = &outStream.vt; + | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~ +Sdk/C/LzmaEnc.c:2811:28: note: ?outStream? declared here + 2811 | CLzmaEnc_SeqOutStreamBuf outStream; + | ^~~~~~~~~ +Sdk/C/LzmaEnc.c:2811:28: note: ?pp? declared here +Sdk/C/LzmaEnc.c:2828:19: error: storing the address of local variable ?outStream? in ?*(CLzmaEnc *)pp.rc.outStream? [-Werror=dangling-pointer=] + 2828 | p->rc.outStream = &outStream.vt; + | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~ +Sdk/C/LzmaEnc.c:2811:28: note: ?outStream? declared here + 2811 | CLzmaEnc_SeqOutStreamBuf outStream; + | ^~~~~~~~~ +Sdk/C/LzmaEnc.c:2811:28: note: ?pp? declared here +cc1: all warnings being treated as errors + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Bob Feng + +reference: https://github.com/tianocore/edk2/pull/2694 +Signed-off-by: Jiabo Feng +--- + BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c +index 4e9b499f8d..4b9f5fa692 100644 +--- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c ++++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c +@@ -2638,12 +2638,13 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); +- p->rc.outStream = &outStream.vt; + + if (desiredPackSize == 0) + return SZ_ERROR_OUTPUT_EOF; + ++ p->rc.outStream = &outStream.vt; + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize); ++ p->rc.outStream = NULL; + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; +-- +2.41.0.windows.1 + diff --git a/0034-Basetools-turn-off-gcc12-warning.patch b/0034-Basetools-turn-off-gcc12-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..f17e7b01abf296c946f62f804a264255f34bb986 --- /dev/null +++ b/0034-Basetools-turn-off-gcc12-warning.patch @@ -0,0 +1,43 @@ +From 22130dcd98b4d4b76ac8d922adb4a2dbc86fa52c Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 24 Mar 2022 20:04:36 +0800 +Subject: [PATCH 3/3] Basetools: turn off gcc12 warning + +In function ?SetDevicePathEndNode?, + inlined from ?FileDevicePath? at DevicePathUtilities.c:857:5: +DevicePathUtilities.c:321:3: error: writing 4 bytes into a region of size 1 [-Werror=stringop-overflow=] + 321 | memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from UefiDevicePathLib.h:22, + from DevicePathUtilities.c:16: +../Include/Protocol/DevicePath.h: In function ?FileDevicePath?: +../Include/Protocol/DevicePath.h:51:9: note: destination object ?Type? of size 1 + 51 | UINT8 Type; ///< 0x01 Hardware Device Path. + | ^~~~ + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Bob Feng + +reference: https://github.com/tianocore/edk2/pull/2694 +Signed-off-by: Jiabo Feng +--- + BaseTools/Source/C/DevicePath/GNUmakefile | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile +index 7ca08af966..b05d2bddfa 100644 +--- a/BaseTools/Source/C/DevicePath/GNUmakefile ++++ b/BaseTools/Source/C/DevicePath/GNUmakefile +@@ -13,6 +13,9 @@ OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtili + + include $(MAKEROOT)/Makefiles/app.makefile + ++# gcc 12 trips over device path handling ++BUILD_CFLAGS += -Wno-error=stringop-overflow ++ + LIBS = -lCommon + ifeq ($(CYGWIN), CYGWIN) + LIBS += -L/lib/e2fsprogs -luuid +-- +2.41.0 + diff --git a/0035-x509-excessive-resource-use-verifying-policy-constra.patch b/0035-x509-excessive-resource-use-verifying-policy-constra.patch new file mode 100644 index 0000000000000000000000000000000000000000..10f71980de59da842c93e4281595351fd03e2aff --- /dev/null +++ b/0035-x509-excessive-resource-use-verifying-policy-constra.patch @@ -0,0 +1,225 @@ +From acb340dfc303ce31bd2577e727f5e56544118054 Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 8 Mar 2023 15:28:20 +1100 +Subject: [PATCH 01/11] x509: excessive resource use verifying policy + constraints + +A security vulnerability has been identified in all supported versions +of OpenSSL related to the verification of X.509 certificate chains +that include policy constraints. Attackers may be able to exploit this +vulnerability by creating a malicious certificate chain that triggers +exponential use of computational resources, leading to a denial-of-service +(DoS) attack on affected systems. + +Fixes CVE-2023-0464 + +Reviewed-by: Tomas Mraz +Reviewed-by: Shane Lontis + +reference: https://github.com/openssl/openssl/pull/20569 +Signed-off-by: yexiao +--- + .../openssl/crypto/x509v3/pcy_local.h | 8 +++- + .../openssl/crypto/x509v3/pcy_node.c | 12 ++++-- + .../openssl/crypto/x509v3/pcy_tree.c | 37 ++++++++++++++----- + 3 files changed, 43 insertions(+), 14 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h +index 5daf78de..344aa067 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h +@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st { + }; + + struct X509_POLICY_TREE_st { ++ /* The number of nodes in the tree */ ++ size_t node_count; ++ /* The maximum number of nodes in the tree */ ++ size_t node_maximum; ++ + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; +@@ -159,7 +164,8 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree); ++ X509_POLICY_TREE *tree, ++ int extra_data); + void policy_node_free(X509_POLICY_NODE *node); + int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c +index e2d7b153..d574fb9d 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c +@@ -59,10 +59,15 @@ X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree) ++ X509_POLICY_TREE *tree, ++ int extra_data) + { + X509_POLICY_NODE *node; + ++ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */ ++ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum) ++ return NULL; ++ + node = OPENSSL_zalloc(sizeof(*node)); + if (node == NULL) { + X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE); +@@ -70,7 +75,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + } + node->data = data; + node->parent = parent; +- if (level) { ++ if (level != NULL) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; +@@ -90,7 +95,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + } + } + +- if (tree) { ++ if (extra_data) { + if (tree->extra_data == NULL) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (tree->extra_data == NULL){ +@@ -103,6 +108,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + } + } + ++ tree->node_count++; + if (parent) + parent->nchild++; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c +index 6e8322cb..6c7fd354 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c +@@ -13,6 +13,18 @@ + + #include "pcy_local.h" + ++/* ++ * If the maximum number of nodes in the policy tree isn't defined, set it to ++ * a generous default of 1000 nodes. ++ * ++ * Defining this to be zero means unlimited policy tree growth which opens the ++ * door on CVE-2023-0464. ++ */ ++ ++#ifndef OPENSSL_POLICY_TREE_NODES_MAX ++# define OPENSSL_POLICY_TREE_NODES_MAX 1000 ++#endif ++ + /* + * Enable this to print out the complete policy tree at various point during + * evaluation. +@@ -168,6 +180,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + return X509_PCY_TREE_INTERNAL; + } + ++ /* Limit the growth of the tree to mitigate CVE-2023-0464 */ ++ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX; ++ + /* + * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3. + * +@@ -184,7 +199,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + level = tree->levels; + if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL) + goto bad_tree; +- if (level_add_node(level, data, NULL, tree) == NULL) { ++ if (level_add_node(level, data, NULL, tree, 1) == NULL) { + policy_data_free(data); + goto bad_tree; + } +@@ -243,7 +258,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + * Return value: 1 on success, 0 otherwise + */ + static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, +- X509_POLICY_DATA *data) ++ X509_POLICY_DATA *data, ++ X509_POLICY_TREE *tree) + { + X509_POLICY_LEVEL *last = curr - 1; + int i, matched = 0; +@@ -253,13 +269,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (policy_node_match(last, node, data->valid_policy)) { +- if (level_add_node(curr, data, node, NULL) == NULL) ++ if (level_add_node(curr, data, node, tree, 0) == NULL) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { +- if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL) ++ if (level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL) + return 0; + } + return 1; +@@ -272,7 +288,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + * Return value: 1 on success, 0 otherwise. + */ + static int tree_link_nodes(X509_POLICY_LEVEL *curr, +- const X509_POLICY_CACHE *cache) ++ const X509_POLICY_CACHE *cache, ++ X509_POLICY_TREE *tree) + { + int i; + +@@ -280,7 +297,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr, + X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i); + + /* Look for matching nodes in previous level */ +- if (!tree_link_matching_nodes(curr, data)) ++ if (!tree_link_matching_nodes(curr, data, tree)) + return 0; + } + return 1; +@@ -311,7 +328,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; +- if (level_add_node(curr, data, node, tree) == NULL) { ++ if (level_add_node(curr, data, node, tree, 1) == NULL) { + policy_data_free(data); + return 0; + } +@@ -373,7 +390,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, + } + /* Finally add link to anyPolicy */ + if (last->anyPolicy && +- level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL) ++ level_add_node(curr, cache->anyPolicy, last->anyPolicy, tree, 0) == NULL) + return 0; + return 1; + } +@@ -555,7 +572,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, + extra->qualifier_set = anyPolicy->data->qualifier_set; + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; +- node = level_add_node(NULL, extra, anyPolicy->parent, tree); ++ node = level_add_node(NULL, extra, anyPolicy->parent, tree, 1); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); +@@ -582,7 +599,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree) + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = policy_cache_set(curr->cert); +- if (!tree_link_nodes(curr, cache)) ++ if (!tree_link_nodes(curr, cache, tree)) + return X509_PCY_TREE_INTERNAL; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) +-- +2.33.0 + diff --git a/0036-test-add-test-cases-for-the-policy-resource-overuse.patch b/0036-test-add-test-cases-for-the-policy-resource-overuse.patch new file mode 100644 index 0000000000000000000000000000000000000000..9840aaedda601f0f2a28cc347ed483fcd602b408 --- /dev/null +++ b/0036-test-add-test-cases-for-the-policy-resource-overuse.patch @@ -0,0 +1,628 @@ +From 29c7751baf59ee8e210102df5d4107b709161024 Mon Sep 17 00:00:00 2001 +From: Pauli +Date: Wed, 8 Mar 2023 14:39:25 +1100 +Subject: [PATCH 02/11] test: add test cases for the policy resource overuse + +These trees have pathological properties with respect to building. The small +tree stays within the imposed limit, the large tree doesn't. + +The large tree would consume over 150Gb of RAM to process. + +Reviewed-by: Tomas Mraz +Reviewed-by: Shane Lontis + +reference: https://github.com/openssl/openssl/pull/20569 +Signed-off-by: yexiao +--- + .../test/recipes/80-test_policy_tree.t | 41 ++ + .../80-test_policy_tree_data/large_leaf.pem | 11 + + .../large_policy_tree.pem | 434 ++++++++++++++++++ + .../80-test_policy_tree_data/small_leaf.pem | 11 + + .../small_policy_tree.pem | 70 +++ + 5 files changed, 567 insertions(+) + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree.t + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_leaf.pem + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_policy_tree.pem + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_leaf.pem + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_policy_tree.pem + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree.t b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree.t +new file mode 100644 +index 00000000..606ad05e +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree.t +@@ -0,0 +1,41 @@ ++#! /usr/bin/env perl ++# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++ ++use strict; ++use warnings; ++ ++use POSIX; ++use OpenSSL::Test qw/:DEFAULT srctop_file with data_file/; ++ ++use OpenSSL::Test::Utils; ++use OpenSSL::Glob; ++ ++setup("test_policy_tree"); ++ ++plan tests => 2; ++ ++# The small pathological tree is expected to work ++my $small_chain = srctop_file("test", "recipes", "80-test_policy_tree_data", ++ "small_policy_tree.pem"); ++my $small_leaf = srctop_file("test", "recipes", "80-test_policy_tree_data", ++ "small_leaf.pem"); ++ ++ok(run(app(["openssl", "verify", "-CAfile", $small_chain, ++ "-policy_check", $small_leaf])), ++ "test small policy tree"); ++ ++# The large pathological tree is expected to fail ++my $large_chain = srctop_file("test", "recipes", "80-test_policy_tree_data", ++ "large_policy_tree.pem"); ++my $large_leaf = srctop_file("test", "recipes", "80-test_policy_tree_data", ++ "large_leaf.pem"); ++ ++ok(!run(app(["openssl", "verify", "-CAfile", $large_chain, ++ "-policy_check", $large_leaf])), ++ "test large policy tree"); +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_leaf.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_leaf.pem +new file mode 100644 +index 00000000..39ed6a7f +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_leaf.pem +@@ -0,0 +1,11 @@ ++-----BEGIN CERTIFICATE----- ++MIIBmTCCAT+gAwIBAgIBADAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE ++AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEp6Qe ++jrN6A0ZjqaFbX/zO01aVYXH5kthBDTEO/fU4H0CdwqrfyMsFrObwssrTJcsmSFKP ++x1FYr8wT2wCACs19lqN4MHYwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t ++MCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMAoGCCqGSM49 ++BAMCA0gAMEUCIDGT8SVBkWJEZ2EzXm8M895NrNRmfc8uoheP0KKv+ndHAiEA2Onr ++20J+zTaR7vONY/1DleMm7fGY3UxTobSHSvOKbfY= ++-----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_policy_tree.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_policy_tree.pem +new file mode 100644 +index 00000000..5cd31c35 +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/large_policy_tree.pem +@@ -0,0 +1,434 @@ ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMjAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATgyLz1C0dD ++ib5J/QmoE4d+Nf5yvvlzjVZHWIu7iCMEqK67cnA1RtMp1d0xdiNQS6si3ExNPBF+ ++ELdkP0E6x26Jo4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSs+ml5upH1h25oUB0Ep4vd ++SUdZ/DAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAOME8j1/cMogNnuNCb0O ++RIOE9pLP4je78KJiP8CZm0iOAiALr8NI67orD/VpfRptkjCmOd7rTWMVOOJfBr6N ++VJFLjw== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICDzCCAbagAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMzAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASIdzU/FF3Y ++rTsTX04fRIN2yrZwxvOAfZ6DuEgKRxEimJx1nCyETuMmfDowm52mx/Cyk08xorp8 ++PhGEbacMd9kio4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSwok/8RfJbVGTzyF5jhWLc ++hO7pcDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDRwAwRAIgYVF7bXxUuOzAZF6SmeIJ ++s+iL15bLSQ2rW7QDc6QYp9MCIAup6YokIcr8JaGttHmLaKbASQLxYDGHhfFIVZuI ++BDvT ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ38Llxxj32 ++H3NN4Z1V8IuRKXLNhdU4z+NbT1rahusEyAHF+z9VTjim+HHfqFKV1QyNOJZ4rMA9 ++J/gODWsNCT4po4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS11YgFNKTx3a6kssIijnA9 ++DiOhoTAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAJXNZHMpvlnMfxhcG6EF ++Vw1pEXJ+iZnWT+Yu02a2zhamAiAiOKNhALBw/iKhQrwLo0cdx6UEfUKbaqTSGiax ++tHUylA== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBBDAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATo81HWQ/we ++egmoO/LMntQK1VQ9YzU627nblv/XWoOjEd/tBeE8+Un4jUnhZqNrP2TAzy48jEaT ++1DShCQNQGek7o4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS6/F38QgbZSHib0W1XtMfs ++4O5DTDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIgXMYCQWi5/6iQw+zqyEav ++CE7kOfTpm9GN4bZX5Eau5AACIQD0rDZwsjWf6hI2Hn8IlpwYVVC9bpxrAM/JmYuu ++79V/uw== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBBTAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNjAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARsPMjOkmzJ ++2jwT30mKUvAFYVgOlgcoXxYr61p54mbQMmmH49ABmJQMu5rjwjwYlYA3UzbEN9ki ++hMsJz/4JIrJGo4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQeflZRWUze+7jne9MkYYy5 ++iWFgJDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAIN6BjMnPlixl3i6Z1Xa ++pZQt52MOCHPm0XzXDn2XlC9+AiAn146u8rbppdEGMFr21vfFZaktwEb0cZkC9fBp ++S1uKwQ== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBBjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNzAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASVmpozZzxX ++f6rFinkqS0y8sfbOwcM0gNuR0x83mmZH5+a8W4ug5W80QiBaS3rHtwTsFHpCeQKq ++eJvfb/esgJu8o4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQPuF2sXR0vOHJynh57qefK +++h7RGDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIgDX0jHPq1alZoMbPDmbZp ++QYuM9UQagQ5KJgVU1B0Mh2ECIQCtdyfT2h5jZvz3lLKkQ9a6LddIuqsyNKDAxbpb ++PlBOOA== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBBzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgODAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASb+9fN9RLe ++SHGynsKXhLWGhIS/kZ6Yl97+h23xpjLaZUOzhn5VafXdmLrQ4BmqSMHqIKzcc8IB ++STV3NwO4NxPBo4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTBF9x+MrsyqoCaTQ2kB7Bn ++tpK2qDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAI37Di/5MrSj2clr+2pX ++iXzeDIvlaxzVetyH3ibUZZBSAiA41aPIssHi9evv2mZonEvXY8g+DKbh/3L2mSub ++/AyLoA== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICETCCAbagAwIBAgIBCDAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgOTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDgwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASrRS12/zEP ++RUNye9SLadN4xK+xfTwyXfxeC+jam+J98lOMcHz6abnLpk5tJ7wab4Pkygsbj1V2 ++STxeW+YH23dto4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQYpYFLhosbir7KoyYdehsQ ++6DdLfzAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSQAwRgIhAPTCN+zWFG2cFzJ+nlfg ++JMY4U2e3vqTQmFeBXYlBASb9AiEA0KvsyNwloF1YeeaYcP5iHoRGRo8UMD3QWKEE ++vWI14Uk= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbegAwIBAgIBCTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTAwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBYxFDASBgNV ++BAMTC1BvbGljeSBDQSA5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoR4udEgt ++usb9f946+Xznm7Q3OaW4DTZjO7wqX1I+27zDp0JrUbCZwtm0Cw+pYkG5kPpNcFTK ++7yG3YgqM1sT+6aOB8jCB7zAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYB ++BQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjgtOHvFBcUQ03AKUbvuJ ++IWO5lzUwJQYDVR0gBB4wHDAMBgpghkgBZQMCATABMAwGCmCGSAFlAwIBMAIwcQYD ++VR0hBGowaDAYBgpghkgBZQMCATABBgpghkgBZQMCATABMBgGCmCGSAFlAwIBMAEG ++CmCGSAFlAwIBMAIwGAYKYIZIAWUDAgEwAgYKYIZIAWUDAgEwATAYBgpghkgBZQMC ++ATACBgpghkgBZQMCATACMAoGCCqGSM49BAMCA0cAMEQCICIboTAzG1DvCY/0tA/o ++l18zrW9qKVnt4mxih5JQe4fOAiBOF2ZeUT2/ZtdFhZmg+zl/fGrQ1xEx09/S956k ++Ig4S9Q== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBCjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTEwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLxetqJp ++VR6apJytboxFCCooQ7jVcc7yoHhjlH8HsaJS3GrWpyMgiqOfyWt4KFMynKkgCU1K ++1QcU9aC5BfRQpyWjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD6etMtD6Qpa7TjVQBgV ++/4PhZP4DMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEA+5uiOjJoq5nU7lKN ++rZtBdYNqUKvHuYB+jiNEfWvxx2cCIFZEJCGw8fzqkAyGWkLe10w8PUzPM64nh757 ++pEtxCzZh ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBCzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTIwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPQuXEeo ++BrbyENdz9HqAoWMSQx1BErsUcQaneq3L0/VHHJBPKihb8s4nB/2yZaEarr8LFAvi ++ofx+4egydkP0mJ+jgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIoC4qL79Uy3+m26Y+ch +++sE6gCOMMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEAx/vMDhaH4EYTM2v9 ++GeM1xTP9pNRgak69JQLKLu1VM1YCIF1RYC8Fma5Bc0cZAYY+Gj7dEf9qHj1TODA5 ++C9es2CPY ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICETCCAbigAwIBAgIBDDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTMwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDlEv73o ++ej8Xvc3UodhSHkech80DbuBKdeldOTrRp6ZaVUP3vMgjNUJkh4WkvP3UVTe5SV4D ++zQXDIiwAEJu+zdmjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCAn0wYXyRdliJOBFvvJ ++eZoGTiyOMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNHADBEAiAo2PPmLBZpcT0bst/C ++SXvnl3gztIZu89O1MKsNwFcM9QIgIzqZx/o9MF/fP7zbLWErVcUQViOGiCRBLVh7 ++ppb7CoA= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBDTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTQwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABB8mgAoN ++rmFo937IBKXKuxHedUjOL7y3cpDYD1H3C4HRDBQDVOL31lC5kJUhS4HBLvJQwebR ++2kW35E3AnhbY/oKjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBGbO20Xp/q0fPChjLHL ++WuJwSNc1MCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEA3qGzdevdYfmiSBj9 ++t9oE8hfEP+APqGiStlOLKD6xVK0CIQDq9cVa2KXMEz7YwmMO3lxoQFDPEXftbRaC ++edFB7q/YXg== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBDjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTUwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxNDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHDiOMtx ++5sfJs/WDnw0xS5NYlkbgy2eOZHAmC/jhRp6cjShZrr2/S4IJsH8B2VMcYAHgum6a ++eMjqWFIMxIjN5xyjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOWtYUeAPk66m0o6Z7ax ++1RN42wmkMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEA+AcazVKKPfqkpcJw ++rkXWIyZrTe+1PNETQzaJCooGNGkCIQDdfHf1I78e+ogaDcjkDe0s3R9VhkvjCty6 ++uKKFtNGHMQ== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBDzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTYwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxNTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKCkdSYz +++zyHItG2rQSyCh018b4bu9Zrw8nzkCBgkT2IyycNtpabYkWhxcEL29ZFqBnB+l7N ++5fYmHl5CmflJPh+jgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNanrmjMEN3PndPGeucm ++mST9ucNWMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiAFt48yhTTv0rP29N8H ++yRhAQGfnV4t1b8JucixLSfe32QIhAOef6iiwLxbBOMUn5ZN/WAK5TERem6DLSzWN ++/PTXHAAt ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICETCCAbigAwIBAgIBEDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTcwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxNjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH5txyDp ++DfRsIyYPTAQ+fuxk08E3/tpChVWoog4XQvod61wcUO1/nhoTGNKZZOhN5uhKWJWb ++1futz+XxV2QxTCyjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHSlcxgh3gxgVag1JvAk ++zbHlgMbEMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNHADBEAiA9Ee47PnxqW0QmELB+ ++dd90Fz8wcQFZlNmkPW4Oq2xr/wIgGlxfutQq7l3TU5hyyO0Lh01AHn2DC5KPFPwE ++l8S9VeY= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBETAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTgwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAJvlQKB ++gJZ+Tysa6iwhllPXCeJrkan6WUm+oqOIY02/SpI5Mba1Kwg73Fsswx3Eywt8sxA2 ++4fiaqwg+xZoil06jgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFM/udZ1ib8qDfShdfdfX ++8gL6w7VMMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEA6kK7vAYF2TPXzywn +++SDLsiGbU6Sj8aTtsJZf9DmhKr4CIQCt4FfI7IWinqNlURXe4HSBPsekcQkOpwjK ++PuJRx3fuFw== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBEjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMTkwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxODBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEerejCw ++gAy7GecLVbQw6eL8k1cGWwLt+wl3sn8he8fA0I+KoFfcOCgtvOF59RMXnjZ1+7OC ++kz3mNDVSbKY6KO2jgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFM0OUOtOKTcTMRXGQwbw ++GOoLCOEYMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEAziPsm2dArB/3ILqm ++04mZl8/DX6dB4EmU+FPF2UpAeLwCIQCofc27tisg3L1mPNeiwZ26+rDe5SdixiUc ++S3KWOJ1cTg== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBEzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjAwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAxOTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPmB5spr ++C64/21ssufcbshGnQtAWbk2o2l+ej6pMMPIZhmNyvM450L3dFX12UBNcaERCABmr ++BEJL7IubGWE9CVOjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJCh/1mh0Hl2+LE0osUv ++OJCmV3IYMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEAtxMIkO4xCRSQCU6d ++0jt+Go4xj/R4bQFWbZrlS9+fYUECICuWAgT3evhoo34o04pU84UaYOvO5V0GJsTt ++hrS1v3hT ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBFDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjEwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHdvTDYo ++M/padIV3LdTnrzwMy1HSTeJ2aTUalkVV17uL2i3C51rWM2pl+qlRordq6W2GboMz ++/+78HhKMcCrMWKCjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAbZN0eSPw3MyvWIEix6 ++GnYRIiFkMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEAlaapLXHwGNkeEwc0 ++jsY2XhuR3RlVhD4T2k/QyJRQ0s0CIQD5E+e+5QTe5s+534Lwcxe2iFb3oFm+8g81 ++OBVtfmSMGg== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBFTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjIwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLTu8R5Y ++7Po4W05hWperfod6mXezwWgAVk2RW2EG2vy4NeZeML2EFhg2geNc6N5Goep9t7pn ++d+BtORRvR75oCDijgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNs0d2vXsRj3YYsBrWDo ++jrvcEA+eMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiBB603Ui+L60FcUWPrB ++Ch06hmgle2u0P07Go/XjTk00ZQIhALGhNArJFEY0gu+XUtyKEZt7BZ0/sh5dtLDP ++xkRgR6Wh ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBFjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjMwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPXpzC9/ ++KGblQyjhdcS0a8KBPAiS7c0n+V0i9JItbyze38Ncrctp0wIGHZLjRoB4DZYX1I8e ++K5C7KVeUPEE9eOGjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFISsw9orkX/cBVWcK5KA ++//kldz8HMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEA1gazdApLS91ql8Am ++4gb4Ku7Lgll4jV+BrLkbABE2cI0CIQCEH1GUJ6ARJB1GdcHrPyaLgeZ5jV2p63UW ++UV2QL6aETA== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBFzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjQwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKdweprb ++RZmuUk4og1Xa9Skb1vu7jsLozlm9CtDhKLbJ+cDX/VeKj/b8FuvakBO3L1QV5XU0 ++iFswsIVBVZ3m+TyjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPgcEbHfKHt0o/PCS0kD ++XWW9XkqMMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEA9XDj0w5qMS/tLlr9 ++Z2j8JtVR4M7pF/Wx2U43vmPFJEACIBAlAiUnCm1Nfj16t2cojrW+m2t1cU80ihmj ++Ld1U+dRD ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICETCCAbigAwIBAgIBGDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjUwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyNDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAq2PphK ++4oVsc+ml3zskBLiMa+dz64k+PrrfKIGSG2Ri5Du/orj0dO9639LeCkkMwWpXAfSx ++wxHHQX0I1KwsudGjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEqcfkso+ynKq2eFaJy8 ++mzNBdN2PMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNHADBEAiBZ71jDD33HFFqMkLAW ++gTAGMmzh9b/vZ8jAclPDKHRghQIgf2GBOF1eEF8Ino9F1n1ia5c3EryvXnvVoklw ++cjMIQ5g= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBGTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjYwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyNTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJRoDkj7 ++iDlIygt4YmMgw4pizu2sx4436MGtw5fFHhjy7T+pPMGjYFg3dixxUOu1NHORpdJq ++8Y7SN8p8Y0XsDpijgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOutMoKSOv5lEGZaqYZM ++zNFwpX3KMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEAks62lsAHmN6xkZsF ++6ocGONpH/XmHLpoO6RfMoRCnWkICIFNFD+W6pSSvdDB96sn8jnZ7W/Y0hyLzscBO ++WtkzqqJJ ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBGjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjcwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyNjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE3seRj5 ++LVNKi9sZk7qv5cBVUG8BLXXfDRUhCUzT10YAU1J0yd2wmLTbwPyYm65GaecvAHSR ++SExOzX6bC35nNt6jgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNx5XhDdoflDgPrW/HyU ++tCokuJ0AMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEApAQVb0KQedyAw1SJ ++J8At4uxxm2b8W13s6ENapxw+lwwCIQC7326NFPsDjbfBKhFDQhCIMkAkYq2wzRJ7 ++ubTwkdT19g== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBGzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjgwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC+FQF2E ++TrZ4YGNyxFxzpTQBjlu9QUrwgHzabAn47toqRkWUGAS68jBfSdR+j2c7/oehQHhO ++relHcbQilhZnh4ijgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIOlwsa4FjZWhzQYTAY3 ++c2TSYhsEMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEAwxNBi+8baAU76yng +++XvMpY62aqPO4bAe/uedaxBb2jMCIQDJHXqibgIAm1T4/YHimllVlLQudQL5OkbF ++Krj3uVHtBg== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBHDAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMjkwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyODBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBmhjGvk ++C3QfSVdY5zuHEY4Rf3eKVro6vcKymgdBPFjjDggZNktR3OMnayCabJB51g2VL7Fg ++MegdwzJWzPvQreyjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEvevGIfitXek0IStYIR ++5ne2SkJwMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiBzlv0TggDJWUWx0UHl ++cqxuMpoNdy+ifizQIlcjWcrzvgIhAJdQfkPaZdc4/j/HfGaVNN9InJuBWGrPYU6A ++iwsSB0jY ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEzCCAbigAwIBAgIBHTAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMzAwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAyOTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCrC5p+Z ++ywMukm1LRuXeJ5V1M6V+8A8PjqB3tgHVeEn973HOfia8lt2/7EoKaLKzP8A7D3eC ++aBJUmTgHauaolYOjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGG5D5h1FRA+aZMbSXfZ ++Mp8pjYUEMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNJADBGAiEAnI2IhyXtBCRiv+Xs ++EzsO497oVf1U8SJiVR8SaEx0gzgCIQC0+un/Hcb0OWvpvoeHKcRi7e8SZkX+vn2i ++u+KsPqlfzA== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBHjAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMzEwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAzMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHg1qbhT ++bpV0agLQkk6di7EdwrrqIn7yCiBCfPwoDI7czY1bHwkR2E8EdrG4ZLBHHFXYNHau ++kEo9nueljxbA6MGjgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGXSqDk/Zov8a62kkXDr ++8YhtqdkTMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEA1D2Fm3D8REQtj8o4 ++ZrnDyWam0Rx6cEMsvmeoafOBUeUCIBW0IoUYmF46faRQWKN7R8wnvbjUw0bxztzy ++okUR5Pma ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEjCCAbigAwIBAgIBHzAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxQb2xpY3kg ++Q0EgMzEwIBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBcxFTATBgNV ++BAMTDFBvbGljeSBDQSAzMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIwGMmHl ++/QJSpu6KHakSe4gkf3L+NpsrtQpxu6sNfmSjO++dGv6sj2v3+DZNeyagVUJRVHaD ++IZzpoyVVrBBO6vijgfIwge8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA+f9g1sP2kM5sOT/8Ge ++IDKq5FcUMCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMHEG ++A1UdIQRqMGgwGAYKYIZIAWUDAgEwAQYKYIZIAWUDAgEwATAYBgpghkgBZQMCATAB ++BgpghkgBZQMCATACMBgGCmCGSAFlAwIBMAIGCmCGSAFlAwIBMAEwGAYKYIZIAWUD ++AgEwAgYKYIZIAWUDAgEwAjAKBggqhkjOPQQDAgNIADBFAiEAvQlbAmF3pS041Zo2 ++eHrxMO3j8thB+XqHU8RatCZ60WACIG1vUFPH7UwzTTann7Sgp4s+Gd/jLOkrJnEk ++W3De9dSX ++-----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_leaf.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_leaf.pem +new file mode 100644 +index 00000000..c40ddff9 +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_leaf.pem +@@ -0,0 +1,11 @@ ++-----BEGIN CERTIFICATE----- ++MIIBmjCCAT+gAwIBAgIBADAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE ++AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER7oh ++z+MnwilNhyEB2bZTuYBpeiwW4QlpYZU6b/8uWOldyMXCaPmaXwY60nrMznfFJX6F ++h8dC6XIzvQmjUMdSoqN4MHYwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t ++MCUGA1UdIAQeMBwwDAYKYIZIAWUDAgEwATAMBgpghkgBZQMCATACMAoGCCqGSM49 ++BAMCA0kAMEYCIQC2km5juUULIRYsRgHuLFEiABBR0pDAyTbl9LRjlkSeEQIhAO9b ++ye60dMNbhY1OOzrr4mDRv0tuNmbGBErcFs61YZkC ++-----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_policy_tree.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_policy_tree.pem +new file mode 100644 +index 00000000..040542d1 +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_policy_tree_data/small_policy_tree.pem +@@ -0,0 +1,70 @@ ++-----BEGIN CERTIFICATE----- ++MIICETCCAbagAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMjAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQu7GyNFjN6 ++Sqwk1CZAt+lzTC/Us6ZkO5nsmb8yAuPb6RJ0A2LvUbsmZea+UyBFq3VuEbbuCoeE ++KRbKkS6wefAzo4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQkJvfn8gFHIXVTBJ4hrtP ++ypA9QTAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSQAwRgIhALn6/b3H+jLusJE5QiaS ++PiwrLcl+NDguWCnxo0c6AfduAiEApkXUN+7vRfXeFFd9CfA1BnTW3eUzBOsukZoN ++zaj+utk= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICDzCCAbagAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgMzAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT+p+A+K6MI ++R3eVP/+2O7lam32HU10frEKpyQslZAabYJwkc9iq5WatMbTMPQibuOIWHFl02uJ8 ++cxGKy/Hke8P5o4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSSOt6HCXw+L/4uzJsInqqA ++XrWt8DAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDRwAwRAIgS/vh3osFy+q1MLuVnAdg ++gMINfiIJw1+3zbYsJYlNhWgCICu6Qgzee4NwIrJagcdVA0RAfnCOo6wfvikpl0ts ++EepA ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQONHKgpAJ6 ++vE41FYBekpLzybpBQp/gUmgRPKrcL0z4lLTDjCG3j6yIbZma8u2bPM1MBXw5otZ7 ++xVFhQ1AkZIOco4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQ69465BL89BXORf4sSnneU ++exkm0jAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAPK9PqPxgme9x6TPFh2z ++vv+qVEM2WxOTdRKOPgUYzCp9AiBl8qO3szv5jNDzb0fRIqVp37v9yBjWcgO9Wl02 ++QDCpGw== ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICETCCAbagAwIBAgIBBDAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASLrUP7BFi7 +++LE2uDVCZ2Z2HK6BpL/kjBbwKkLxlJe+LqNolzu53b8+WtHwrvPPVkD9t3KMdWXU ++K7NtHYgXUz07o4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS0kaY2oJVEBLtjkqI8pXsv ++eqm3VDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSQAwRgIhAJuTMvMUda4Y29V1Tm5O ++jCqBThR2NwdQfnET1sjch3Q7AiEA7nEudfXKMljjz608aWtafTkw5V5I2/SbuUKr ++vjprfIo= ++-----END CERTIFICATE----- ++-----BEGIN CERTIFICATE----- ++MIICEDCCAbagAwIBAgIBBTAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg ++Q0EgNTAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE ++AxMLUG9saWN5IENBIDUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ9RuYVzUGB ++FkAEM9kHe9xynDo/NcsiaAO3+E2u7jJQQN50d6hVEDHf9961omldhKhP4HTNfhqj ++VMIHKGMhXCgKo4HyMIHvMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF ++BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVrjWaVjkfMpilq5tGZ4zZ ++iJtaSDAlBgNVHSAEHjAcMAwGCmCGSAFlAwIBMAEwDAYKYIZIAWUDAgEwAjBxBgNV ++HSEEajBoMBgGCmCGSAFlAwIBMAEGCmCGSAFlAwIBMAEwGAYKYIZIAWUDAgEwAQYK ++YIZIAWUDAgEwAjAYBgpghkgBZQMCATACBgpghkgBZQMCATABMBgGCmCGSAFlAwIB ++MAIGCmCGSAFlAwIBMAIwCgYIKoZIzj0EAwIDSAAwRQIhAPVgPpACX2ylQMEMSntw ++izxKHTSPhXuF6IHhNHRz7KFnAiB8y/QcF7N2iXNZEqffWSkVted/XOw3Xrck0sJ6 ++4eXNcw== ++-----END CERTIFICATE----- +-- +2.33.0 + diff --git a/0037-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch b/0037-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed6048baf7157301d62e7260a408664be828dcde --- /dev/null +++ b/0037-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch @@ -0,0 +1,56 @@ +From 03afa0dfe07fc58931780105d2f1010cd9df26e2 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 7 Mar 2023 16:52:55 +0000 +Subject: [PATCH 03/11] Ensure that EXFLAG_INVALID_POLICY is checked even in + leaf certs + +Even though we check the leaf cert to confirm it is valid, we +later ignored the invalid flag and did not notice that the leaf +cert was bad. + +Fixes: CVE-2023-0465 + +Reviewed-by: Hugo Landau +Reviewed-by: Tomas Mraz + +reference: https://github.com/openssl/openssl/pull/20588 +Signed-off-by: yexiao +--- + .../Library/OpensslLib/openssl/crypto/x509/x509_vfy.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c +index f28f2d26..0c6ebb45 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c +@@ -1615,18 +1615,25 @@ static int check_policy(X509_STORE_CTX *ctx) + } + /* Invalid or inconsistent extensions */ + if (ret == X509_PCY_TREE_INVALID) { +- int i; ++ int i, cbcalled = 0; + + /* Locate certificates with bad extensions and notify callback. */ +- for (i = 1; i < sk_X509_num(ctx->chain); i++) { ++ for (i = 0; i < sk_X509_num(ctx->chain); i++) { + X509 *x = sk_X509_value(ctx->chain, i); + + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; ++ cbcalled = 1; + if (!verify_cb_cert(ctx, x, i, + X509_V_ERR_INVALID_POLICY_EXTENSION)) + return 0; + } ++ if (!cbcalled) { ++ /* Should not be able to get here */ ++ X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ /* The callback ignored the error so we return success */ + return 1; + } + if (ret == X509_PCY_TREE_FAILURE) { +-- +2.33.0 + diff --git a/0038-Fix-documentation-of-X509_VERIFY_PARAM_add0_policy.patch b/0038-Fix-documentation-of-X509_VERIFY_PARAM_add0_policy.patch new file mode 100644 index 0000000000000000000000000000000000000000..35fb761e0a883a7668260889e10baeec965f8cbe --- /dev/null +++ b/0038-Fix-documentation-of-X509_VERIFY_PARAM_add0_policy.patch @@ -0,0 +1,48 @@ +From 751d202d04dc900154b25fbaf52d7d47b14f221d Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 21 Mar 2023 16:15:47 +0100 +Subject: [PATCH 04/11] Fix documentation of X509_VERIFY_PARAM_add0_policy() + +The function was incorrectly documented as enabling policy checking. + +Fixes: CVE-2023-0466 + +Reviewed-by: Matt Caswell +Reviewed-by: Paul Dale + +reference: https://github.com/openssl/openssl/pull/20564 +Signed-off-by: yexiao +--- + .../openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod +index 7593dea7..102f0c08 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod ++++ b/CryptoPkg/Library/OpensslLib/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod +@@ -92,8 +92,9 @@ B. + X509_VERIFY_PARAM_set_time() sets the verification time in B to + B. Normally the current time is used. + +-X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled +-by default) and adds B to the acceptable policy set. ++X509_VERIFY_PARAM_add0_policy() adds B to the acceptable policy set. ++Contrary to preexisting documentation of this function it does not enable ++policy checking. + + X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled + by default) and sets the acceptable policy set to B. Any existing +@@ -374,6 +375,10 @@ and has no effect. + + The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i. + ++The function X509_VERIFY_PARAM_add0_policy() was historically documented as ++enabling policy checking however the implementation has never done this. ++The documentation was changed to align with the implementation. ++ + =head1 COPYRIGHT + + Copyright 2009-2019 The OpenSSL Project Authors. All Rights Reserved. +-- +2.33.0 + diff --git a/0039-Restrict-the-size-of-OBJECT-IDENTIFIERs-that-OBJ_obj.patch b/0039-Restrict-the-size-of-OBJECT-IDENTIFIERs-that-OBJ_obj.patch new file mode 100644 index 0000000000000000000000000000000000000000..61bf0ddcfa042b14b93695c20966557b85e6ecbe --- /dev/null +++ b/0039-Restrict-the-size-of-OBJECT-IDENTIFIERs-that-OBJ_obj.patch @@ -0,0 +1,67 @@ +From 65c0eaad449b809f827a177558a880522d18dd88 Mon Sep 17 00:00:00 2001 +From: Richard Levitte +Date: Fri, 12 May 2023 10:00:13 +0200 +Subject: [PATCH 05/11] Restrict the size of OBJECT IDENTIFIERs that + OBJ_obj2txt will translate + +OBJ_obj2txt() would translate any size OBJECT IDENTIFIER to canonical +numeric text form. For gigantic sub-identifiers, this would take a very +long time, the time complexity being O(n^2) where n is the size of that +sub-identifier. + +To mitigate this, a restriction on the size that OBJ_obj2txt() will +translate to canonical numeric text form is added, based on RFC 2578 +(STD 58), which says this: + +> 3.5. OBJECT IDENTIFIER values +> +> An OBJECT IDENTIFIER value is an ordered list of non-negative numbers. +> For the SMIv2, each number in the list is referred to as a sub-identifier, +> there are at most 128 sub-identifiers in a value, and each sub-identifier +> has a maximum value of 2^32-1 (4294967295 decimal). + +Fixes otc/security#96 +Fixes CVE-2023-2650 + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz + +reference: https://github.com/openssl/openssl/commit/9e209944b35cf82368071f160a744b6178f9b098 +Signed-off-by: yexiao +--- + .../openssl/crypto/objects/obj_dat.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c +index 46006fe6..14206390 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c +@@ -427,6 +427,25 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) + first = 1; + bl = NULL; + ++ /* ++ * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs: ++ * ++ * > 3.5. OBJECT IDENTIFIER values ++ * > ++ * > An OBJECT IDENTIFIER value is an ordered list of non-negative ++ * > numbers. For the SMIv2, each number in the list is referred to as a ++ * > sub-identifier, there are at most 128 sub-identifiers in a value, ++ * > and each sub-identifier has a maximum value of 2^32-1 (4294967295 ++ * > decimal). ++ * ++ * So a legitimate OID according to this RFC is at most (32 * 128 / 7), ++ * i.e. 586 bytes long. ++ * ++ * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5 ++ */ ++ if (len > 586) ++ goto err; ++ + while (len > 0) { + l = 0; + use_bn = 0; +-- +2.33.0 + diff --git a/0040-Add-a-test-for-CVE-2023-3446.patch b/0040-Add-a-test-for-CVE-2023-3446.patch new file mode 100644 index 0000000000000000000000000000000000000000..b569a40226ace5fbd890308a0e6c857cc9f2cbbd --- /dev/null +++ b/0040-Add-a-test-for-CVE-2023-3446.patch @@ -0,0 +1,63 @@ +From 608d30d14e125a8b8352f864aa0a529418125697 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 7 Jul 2023 14:39:48 +0100 +Subject: [PATCH 06/11] Add a test for CVE-2023-3446 + +Confirm that the only errors DH_check() finds with DH parameters with an +excessively long modulus is that the modulus is too large. We should not +be performing time consuming checks using that modulus. + +Reviewed-by: Paul Dale +Reviewed-by: Tom Cosgrove +Reviewed-by: Bernd Edlinger +Reviewed-by: Tomas Mraz + +reference: https://github.com/openssl/openssl/pull/21452 +Signed-off-by: yexiao +--- + .../Library/OpensslLib/openssl/test/dhtest.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c +index 9d5609b9..00b3c471 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c +@@ -63,7 +63,7 @@ static int dh_test(void) + || !TEST_true(DH_set0_pqg(dh, p, q, g))) + goto err1; + +- if (!DH_check(dh, &i)) ++ if (!TEST_true(DH_check(dh, &i))) + goto err2; + if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) + || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME) +@@ -123,6 +123,17 @@ static int dh_test(void) + /* check whether the public key was calculated correctly */ + TEST_uint_eq(BN_get_word(pub_key2), 3331L); + ++ /* Modulus of size: dh check max modulus bits + 1 */ ++ if (!TEST_true(BN_set_word(p, 1)) ++ || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) ++ goto err3; ++ ++ /* ++ * We expect no checks at all for an excessively large modulus ++ */ ++ if (!TEST_false(DH_check(dh, &i))) ++ goto err3; ++ + /* + * II) key generation + */ +@@ -137,7 +148,7 @@ static int dh_test(void) + goto err3; + + /* ... and check whether it is valid */ +- if (!DH_check(a, &i)) ++ if (!TEST_true(DH_check(a, &i))) + goto err3; + if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) + || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME) +-- +2.33.0 + diff --git a/0041-Fix-DH_check-excessive-time-with-over-sized-modulus.patch b/0041-Fix-DH_check-excessive-time-with-over-sized-modulus.patch new file mode 100644 index 0000000000000000000000000000000000000000..aaf9b99a96bff143c84aaf529095e79951b1333c --- /dev/null +++ b/0041-Fix-DH_check-excessive-time-with-over-sized-modulus.patch @@ -0,0 +1,127 @@ +From 01fae0d95d961c14a7819e02ec16e43c1225dfa9 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 6 Jul 2023 16:36:35 +0100 +Subject: [PATCH 07/11] Fix DH_check() excessive time with over sized modulus + +The DH_check() function checks numerous aspects of the key or parameters +that have been supplied. Some of those checks use the supplied modulus +value even if it is excessively large. + +There is already a maximum DH modulus size (10,000 bits) over which +OpenSSL will not generate or derive keys. DH_check() will however still +perform various tests for validity on such a large modulus. We introduce a +new maximum (32,768) over which DH_check() will just fail. + +An application that calls DH_check() and supplies a key or parameters +obtained from an untrusted source could be vulnerable to a Denial of +Service attack. + +The function DH_check() is itself called by a number of other OpenSSL +functions. An application calling any of those other functions may +similarly be affected. The other functions affected by this are +DH_check_ex() and EVP_PKEY_param_check(). + +CVE-2023-3446 + +Reviewed-by: Paul Dale +Reviewed-by: Tom Cosgrove +Reviewed-by: Bernd Edlinger +Reviewed-by: Tomas Mraz + +reference: https://github.com/openssl/openssl/pull/21452 +Signed-off-by: yexiao +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c | 6 ++++++ + CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c | 3 ++- + CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt | 1 + + CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h | 4 ++++ + .../Library/OpensslLib/openssl/include/openssl/dherr.h | 3 ++- + 5 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +index 4ac169e7..e5f9dd50 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +@@ -101,6 +101,12 @@ int DH_check(const DH *dh, int *ret) + BN_CTX *ctx = NULL; + BIGNUM *t1 = NULL, *t2 = NULL; + ++ /* Don't do any checks at all with an excessively large modulus */ ++ if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { ++ DHerr(DH_F_DH_CHECK, DH_R_MODULUS_TOO_LARGE); ++ return 0; ++ } ++ + if (!DH_check_params(dh, ret)) + return 0; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c +index 7285587b..92800d3f 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -18,6 +18,7 @@ static const ERR_STRING_DATA DH_str_functs[] = { + {ERR_PACK(ERR_LIB_DH, DH_F_DHPARAMS_PRINT_FP, 0), "DHparams_print_fp"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS, 0), + "dh_builtin_genparams"}, ++ {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK, 0), "DH_check"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"}, + {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"}, +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +index 03d16406..a07f1a1b 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +@@ -401,6 +401,7 @@ CT_F_SCT_SET_VERSION:104:SCT_set_version + DH_F_COMPUTE_KEY:102:compute_key + DH_F_DHPARAMS_PRINT_FP:101:DHparams_print_fp + DH_F_DH_BUILTIN_GENPARAMS:106:dh_builtin_genparams ++DH_F_DH_CHECK:126:DH_check + DH_F_DH_CHECK_EX:121:DH_check_ex + DH_F_DH_CHECK_PARAMS_EX:122:DH_check_params_ex + DH_F_DH_CHECK_PUB_KEY_EX:123:DH_check_pub_key_ex +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h +index 3527540c..ff00397c 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h +@@ -30,6 +30,10 @@ extern "C" { + # define OPENSSL_DH_MAX_MODULUS_BITS 10000 + # endif + ++# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS ++# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768 ++# endif ++ + # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + + # define DH_FLAG_CACHE_MONT_P 0x01 +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h +index 916b3bed..528c8198 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -30,6 +30,7 @@ int ERR_load_DH_strings(void); + # define DH_F_COMPUTE_KEY 102 + # define DH_F_DHPARAMS_PRINT_FP 101 + # define DH_F_DH_BUILTIN_GENPARAMS 106 ++# define DH_F_DH_CHECK 126 + # define DH_F_DH_CHECK_EX 121 + # define DH_F_DH_CHECK_PARAMS_EX 122 + # define DH_F_DH_CHECK_PUB_KEY_EX 123 +-- +2.33.0 + diff --git a/0042-Update-further-expiring-certificates-that-affect-tes.patch b/0042-Update-further-expiring-certificates-that-affect-tes.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d8695a0accd5374c2d4e6d6c51254e78e0f029f --- /dev/null +++ b/0042-Update-further-expiring-certificates-that-affect-tes.patch @@ -0,0 +1,965 @@ +From 23b5325a3a8ebd268eab4b6df2df057d5c2c87aa Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Thu, 2 Jun 2022 18:12:05 +0200 +Subject: [PATCH 08/11] Update further expiring certificates that affect tests + +Namely the smime certificates used in test_cms +will expire soon and affect tests. + +Fixes #15179 + +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Paul Dale + +reference: https://github.com/openssl/openssl/pull/18481) +Signed-off-by: yexiao +--- + .../openssl/test/smime-certs/mksmime-certs.sh | 22 ++--- + .../openssl/test/smime-certs/smdh.pem | 72 +++++++++------ + .../openssl/test/smime-certs/smdsa1.pem | 86 +++++++++--------- + .../openssl/test/smime-certs/smdsa2.pem | 86 +++++++++--------- + .../openssl/test/smime-certs/smdsa3.pem | 86 +++++++++--------- + .../openssl/test/smime-certs/smec1.pem | 36 ++++---- + .../openssl/test/smime-certs/smec2.pem | 38 ++++---- + .../openssl/test/smime-certs/smroot.pem | 90 +++++++++---------- + .../openssl/test/smime-certs/smrsa1.pem | 90 +++++++++---------- + .../openssl/test/smime-certs/smrsa2.pem | 90 +++++++++---------- + .../openssl/test/smime-certs/smrsa3.pem | 90 +++++++++---------- + 11 files changed, 400 insertions(+), 386 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/mksmime-certs.sh b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/mksmime-certs.sh +index c98e164b..caa191ed 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/mksmime-certs.sh ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/mksmime-certs.sh +@@ -15,23 +15,23 @@ export OPENSSL_CONF + + # Root CA: create certificate directly + CN="Test S/MIME RSA Root" $OPENSSL req -config ca.cnf -x509 -nodes \ +- -keyout smroot.pem -out smroot.pem -newkey rsa:2048 -days 3650 ++ -keyout smroot.pem -out smroot.pem -newkey rsa:2048 -days 36501 + + # EE RSA certificates: create request first + CN="Test S/MIME EE RSA #1" $OPENSSL req -config ca.cnf -nodes \ + -keyout smrsa1.pem -out req.pem -newkey rsa:2048 + # Sign request: end entity extensions +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa1.pem + + CN="Test S/MIME EE RSA #2" $OPENSSL req -config ca.cnf -nodes \ + -keyout smrsa2.pem -out req.pem -newkey rsa:2048 +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa2.pem + + CN="Test S/MIME EE RSA #3" $OPENSSL req -config ca.cnf -nodes \ + -keyout smrsa3.pem -out req.pem -newkey rsa:2048 +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa3.pem + + # Create DSA parameters +@@ -40,15 +40,15 @@ $OPENSSL dsaparam -out dsap.pem 2048 + + CN="Test S/MIME EE DSA #1" $OPENSSL req -config ca.cnf -nodes \ + -keyout smdsa1.pem -out req.pem -newkey dsa:dsap.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa1.pem + CN="Test S/MIME EE DSA #2" $OPENSSL req -config ca.cnf -nodes \ + -keyout smdsa2.pem -out req.pem -newkey dsa:dsap.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa2.pem + CN="Test S/MIME EE DSA #3" $OPENSSL req -config ca.cnf -nodes \ + -keyout smdsa3.pem -out req.pem -newkey dsa:dsap.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa3.pem + + # Create EC parameters +@@ -58,15 +58,15 @@ $OPENSSL ecparam -out ecp2.pem -name K-283 + + CN="Test S/MIME EE EC #1" $OPENSSL req -config ca.cnf -nodes \ + -keyout smec1.pem -out req.pem -newkey ec:ecp.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec1.pem + CN="Test S/MIME EE EC #2" $OPENSSL req -config ca.cnf -nodes \ + -keyout smec2.pem -out req.pem -newkey ec:ecp2.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec2.pem + CN="Test S/MIME EE EC #3" $OPENSSL req -config ca.cnf -nodes \ + -keyout smec3.pem -out req.pem -newkey ec:ecp.pem +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec3.pem + # Create X9.42 DH parameters. + $OPENSSL genpkey -genparam -algorithm DH -pkeyopt dh_paramgen_type:2 \ +@@ -78,7 +78,7 @@ $OPENSSL pkey -pubout -in smdh.pem -out dhpub.pem + CN="Test S/MIME EE DH #1" $OPENSSL req -config ca.cnf -nodes \ + -keyout smtmp.pem -out req.pem -newkey rsa:2048 + # Sign request but force public key to DH +-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \ ++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \ + -force_pubkey dhpub.pem \ + -extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdh.pem + # Remove temp files. +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdh.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdh.pem +index f831b071..273dfca5 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdh.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdh.pem +@@ -1,33 +1,47 @@ + -----BEGIN PRIVATE KEY----- +-MIIBSgIBADCCASsGByqGSM4+AgEwggEeAoGBANQMSgwEcnEZ31kZxa9Ef8qOK/AJ +-9dMlsXMWVYnf/QevGdN/0Aei/j9a8QHG+CvvTm0DOEKhN9QUtABKsYZag865CA7B +-mSdHjQuFqILtzA25sDJ+3+jk9vbss+56ETRll/wasJVLGbmmHNkBMvc1fC1d/sGF +-cEn4zJnQvvFaeMgDAoGAaQD9ZvL8FYsJuNxN6qp5VfnfRqYvyi2PWSqtRKPGGC+V +-thYg49PRjwPOcXzvOsdEOQ7iH9jTiSvnUdwSSEwYTZkSBuQXAgOMJAWOpoXyaRvh +-atziBDoBnWS+/kX5RBhxvS0+em9yfRqAQleuGG+R1mEDihyJc8dWQQPT+O1l4oUC +-FQCJlKsQZ0VBrWPGcUCNa54ZW6TH9QQWAhRR2NMZrQSfWthXDO8Lj5WZ34zQrA== ++MIICXAIBADCCAjUGByqGSM4+AgEwggIoAoIBAQCB6AUA/1eXRh+iLWHXe+lUl6e+ +++460tAIIpsQ1jw1ZaTmlH9SlrWSBNVRVHwDuBW7vA+lKgBvDpCIjmhRbgrZIGwcZ ++6ruCYy5KF/B3AW5MApC9QCDaVrG6Hb7NfpMgwuUIKvvvOMrrvn4r5Oxtsx9rORTE ++bdS33MuZCOIbodjs5u+e/2hhssOwgUTMASDwXppJTyeMwAAZ+p78ByrSULP6yYdP ++PTh8sK1begDG6YTSKE3VqYNg1yaE5tQvCQ0U2L4qZ8JqexAVHbR8LA8MNhtA1pma ++Zj4q2WNAEevpprIIRXgJEZY278nPlvVeoKfOef9RBHgQ6ZTnZ1Et5iLMCwYHAoIB ++AFVgJaHfnBVJYfaQh1NyoVZJ5xX6UvvL5xEKUwwEMgs8JSOzp2UI+KRDpy9KbNH7 ++93Kwa2d8Q7ynciDiCmd1ygF4CJKb4ZOwjWjpZ4DedHr0XokGhyBCyjaBxOi3i4tP ++EFO8YHs5B/yOZHzcpTfs2VxJqIm3KF8q0Ify9PWDAsgo+d21/+eye60FHjF9o2/D ++l3NRlOhUhHNGykfqFgKEEEof3/3c6r5BS0oRXdsu6dx/y2/v8j9aJoHfyGHkswxr ++ULSBxJENOBB89C+GET6yhbxV1e4SFwzHnXgG8bWXwk7bea6ZqXbHq0pT3kUiQeKe ++assXKqRBAG9NLbQ3mmx8RFkCHQDIVBWPf6VwBa2s1CAcsIziVJ8qr/KAKx9DZ3h5 ++BB4CHAF3VZBAC/TB85J4PzsLJ+VrOWr0c8kQlYUR9rw= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIID/zCCAuegAwIBAgIJANv1TSKgememMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA4MDIxNDQ5MjlaFw0yMzA2MTExNDQ5MjlaMEQx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU +-ZXN0IFMvTUlNRSBFRSBESCAjMTCCAbYwggErBgcqhkjOPgIBMIIBHgKBgQDUDEoM +-BHJxGd9ZGcWvRH/KjivwCfXTJbFzFlWJ3/0HrxnTf9AHov4/WvEBxvgr705tAzhC +-oTfUFLQASrGGWoPOuQgOwZknR40LhaiC7cwNubAyft/o5Pb27LPuehE0ZZf8GrCV +-Sxm5phzZATL3NXwtXf7BhXBJ+MyZ0L7xWnjIAwKBgGkA/Wby/BWLCbjcTeqqeVX5 +-30amL8otj1kqrUSjxhgvlbYWIOPT0Y8DznF87zrHRDkO4h/Y04kr51HcEkhMGE2Z +-EgbkFwIDjCQFjqaF8mkb4Wrc4gQ6AZ1kvv5F+UQYcb0tPnpvcn0agEJXrhhvkdZh +-A4ociXPHVkED0/jtZeKFAhUAiZSrEGdFQa1jxnFAjWueGVukx/UDgYQAAoGAL1ve +-cgI2awBeJH8ULBhSQpdL224VUDxFPiXzt8Vu5VLnxPv0pfA5En+8VByTuV7u6RSw +-3/78NuTyr/sTyN8YlB1AuXHdTJynA1ICte1xgD4j2ijlq+dv8goOAFt9xkvXx7LD +-umJ/cCignXETcNGfMi8+0s0bpMZyoHRdce8DQ26jYDBeMAwGA1UdEwEB/wQCMAAw +-DgYDVR0PAQH/BAQDAgXgMB0GA1UdDgQWBBQLWk1ffSXH8p3Bqrdjgi/6jzLnwDAf +-BgNVHSMEGDAWgBTffl6IBSQzCN0igQKXzJq3sTMnMDANBgkqhkiG9w0BAQUFAAOC +-AQEAWvJj79MW1/Wq3RIANgAhonsI1jufYqxTH+1M0RU0ZXHulgem77Le2Ls1bizi +-0SbvfpTiiFGkbKonKtO2wvfqwwuptSg3omMI5IjAGxYbyv2KBzIpp1O1LTDk9RbD +-48JMMF01gByi2+NLUQ1MYF+5RqyoRqcyp5x2+Om1GeIM4Q/GRuI4p4dybWy8iC+d +-LeXQfR7HXfh+tAum+WzjfLJwbnWbHmPhTbKB01U4lBp6+r8BGHAtNdPjEHqap4/z +-vVZVXti9ThZ20EhM+VFU3y2wyapeQjhQvw/A2YRES0Ik7BSj3hHfWH/CTbLVQnhu +-Uj6tw18ExOYxqoEGixNLPA5qsQ== ++MIIFmDCCBICgAwIBAgIUWlJkHZZ2eZgkGCHFtcMAjlLdDH8wDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBEMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEdMBsGA1UEAwwUVGVzdCBTL01JTUUgRUUgREggIzEwggNCMIICNQYHKoZIzj4C ++ATCCAigCggEBAIHoBQD/V5dGH6ItYdd76VSXp777jrS0AgimxDWPDVlpOaUf1KWt ++ZIE1VFUfAO4Fbu8D6UqAG8OkIiOaFFuCtkgbBxnqu4JjLkoX8HcBbkwCkL1AINpW ++sbodvs1+kyDC5Qgq++84yuu+fivk7G2zH2s5FMRt1Lfcy5kI4huh2Ozm757/aGGy ++w7CBRMwBIPBemklPJ4zAABn6nvwHKtJQs/rJh089OHywrVt6AMbphNIoTdWpg2DX ++JoTm1C8JDRTYvipnwmp7EBUdtHwsDww2G0DWmZpmPirZY0AR6+mmsghFeAkRljbv ++yc+W9V6gp855/1EEeBDplOdnUS3mIswLBgcCggEAVWAlod+cFUlh9pCHU3KhVknn ++FfpS+8vnEQpTDAQyCzwlI7OnZQj4pEOnL0ps0fv3crBrZ3xDvKdyIOIKZ3XKAXgI ++kpvhk7CNaOlngN50evReiQaHIELKNoHE6LeLi08QU7xgezkH/I5kfNylN+zZXEmo ++ibcoXyrQh/L09YMCyCj53bX/57J7rQUeMX2jb8OXc1GU6FSEc0bKR+oWAoQQSh/f ++/dzqvkFLShFd2y7p3H/Lb+/yP1omgd/IYeSzDGtQtIHEkQ04EHz0L4YRPrKFvFXV ++7hIXDMedeAbxtZfCTtt5rpmpdserSlPeRSJB4p5qyxcqpEEAb00ttDeabHxEWQId ++AMhUFY9/pXAFrazUIBywjOJUnyqv8oArH0NneHkDggEFAAKCAQBigH0Mp4jUMSfK ++yOhKlEfyZ/hj/EImsUYW4+u8xjBN+ruOJUTJ06Mtgw3g2iLkhQoO9NROqvC9rdLj +++j3e+1QWm9EDNKQAa4nUp8/W+XZ5KkQWudmtaojEXD1+kd44ieNLtPGuVnPtDGO4 ++zPf04IUq7tDGbMDMMn6YXvW6f28lR3gF5vvVIsnjsd/Lau6orzmNSrymXegsEsFR ++Q7hT+/tPoAtro6Hx9rBrYb/0OCiRe4YuYrFKkC0aaJfUQepVyuVMSTxxKTzq8T06 ++M8SBITlmkPFZJHyGzV/+a72hpJsAa0BaDnpxH3cFpEMzeYG1XQK461zexoIYN3ub ++i3xNPUzPo2AwXjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4E ++FgQULayIqKcWHtUH4pFolI6dKxycIG8wHwYDVR0jBBgwFoAUFcETIWviVV+nah1X ++INbP86lzZFkwDQYJKoZIhvcNAQELBQADggEBAKjKvvJ6Vc9HiQXACqqRZnekz2gO ++ue71nsXXDr2+y4PPpgcDzgtO3vhQc7Akv6Uyca9LY7w/X+temP63yxdLpKXTV19w ++Or0p4VEvTZ8AttMjFh4Hl8caVYk/J4TIudSXLIfKROP6sFu5GOw7W3xpBkL5Zio6 ++3dqe6xAYK0woNQPDfj5yOAlqj1Ohth81JywW5h2g8GfLtNe62coAqwjMJT+ExHfU ++EkF/beSqRGOvXwyhSxFpe7HVjUMgrgdfoZnNsoPmpH3eTiF4BjamGWI1+Z0o+RHa ++oPwN+cCzbDsi9uTQJO1D5S697heX00zzzU/KSW7djNzKv55vm24znuFkXTM= + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa1.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa1.pem +index b424f670..0104e207 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa1.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa1.pem +@@ -1,47 +1,47 @@ + -----BEGIN PRIVATE KEY----- +-MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQCQfLlNdehPnTrGIMhw4rk0uua6 +-k1nCG3zcyfXli17BdB2k0HBPaTA3a3ZHfOt1Awy0Uu0wZ3gdPr9z0I64hnJXIGou +-zIanZ7nYRImHtX5JMFbXeyxo1Owd2Zs3oEk9nQUoUsMxvmYC/ghPL5Zx1pPxcHCO +-wzWxoG4yZMjimXOc1/W7zvK/4/g/Cz9fItD3zdcydfgM/hK0/CeYQ21xfhqf4mjK +-v9plnCcWgToGI+7H8VK80MFbkO2QKRz3vP1/TjK6PRm9sEeB5b10+SvGv2j2w+CC +-0fXL4s6n7PtBlm/bww8xL1/Az8kwejUcII1Dc8uNwwISwGbwaGBvl7IHpm21AiEA +-rodZi+nCKZdTL8IgCjX3n0DuhPRkVQPjz/B6VweLW9MCggEAfimkUNwnsGFp7mKM +-zJKhHoQkMB1qJzyIHjDzQ/J1xjfoF6i27afw1/WKboND5eseZhlhA2TO5ZJB6nGx +-DOE9lVQxYVml++cQj6foHh1TVJAgGl4mWuveW/Rz+NEhpK4zVeEsfMrbkBypPByy +-xzF1Z49t568xdIo+e8jLI8FjEdXOIUg4ehB3NY6SL8r4oJ49j/sJWfHcDoWH/LK9 +-ZaBF8NpflJe3F40S8RDvM8j2HC+y2Q4QyKk1DXGiH+7yQLGWzr3M73kC3UBnnH0h +-Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+ +-TQMsxQQjAiEAkolGvb/76X3vm5Ov09ezqyBYt9cdj/FLH7DyMkxO7X0= ++MIICXQIBADCCAjYGByqGSM44BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1 ++i0SuHnFvPc5gHMLIxJhDp3cLJ5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t ++4INbA4D+QSkxb4SWNurRBQj5LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAa ++kOxI+l/rPAQlIUMCHSF6xXgd62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLg ++c9HnYvwxlpoV+SHi+QXSrcrtMBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S ++8EP8eXSDD+1Sni2Jk38etU+laS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0A ++mkjrU1XrCahV9d78Rklpd4fK3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huaw ++V6wj7hT99kjzQjZqbvLENW9bbAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7 ++ioJmtded5hhS6GDg3Oj4IYiJ9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKR ++CnZ2/FeRyjSS3cUey89GE2N2DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL ++5H4Oo6NaSUc8dl7HWEeWoS8BE7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdL ++QldkaQkHAEg0QqYb2Hv/xHfVhn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwX ++ygQeAhwE9yuqObvNXzUTN+PY2rg00PzdyJw3XJAUrmlY + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBDMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8 +-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS +-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS +-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1 +-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9 +-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D +-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb +-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu +-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4 +-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv +-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf +-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P +-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAGXSQADbuRIZBjiQ6NikwZl+x +-EDEffIE0RWbvwf1tfWxw4ZvanO/djyz5FePO0AIJDBCLUjr9D32nkmIG1Hu3dWgV +-86knQsM6uFiMSzY9nkJGZOlH3w4NHLE78pk75xR1sg1MEZr4x/t+a/ea9Y4AXklE +-DCcaHtpMGeAx3ZAqSKec+zQOOA73JWP1/gYHGdYyTQpQtwRTsh0Gi5mOOdpoJ0vp +-O83xYbFCZ+ZZKX1RWOjJe2OQBRtw739q1nRga1VMLAT/LFSQsSE3IOp8hiWbjnit +-1SE6q3II2a/aHZH/x4OzszfmtQfmerty3eQSq3bgajfxCsccnRjSbLeNiazRSKNg +-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFNHQYTOO +-xaZ/N68OpxqjHKuatw6sMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs +-MA0GCSqGSIb3DQEBBQUAA4IBAQAAiLociMMXcLkO/uKjAjCIQMrsghrOrxn4ZGBx +-d/mCTeqPxhcrX2UorwxVCKI2+Dmz5dTC2xKprtvkiIadJamJmxYYzeF1pgRriFN3 +-MkmMMkTbe/ekSvSeMtHQ2nHDCAJIaA/k9akWfA0+26Ec25/JKMrl3LttllsJMK1z +-Xj7TcQpAIWORKWSNxY/ezM34+9ABHDZB2waubFqS+irlZsn38aZRuUI0K67fuuIt +-17vMUBqQpe2hfNAjpZ8dIpEdAGjQ6izV2uwP1lXbiaK9U4dvUqmwyCIPniX7Hpaf +-0VnX0mEViXMT6vWZTjLBUv0oKmO7xBkWHIaaX6oyF32pK5AO ++MIIFmjCCBIKgAwIBAgIUUoOmJmXAY29/2rWY0wJphQ5/pzUwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgRFNBICMxMIIDQzCCAjYGByqGSM44 ++BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1i0SuHnFvPc5gHMLIxJhDp3cL ++J5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t4INbA4D+QSkxb4SWNurRBQj5 ++LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAakOxI+l/rPAQlIUMCHSF6xXgd ++62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLgc9HnYvwxlpoV+SHi+QXSrcrt ++MBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S8EP8eXSDD+1Sni2Jk38etU+l ++aS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0AmkjrU1XrCahV9d78Rklpd4fK ++3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huawV6wj7hT99kjzQjZqbvLENW9b ++bAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7ioJmtded5hhS6GDg3Oj4IYiJ ++9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKRCnZ2/FeRyjSS3cUey89GE2N2 ++DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL5H4Oo6NaSUc8dl7HWEeWoS8B ++E7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdLQldkaQkHAEg0QqYb2Hv/xHfV ++hn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwXygOCAQUAAoIBACGS7hCpTL0g ++lx9C1Bwz5xfVd0mwCqx9UGiH8Bf4lRsSagL0Irwvnjz++WH1vecZa2bWsYsPhQ+D ++KDzaCo20CYln4IFEPgY0fSE+KTF1icFj/mD+MgxWgsgKoTI120ENPGHqHpKkv0Uv ++OlwTImU4BxxkctZ5273XEv3VPQE8COGnXgqt7NBazU/O7vibFm0iaEsVjHFHYcoo +++sMcm3F2E/gvR9IJGaGPeCk0sMW8qloPzErWIugx/OGqM7fni2cIcZwGdju52O+l ++cLV0tZdgC7eTbVDMLspyuiYME+zvEzRwCQF/GqcCDSn68zxJv/zSNZ9XxOgZaBfs ++Na7e8YGATiujYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMB0GA1Ud ++DgQWBBSFVrWPZrHzhHUg0MMEAAKwQIfsazAfBgNVHSMEGDAWgBQVwRMha+JVX6dq ++HVcg1s/zqXNkWTANBgkqhkiG9w0BAQsFAAOCAQEAbm49FB+eyeX7OBUC/akhnkFw ++cDXqw7Fl2OibRK+g/08zp4CruwJdb72j5+pTmG+9SF7tGyQBfHFf1+epa3ZiIc+0 ++UzFf2xQBMyHjesL19cTe4i176dHz8pCxx9OEow0GlZVV85+Anev101NskKVNNVA7 ++YnB2xKQWgf8HORh66XVCk54xMcd99ng8xQ8vhZC6KckVbheQgdPp7gUAcDgxH2Yo ++JF8jHQlsWNcCGURDldP6FQ49TGWHj24IGjnjGapWxMUjvCz+kV6sGW/OIYu+MM9w ++FMIOyEdUUtKowWT6eXwrITup3T6pspPTicbK61ZCPuxMvP2JBFGZsqat+F5g+w== + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa2.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa2.pem +index 648447fc..7d5b969d 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa2.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa2.pem +@@ -1,47 +1,47 @@ + -----BEGIN PRIVATE KEY----- +-MIICZAIBADCCAjkGByqGSM44BAEwggIsAoIBAQCQfLlNdehPnTrGIMhw4rk0uua6 +-k1nCG3zcyfXli17BdB2k0HBPaTA3a3ZHfOt1Awy0Uu0wZ3gdPr9z0I64hnJXIGou +-zIanZ7nYRImHtX5JMFbXeyxo1Owd2Zs3oEk9nQUoUsMxvmYC/ghPL5Zx1pPxcHCO +-wzWxoG4yZMjimXOc1/W7zvK/4/g/Cz9fItD3zdcydfgM/hK0/CeYQ21xfhqf4mjK +-v9plnCcWgToGI+7H8VK80MFbkO2QKRz3vP1/TjK6PRm9sEeB5b10+SvGv2j2w+CC +-0fXL4s6n7PtBlm/bww8xL1/Az8kwejUcII1Dc8uNwwISwGbwaGBvl7IHpm21AiEA +-rodZi+nCKZdTL8IgCjX3n0DuhPRkVQPjz/B6VweLW9MCggEAfimkUNwnsGFp7mKM +-zJKhHoQkMB1qJzyIHjDzQ/J1xjfoF6i27afw1/WKboND5eseZhlhA2TO5ZJB6nGx +-DOE9lVQxYVml++cQj6foHh1TVJAgGl4mWuveW/Rz+NEhpK4zVeEsfMrbkBypPByy +-xzF1Z49t568xdIo+e8jLI8FjEdXOIUg4ehB3NY6SL8r4oJ49j/sJWfHcDoWH/LK9 +-ZaBF8NpflJe3F40S8RDvM8j2HC+y2Q4QyKk1DXGiH+7yQLGWzr3M73kC3UBnnH0h +-Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+ +-TQMsxQQiAiAdCUJ5n2Q9hIynN8BMpnRcdfH696BKejGx+2Mr2kfnnA== ++MIICXQIBADCCAjYGByqGSM44BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1 ++i0SuHnFvPc5gHMLIxJhDp3cLJ5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t ++4INbA4D+QSkxb4SWNurRBQj5LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAa ++kOxI+l/rPAQlIUMCHSF6xXgd62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLg ++c9HnYvwxlpoV+SHi+QXSrcrtMBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S ++8EP8eXSDD+1Sni2Jk38etU+laS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0A ++mkjrU1XrCahV9d78Rklpd4fK3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huaw ++V6wj7hT99kjzQjZqbvLENW9bbAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7 ++ioJmtded5hhS6GDg3Oj4IYiJ9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKR ++CnZ2/FeRyjSS3cUey89GE2N2DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL ++5H4Oo6NaSUc8dl7HWEeWoS8BE7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdL ++QldkaQkHAEg0QqYb2Hv/xHfVhn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwX ++ygQeAhwmRauZi+nQ3kQ+GSKD7JCwv8XkD9NObMGlW018 + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBEMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8 +-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS +-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS +-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1 +-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9 +-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D +-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb +-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu +-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4 +-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv +-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf +-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P +-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAItQlFu0t7Mw1HHROuuwKLS+E +-h2WNNZP96MLQTygOVlqgaJY+1mJLzvl/51LLH6YezX0t89Z2Dm/3SOJEdNrdbIEt +-tbu5rzymXxFhc8uaIYZFhST38oQwJOjM8wFitAQESe6/9HZjkexMqSqx/r5aEKTa +-LBinqA1BJRI72So1/1dv8P99FavPADdj8V7fAccReKEQKnfnwA7mrnD+OlIqFKFn +-3wCGk8Sw7tSJ9g6jgCI+zFwrKn2w+w+iot/Ogxl9yMAtKmAd689IAZr5GPPvV2y0 +-KOogCiUYgSTSawZhr+rjyFavfI5dBWzMq4tKx/zAi6MJ+6hGJjJ8jHoT9JAPmaNg +-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFGaxw04k +-qpufeGZC+TTBq8oMnXyrMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs +-MA0GCSqGSIb3DQEBBQUAA4IBAQCk2Xob1ICsdHYx/YsBzY6E1eEwcI4RZbZ3hEXp +-VA72/Mbz60gjv1OwE5Ay4j+xG7IpTio6y2A9ZNepGpzidYcsL/Lx9Sv1LlN0Ukzb +-uk6Czd2sZJp+PFMTTrgCd5rXKnZs/0D84Vci611vGMA1hnUnbAnBBmgLXe9pDNRV +-6mhmCLLjJ4GOr5Wxt/hhknr7V2e1VMx3Q47GZhc0o/gExfhxXA8+gicM0nEYNakD +-2A1F0qDhQGakjuofANHhjdUDqKJ1sxurAy80fqb0ddzJt2el89iXKN+aXx/zEX96 +-GI5ON7z/bkVwIi549lUOpWb2Mved61NBzCLKVP7HSuEIsC/I ++MIIFmjCCBIKgAwIBAgIUHGKu2FMhT1wCiJTK3uAnklo55uowDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgRFNBICMyMIIDQzCCAjYGByqGSM44 ++BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1i0SuHnFvPc5gHMLIxJhDp3cL ++J5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t4INbA4D+QSkxb4SWNurRBQj5 ++LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAakOxI+l/rPAQlIUMCHSF6xXgd ++62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLgc9HnYvwxlpoV+SHi+QXSrcrt ++MBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S8EP8eXSDD+1Sni2Jk38etU+l ++aS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0AmkjrU1XrCahV9d78Rklpd4fK ++3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huawV6wj7hT99kjzQjZqbvLENW9b ++bAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7ioJmtded5hhS6GDg3Oj4IYiJ ++9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKRCnZ2/FeRyjSS3cUey89GE2N2 ++DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL5H4Oo6NaSUc8dl7HWEeWoS8B ++E7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdLQldkaQkHAEg0QqYb2Hv/xHfV ++hn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwXygOCAQUAAoIBAE0+OYS0s8/o ++HwuuiPsBZTlRynqdwF6FHdE0Ei2uVTxnJouPYB2HvaMioG2inbISzPtEcnLF9Pyx ++4hsXz7D49yqyMFjE3G8ObBOs/Vdno6E9ZZshWiRDwPf8JmoYp551UuJDoVaOTnhx ++pEs30nuidtqd54PMdWUQPfp58kTu6bXvcRxdUj5CK/PyjavJCnGfppq/6j8jtrji ++mOjIIeLZIbWp7hTVS/ffmfqZ8Lx/ShOcUzDa0VS3lfO28XqXpeqbyHdojsYlG2oA ++shKJL7/scq3ab8cI5QuHEIGSbxinKfjCX4OEQ04CNsgUwMY9emPSaNdYDZOPqq/K ++3bGk2PLcRsyjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMB0GA1Ud ++DgQWBBTQAQyUCqYWGo5RuwGCtHNgXgzEQzAfBgNVHSMEGDAWgBQVwRMha+JVX6dq ++HVcg1s/zqXNkWTANBgkqhkiG9w0BAQsFAAOCAQEAc3rayE2FGgG1RhLXAHYAs1Ky ++4fcVcrzaPaz5jjWbpBCStkx+gNcUiBf+aSxNrRvUoPOSwMDLpMhbNBj2cjJqQ0W1 ++oq4RUQth11qH89uPtBqiOqRTdlWAGZJbUTtVfrlc58DsDxFCwdcktSDYZwlO2lGO ++vMCOn9N7oqEEuwRa++xVnYc8ZbY8lGwJD3bGR6iC7NkYk+2LSqPS52m8e0GO8dpf ++RUrndbhmtsYa925dj2LlI218F3XwVcAUPW67dbpeEVw5OG8OCHRHqrwBEJj2PMV3 ++tHeNXDEhjTzI3wiFia4kDBAKIsrC/XQ4tEiFzq0V00BiVY0ykhy+v/qNPskTsg== + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa3.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa3.pem +index 77acc5e4..6df46994 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa3.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa3.pem +@@ -1,47 +1,47 @@ + -----BEGIN PRIVATE KEY----- +-MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQCQfLlNdehPnTrGIMhw4rk0uua6 +-k1nCG3zcyfXli17BdB2k0HBPaTA3a3ZHfOt1Awy0Uu0wZ3gdPr9z0I64hnJXIGou +-zIanZ7nYRImHtX5JMFbXeyxo1Owd2Zs3oEk9nQUoUsMxvmYC/ghPL5Zx1pPxcHCO +-wzWxoG4yZMjimXOc1/W7zvK/4/g/Cz9fItD3zdcydfgM/hK0/CeYQ21xfhqf4mjK +-v9plnCcWgToGI+7H8VK80MFbkO2QKRz3vP1/TjK6PRm9sEeB5b10+SvGv2j2w+CC +-0fXL4s6n7PtBlm/bww8xL1/Az8kwejUcII1Dc8uNwwISwGbwaGBvl7IHpm21AiEA +-rodZi+nCKZdTL8IgCjX3n0DuhPRkVQPjz/B6VweLW9MCggEAfimkUNwnsGFp7mKM +-zJKhHoQkMB1qJzyIHjDzQ/J1xjfoF6i27afw1/WKboND5eseZhlhA2TO5ZJB6nGx +-DOE9lVQxYVml++cQj6foHh1TVJAgGl4mWuveW/Rz+NEhpK4zVeEsfMrbkBypPByy +-xzF1Z49t568xdIo+e8jLI8FjEdXOIUg4ehB3NY6SL8r4oJ49j/sJWfHcDoWH/LK9 +-ZaBF8NpflJe3F40S8RDvM8j2HC+y2Q4QyKk1DXGiH+7yQLGWzr3M73kC3UBnnH0h +-Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+ +-TQMsxQQjAiEArJr6p2zTbhRppQurHGTdmdYHqrDdZH4MCsD9tQCw1xY= ++MIICXgIBADCCAjYGByqGSM44BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1 ++i0SuHnFvPc5gHMLIxJhDp3cLJ5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t ++4INbA4D+QSkxb4SWNurRBQj5LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAa ++kOxI+l/rPAQlIUMCHSF6xXgd62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLg ++c9HnYvwxlpoV+SHi+QXSrcrtMBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S ++8EP8eXSDD+1Sni2Jk38etU+laS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0A ++mkjrU1XrCahV9d78Rklpd4fK3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huaw ++V6wj7hT99kjzQjZqbvLENW9bbAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7 ++ioJmtded5hhS6GDg3Oj4IYiJ9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKR ++CnZ2/FeRyjSS3cUey89GE2N2DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL ++5H4Oo6NaSUc8dl7HWEeWoS8BE7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdL ++QldkaQkHAEg0QqYb2Hv/xHfVhn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwX ++ygQfAh0AkfI6533W5nBIVrDPcp2DCXC8u2SIwBob6OoK5A== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBFMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8 +-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS +-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS +-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1 +-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9 +-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D +-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb +-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu +-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4 +-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv +-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf +-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P +-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAcXvtfiJfIZ0wgGpN72ZeGrJ9 +-msUXOxow7w3fDbP8r8nfVkBNbfha8rx0eY6fURFVZzIOd8EHGKypcH1gS6eZNucf +-zgsH1g5r5cRahMZmgGXBEBsWrh2IaDG7VSKt+9ghz27EKgjAQCzyHQL5FCJgR2p7 +-cv0V4SRqgiAGYlJ191k2WtLOsVd8kX//jj1l8TUgE7TqpuSEpaSyQ4nzJROpZWZp +-N1RwFmCURReykABU/Nzin/+rZnvZrp8WoXSXEqxeB4mShRSaH57xFnJCpRwKJ4qS +-2uhATzJaKH7vu63k3DjftbSBVh+32YXwtHc+BGjs8S2aDtCW3FtDA7Z6J8BIxaNg +-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFMJxatDE +-FCEFGl4uoiQQ1050Ju9RMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs +-MA0GCSqGSIb3DQEBBQUAA4IBAQBGZD1JnMep39KMOhD0iBTmyjhtcnRemckvRask +-pS/CqPwo+M+lPNdxpLU2w9b0QhPnj0yAS/BS1yBjsLGY4DP156k4Q3QOhwsrTmrK +-YOxg0w7DOpkv5g11YLJpHsjSOwg5uIMoefL8mjQK6XOFOmQXHJrUtGulu+fs6FlM +-khGJcW4xYVPK0x/mHvTT8tQaTTkgTdVHObHF5Dyx/F9NMpB3RFguQPk2kT4lJc4i +-Up8T9mLzaxz6xc4wwh8h70Zw81lkGYhX+LRk3sfd/REq9x4QXQNP9t9qU1CgrBzv +-4orzt9cda4r+rleSg2XjWnXzMydE6DuwPVPZlqnLbSYUy660 ++MIIFmjCCBIKgAwIBAgIUO2QHMd9V/S6KlrFDIPd7asRP4FAwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgRFNBICMzMIIDQzCCAjYGByqGSM44 ++BAEwggIpAoIBAQCg5xGADjdINCKODDX6yq3w8vQ1i0SuHnFvPc5gHMLIxJhDp3cL ++J5eJmcHZ07WflsMgSxD2Wd5lX5Q9uxtv78/erv5t4INbA4D+QSkxb4SWNurRBQj5 ++LuoGhFMpCubDYSxiKkTJ4pmOEbsjnlGLiN5R1jAakOxI+l/rPAQlIUMCHSF6xXgd ++62fUdEAnRYj46Lgw+FWKAKNhcH7rOLA7k4JnYCLgc9HnYvwxlpoV+SHi+QXSrcrt ++MBNCmIgIONI5uNuBnZq6jjHE/Wg1+D4wGxOZl+/S8EP8eXSDD+1Sni2Jk38etU+l ++aS0pVV9lh6sV3zV28YXVZl01CHUfwH+3w/XJAh0AmkjrU1XrCahV9d78Rklpd4fK ++3K53+X5MeTgNLQKCAQEAoA32HKvIhx6wvmT9huawV6wj7hT99kjzQjZqbvLENW9b ++bAgOdPzZzusqZmZMgGdDr94oYz1/MhmAKNY4lQv7ioJmtded5hhS6GDg3Oj4IYiJ ++9trAQ/ATrDrSi3sQAZ3Pvip7j4oljvsQBmAj3KKRCnZ2/FeRyjSS3cUey89GE2N2 ++DQbHEmuG/F8aDmUhLNusZm6nXs2Y1W7+kQRwswBL5H4Oo6NaSUc8dl7HWEeWoS8B ++E7G4JFCXBQwwgInOJINyQlknxMSpv7dwxp32SgdLQldkaQkHAEg0QqYb2Hv/xHfV ++hn9vTpGJQyWvnT5RvbXSGdTk1CTlZTrUAGmbHOwXygOCAQUAAoIBAEj25Os9f57G ++TaxsP8NzdCRBThCLqZWqLADh6S/aFOQQFpRRk3vGkvrOK/5La8KGKIDyzCEQo7Kg ++sPwI1o4N5GKx15Cer2ekDWLtP4hA2CChs4tWJzEa8VxIDTg4EUnASFCbfDUY/Yt0 ++5NM4nxtBhnr6PT7XmRehEFaTAgmsQFJ29jKx4tJkr+Gmj9J4i10CPd9DvIgIEnNt ++rYMAlfbGovaZVCgKp5INVA4IkDfCcbzDeNiOGaACeV+4QuEbgIbUhMq9vbw3Vvqe ++jwozPdrTYjd7oNxx/tY7gqxFRFxdDPXPno230afsAJsHmNF7lpj9Q4vBhy8w/EI1 ++jGzuiXjei9qjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMB0GA1Ud ++DgQWBBTwbCT+wSR9cvTg70jA2yIWgQSDZjAfBgNVHSMEGDAWgBQVwRMha+JVX6dq ++HVcg1s/zqXNkWTANBgkqhkiG9w0BAQsFAAOCAQEAe5t9oi8K76y+wnV6I21vKgEh ++M6DEe3+XTq10kAgYbcbMm+a6n86beaID7FANGET+3bsShxFeAX9g4Qsdw+Z3PF3P ++wvqiBD8MaXczj28zP6j9TxsjGzpAsV3xo1n7aQ+hHzpopJUxAyx4hLBqSSwdj/xe ++azELeVKoXY/nlokXnONWC5AvtfR7m7mKFPOmUghbeGCJH7+FXnC58eiF7BEpSbQl ++SniAdQFis+Dne6/kwZnQQaSDg55ELfaZOLhaLcRtqqgU+kv24mXGGEBhs9bBKMz5 ++ZNiKLafE3tCGRA5iMRwzdeSgrdnkQDHFiYXh3JHk5oKwGOdxusgt3DTHAFej1A== + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec1.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec1.pem +index 75a86266..a94f65c6 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec1.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec1.pem +@@ -1,22 +1,22 @@ + -----BEGIN PRIVATE KEY----- +-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgXzBRX9Z5Ib4LAVAS +-DMlYvkj0SmLmYvWULe2LfyXRmpWhRANCAAS+SIj2FY2DouPRuNDp9WVpsqef58tV +-3gIwV0EOV/xyYTzZhufZi/aBcXugWR1x758x4nHus2uEuEFi3Mr3K3+x ++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgdOomk0EB/oWMnTZB ++Qm5XMjlKnZNF4PMpwgov0Tj3u8OhRANCAATbG6XprSqHiD9AxWJiXRFgS+y38DGZ ++7hpSjs4bd95L+Lli+O91/lUy7Tb8aJ6VU2CoyWQjV4sQjbdVqeD+y4Ky + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIICoDCCAYigAwIBAgIJANk5lu6mSyBGMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEQx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU +-ZXN0IFMvTUlNRSBFRSBFQyAjMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL5I +-iPYVjYOi49G40On1ZWmyp5/ny1XeAjBXQQ5X/HJhPNmG59mL9oFxe6BZHXHvnzHi +-ce6za4S4QWLcyvcrf7GjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXg +-MB0GA1UdDgQWBBR/ybxC2DI+Jydhx1FMgPbMTmLzRzAfBgNVHSMEGDAWgBTJkVMK +-Y3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEAdk9si83JjtgHHHGy +-WcgWDfM0jzlWBsgFNQ9DwAuB7gJd/LG+5Ocajg5XdA5FXAdKkfwI6be3PdcVs3Bt +-7f/fdKfBxfr9/SvFHnK7PVAX2x1wwS4HglX1lfoyq1boSvsiJOnAX3jsqXJ9TJiV +-FlgRVnhnrw6zz3Xs/9ZDMTENUrqDHPNsDkKEi+9SqIsqDXpMCrGHP4ic+S8Rov1y +-S+0XioMxVyXDp6XcL4PQ/NgHbw5/+UcS0me0atZ6pW68C0vi6xeU5vxojyuZxMI1 +-DXXwMhOXWaKff7KNhXDUN0g58iWlnyaCz4XQwFsbbFs88TQ1+e/aj3bbwTxUeyN7 +-qtcHJA== ++MIICrTCCAZWgAwIBAgIUdLT4B443vbxt0B8Mzy0sR4+6AyowDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBEMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEdMBsGA1UEAwwUVGVzdCBTL01JTUUgRUUgRUMgIzEwWTATBgcqhkjOPQIBBggq ++hkjOPQMBBwNCAATbG6XprSqHiD9AxWJiXRFgS+y38DGZ7hpSjs4bd95L+Lli+O91 ++/lUy7Tb8aJ6VU2CoyWQjV4sQjbdVqeD+y4Kyo2AwXjAMBgNVHRMBAf8EAjAAMA4G ++A1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUOia9H7l0qw3ftsDgEEeSBrHwQrwwHwYD ++VR0jBBgwFoAUFcETIWviVV+nah1XINbP86lzZFkwDQYJKoZIhvcNAQELBQADggEB ++AC7h/QkMocYANPqMQAO2okygG+OaE4qpKnlzHPUFMYedJGCvAWrwxu4hWL9T+hZo ++qilM7Fwaxw/P4Zaaa15SOOhXkIdn9Fu2ROmBQtEiklmWGMjiZ6F+9NCZPk0cTAXK ++2WQZOy41YNuvts+20osD4X/8x3fiARlokufj/TVyE73wG8pSSDh4KxWDfKv5Pi1F ++PC5IJh8XVELnFkeY3xjtoux5AYT+1xIQHO4eBua02Y1oPiWG7l/sK3grVlxrupd9 ++pXowwFlezWZP9q12VlWkcqwNb9hF9PkZge9bpiOJipSYgyobtAnms/CRHu3e6izl ++LJRua7p4Wt/8GQENDrVkHqU= + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec2.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec2.pem +index 457297a7..3fe14b3a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec2.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec2.pem +@@ -1,23 +1,23 @@ + -----BEGIN PRIVATE KEY----- +-MIGPAgEAMBAGByqGSM49AgEGBSuBBAAQBHgwdgIBAQQjhHaq507MOBznelrLG/pl +-brnnJi/iEJUUp+Pm3PEiteXqckmhTANKAAQF2zs6vobmoT+M+P2+9LZ7asvFBNi7 +-uCzLYF/8j1Scn/spczoC9vNzVhNw+Lg7dnjNL4EDIyYZLl7E0v69luzbvy+q44/8 +-6bQ= ++MIGQAgEAMBAGByqGSM49AgEGBSuBBAAQBHkwdwIBAQQkAEkuzLBwx5bIw3Q2PMNQ ++HzaY8yL3QLjzaJ8tCHrI/JTb9Q7VoUwDSgAEAu8b2HvLzKd0qhPtIw65Lh3OgF3X ++IN5874qHwt9zPSvokijSAH3v9tcBJPdRLD3Lweh2ZPn5hMwVwVorHqSgASk5vnjp ++HqER + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIICpTCCAY2gAwIBAgIJANk5lu6mSyBHMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEQx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU +-ZXN0IFMvTUlNRSBFRSBFQyAjMjBeMBAGByqGSM49AgEGBSuBBAAQA0oABAXbOzq+ +-huahP4z4/b70tntqy8UE2Lu4LMtgX/yPVJyf+ylzOgL283NWE3D4uDt2eM0vgQMj +-JhkuXsTS/r2W7Nu/L6rjj/zptKNgMF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8E +-BAMCBeAwHQYDVR0OBBYEFGf+QSQlkN20PsNN7x+jmQIJBDcXMB8GA1UdIwQYMBaA +-FMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3DQEBBQUAA4IBAQBaBBryl2Ez +-ftBrGENXMKQP3bBEw4n9ely6HvYQi9IC7HyK0ktz7B2FcJ4z96q38JN3cLxV0DhK +-xT/72pFmQwZVJngvRaol0k1B+bdmM03llxCw/uNNZejixDjHUI9gEfbigehd7QY0 +-uYDu4k4O35/z/XPQ6O5Kzw+J2vdzU8GXlMBbWeZWAmEfLGbk3Ux0ouITnSz0ty5P +-rkHTo0uprlFcZAsrsNY5v5iuomYT7ZXAR3sqGZL1zPOKBnyfXeNFUfnKsZW7Fnlq +-IlYBQIjqR1HGxxgCSy66f1oplhxSch4PUpk5tqrs6LeOqc2+xROy1T5YrB3yjVs0 +-4ZdCllHZkhop ++MIICsjCCAZqgAwIBAgIUFMjrNKt+D8tzvn7jtjZ5HrLcUlswDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxNFoYDzIxMjIw ++NTA5MTUzMzE0WjBEMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEdMBsGA1UEAwwUVGVzdCBTL01JTUUgRUUgRUMgIzIwXjAQBgcqhkjOPQIBBgUr ++gQQAEANKAAQC7xvYe8vMp3SqE+0jDrkuHc6AXdcg3nzviofC33M9K+iSKNIAfe/2 ++1wEk91EsPcvB6HZk+fmEzBXBWisepKABKTm+eOkeoRGjYDBeMAwGA1UdEwEB/wQC ++MAAwDgYDVR0PAQH/BAQDAgXgMB0GA1UdDgQWBBSqWRYUy2syIUwfSR31e19LeNXK ++9TAfBgNVHSMEGDAWgBQVwRMha+JVX6dqHVcg1s/zqXNkWTANBgkqhkiG9w0BAQsF ++AAOCAQEASbh+sI03xUMMzPT8bRbWNF5gG3ab8IUzqm05rTa54NCPRSn+ZdMXcCFz ++5fSU0T1dgEjeD+cCRVAZxskTZF7FWmRLc2weJMf7x+nPE5KaWyRAoD7FIKGP2m6m ++IMCVOmiafuzmHASBYOz6RwjgWS0AWES48DJX6o0KpuT4bsknz+H7Xo+4+NYGCRao ++enqIMZmWesGVXJ63pl32jUlXeAg59W6PpV2L9XRWLzDW1t1q2Uji7coCWtNjkojZ ++rv0yRMc1czkT+mAJRAJ8D9MoTnRXm1dH4bOxte4BGUHNQ2P1HeV01vkd1RTL0g0R ++lPyDAlBASvMn7RZ9nX8G3UOOL6gtVA== + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smroot.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smroot.pem +index d1a253f4..9af38d31 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smroot.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smroot.pem +@@ -1,49 +1,49 @@ + -----BEGIN PRIVATE KEY----- +-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyyQXED5HyVWwq +-nXyzmY317yMUJrIfsKvREG2C691dJNHgNg+oq5sjt/fzkyS84AvdOiicAsao4cYL +-DulthaLpbC7msEBhvwAil0FNb5g3ERupe1KuTdUV1UuD/i6S2VoaNXUBBn1rD9Wc +-BBc0lnx/4Wt92eQTI6925pt7ZHPQw2Olp7TQDElyi5qPxCem4uT0g3zbZsWqmmsI +-MXbu+K3dEprzqA1ucKXbxUmZNkMwVs2XCmlLxrRUj8C3/zENtH17HWCznhR/IVcV +-kgIuklkeiDsEhbWvUQumVXR7oPh/CPZAbjGqq5mVueHSHrp7brBVZKHZvoUka28Q +-LWitq1W5AgMBAAECggEASkRnOMKfBeOmQy2Yl6K57eeg0sYgSDnDpd0FINWJ5x9c +-b58FcjOXBodtYKlHIY6QXx3BsM0WaSEge4d+QBi7S+u8r+eXVwNYswXSArDQsk9R +-Bl5MQkvisGciL3pvLmFLpIeASyS/BLJXMbAhU58PqK+jT2wr6idwxBuXivJ3ichu +-ISdT1s2aMmnD86ulCD2DruZ4g0mmk5ffV+Cdj+WWkyvEaJW2GRYov2qdaqwSOxV4 +-Yve9qStvEIWAf2cISQjbnw2Ww6Z5ebrqlOz9etkmwIly6DTbrIneBnoqJlFFWGlF +-ghuzc5RE2w1GbcKSOt0qXH44MTf/j0r86dlu7UIxgQKBgQDq0pEaiZuXHi9OQAOp +-PsDEIznCU1bcTDJewANHag5DPEnMKLltTNyLaBRulMypI+CrDbou0nDr29VOzfXx +-mNvi/c7RttOBOx7kXKvu0JUFKe2oIWRsg0KsyMX7UFMVaHFgrW+8DhQc7HK7URiw +-nitOnA7YwIHRF9BMmcWcLFEYBQKBgQDC6LPbXV8COKO0YCfGXPnE7EZGD/p0Q92Z +-8CoSefphEScSdO1IpxFXG7fOZ4x2GQb9q7D3IvaeKAqNjUjkuyxdB30lIWDBwSWw +-fFgsa2SZwD5P60G/ar50YJr6LiF333aUMDVmC9swFfZERAEmGUz2NTrPWQdIx/lu +-PyDtUR75JQKBgHaoCCJ8vl5SJl1IA5GV4Bo8IoeLTSzsY9d09zMy6BoZcMD1Ix2T +-5S2cXhayoegl9PT6bsYSGHVWFCdJ86ktMI826TcXRzDaCvYhzc9THroJQcnfdbtP +-aHWezkv7fsAmkoPjn75K7ubeo+r7Q5qbkg6a1PW58N8TRXIvkackzaVxAoGBALAq +-qh3U+AHG9dgbrPeyo6KkuCOtX39ks8/mbfCDRZYkbb9V5f5r2tVz3R93IlK/7jyr +-yWimtmde46Lrl33922w+T5OW5qBZllo9GWkUrDn3s5qClcuQjJIdmxYTSfbSCJiK +-NkmE39lHkG5FVRB9f71tgTlWS6ox7TYDYxx83NTtAoGAUJPAkGt4yGAN4Pdebv53 +-bSEpAAULBHntiqDEOu3lVColHuZIucml/gbTpQDruE4ww4wE7dOhY8Q4wEBVYbRI +-vHkSiWpJUvZCuKG8Foh5pm9hU0qb+rbQV7NhLJ02qn1AMGO3F/WKrHPPY8/b9YhQ +-KfvPCYimQwBjVrEnSntLPR0= ++MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDZLSl8LdU54OUA ++T8ctFuKLShJul2IMzaEDkFLoL4agccajgvsRxW+8vbc2Re0y1mVMvfNz7Cg5a7Ke ++iSuFJOrQtvDt+HkU5c706YDmw15mBpDSHapkXr80G/ABFbstWafOfagVW45wv65K ++H4cnpcqwrLhagmC8QG0KfWbf+Z2efOxaGu/dTNA3Cnq/BQGTdlkQ28xbrvd+Ubzg ++cY4Y/hJ7Fw1/IeEhgr/iVJhQIUAklp9B+xqDfWuxIt5mNwWWh/Lfk+UxqE99EhQR ++0YZWyIKfKzbeJLBzDqY2hQzVL6kAvY9cR1WbBItTA0G2F5qZ9B/3EHEFWZMBvobt +++UTEkuBdAgMBAAECggEAF3Eagz7nPyIZVdlGpIVN2r8aEjng6YTglmPjrxBCNdtS ++F6AxvY9UKklIF2Gg4tXlhU0TlDWvedM4Koif2/VKK1Ez3FvvpePQXPs/YKlB7T1U ++MHnnRII9nUBOva88zv5YcJ97nyKM03q9M18H1a29nShnlc1w56EEpBc5HX/yFYMv ++kMYydvB5j0DQkJlkQNFn4yRag0wIIPeyXwwh5l98SMlr40hO10OYTOQPrrgP/ham ++AOZ//DvGo5gF8hGJYoqG4vcYbxRfTqbc2lQ4XRknOT182l9gRum52ahkBY6LKb4r ++IZXPStS6fCAR5S0lcdBb3uN/ap9SUfb9w/Dhj5DZAQKBgQDr06DcsBpoGV2dK9ib ++YL5MxC5JL7G79IBPi3ThRiOSttKXv3oDAFB0AlJvFKwYmVz8SxXqQ2JUA4BfvMGF ++TNrbhukzo0ou5boExnQW/RjLN3fWVq1JM7iLbNU9YYpPCIG5LXrt4ZDOwITeGe8f ++bmZK9zxWxc6BBJtc3mTFS5tm4QKBgQDrwRyEn6oZ9TPbR69fPgWvDqQwKs+6TtYn ++0otMG9UejbSMcyU4sI+bZouoca2CzoNi2qZVIvI9aOygUHQAP7Dyq1KhsvYtzJub ++KEua379WnzBMMjJ56Q/e4aKTq229QvOk+ZEYl6aklZX7xnYetYNZQrp4QzUyOQTG ++gfxgxKi0/QKBgQCy1esAUJ/F366JOS3rLqNBjehX4c5T7ae8KtJ433qskO4E29TI ++H93jC7u9txyHDw5f2QUGgRE5Cuq4L2lGEDFMFvQUD7l69QVrB6ATqt25hhffuB1z ++DMDfIqpXAPgk1Rui9SVq7gqlb4OS9nHLESqLoQ/l8d2XI4o6FACxSZPQoQKBgQCR ++8AvwSUoqIXDFaB22jpVEJYMb0hSfFxhYtGvIZF5MOJowa0L6UcnD//mp/xzSoXYR ++pppaj3R28VGxd7wnP0YRIl7XfAoKleMpbAtJRwKR458pO9WlQ9GwPeq/ENqw0xYx ++5M+d8pqUvYiHv/X00pYJllYKBkiS21sKawLJAFQTHQKBgQCJCwVHxvxkdQ8G0sU2 ++Vtv2W38hWOSg5+cxa+g1W6My2LhX34RkgKzuaUpYMlWGHzILpxIxhPrVLk1ZIjil ++GIP969XJ1BjB/kFtLWdxXG8tH1If3JgzfSHUofPHF3CENoJYEZ1ugEfIPzWPZJDI ++DL5zP8gmBL9ZAOO/J9YacxWYMQ== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIDbjCCAlagAwIBAgIJAMc+8VKBJ/S9MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MjlaFw0yMzA3MTUxNzI4MjlaMEQx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU +-ZXN0IFMvTUlNRSBSU0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +-ggEBALLJBcQPkfJVbCqdfLOZjfXvIxQmsh+wq9EQbYLr3V0k0eA2D6irmyO39/OT +-JLzgC906KJwCxqjhxgsO6W2FoulsLuawQGG/ACKXQU1vmDcRG6l7Uq5N1RXVS4P+ +-LpLZWho1dQEGfWsP1ZwEFzSWfH/ha33Z5BMjr3bmm3tkc9DDY6WntNAMSXKLmo/E +-J6bi5PSDfNtmxaqaawgxdu74rd0SmvOoDW5wpdvFSZk2QzBWzZcKaUvGtFSPwLf/ +-MQ20fXsdYLOeFH8hVxWSAi6SWR6IOwSFta9RC6ZVdHug+H8I9kBuMaqrmZW54dIe +-untusFVkodm+hSRrbxAtaK2rVbkCAwEAAaNjMGEwHQYDVR0OBBYEFMmRUwpjexZb +-i71E8HaIqSTm5bZsMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA8G +-A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IB +-AQAwpIVWQey2u/XoQSMSu0jd0EZvU+lhLaFrDy/AHQeG3yX1+SAOM6f6w+efPvyb +-Op1NPI9UkMPb4PCg9YC7jgYokBkvAcI7J4FcuDKMVhyCD3cljp0ouuKruvEf4FBl +-zyQ9pLqA97TuG8g1hLTl8G90NzTRcmKpmhs18BmCxiqHcTfoIpb3QvPkDX8R7LVt +-9BUGgPY+8ELCgw868TuHh/Cnc67gBtRjBp0sCYVzGZmKsO5f1XdHrAZKYN5mEp0C +-7/OqcDoFqORTquLeycg1At/9GqhDEgxNrqA+YEsPbLGAfsNuXUsXs2ubpGsOZxKt +-Emsny2ah6fU2z7PztrUy/A80 ++MIIDezCCAmOgAwIBAgIUBxh2L3ItsVPuBogDI0WfUX1lFnMwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxM1oYDzIxMjIw ++NTEwMTUzMzEzWjBEMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEdMBsGA1UEAwwUVGVzdCBTL01JTUUgUlNBIFJvb3QwggEiMA0GCSqGSIb3DQEB ++AQUAA4IBDwAwggEKAoIBAQDZLSl8LdU54OUAT8ctFuKLShJul2IMzaEDkFLoL4ag ++ccajgvsRxW+8vbc2Re0y1mVMvfNz7Cg5a7KeiSuFJOrQtvDt+HkU5c706YDmw15m ++BpDSHapkXr80G/ABFbstWafOfagVW45wv65KH4cnpcqwrLhagmC8QG0KfWbf+Z2e ++fOxaGu/dTNA3Cnq/BQGTdlkQ28xbrvd+UbzgcY4Y/hJ7Fw1/IeEhgr/iVJhQIUAk ++lp9B+xqDfWuxIt5mNwWWh/Lfk+UxqE99EhQR0YZWyIKfKzbeJLBzDqY2hQzVL6kA ++vY9cR1WbBItTA0G2F5qZ9B/3EHEFWZMBvobt+UTEkuBdAgMBAAGjYzBhMB0GA1Ud ++DgQWBBQVwRMha+JVX6dqHVcg1s/zqXNkWTAfBgNVHSMEGDAWgBQVwRMha+JVX6dq ++HVcg1s/zqXNkWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkq ++hkiG9w0BAQsFAAOCAQEAvdAmpDPi1Wt7Hk30dXKF7Ug6MUKETi+uoO1Suo9JhNko ++/cpvoi8fbo/dnWVDfHVoItEn644Svver5UJdKJY62DvhilpCtAywYfCpgxkpKoKE ++dnpjnRBSMcbVDImsqvf1YjzFKiOiD7kcVvz4V0NZY91ZWwu3vgaSvcTJQkpWN0a+ ++LWanpVKqigl8nskttnBeiHDHGebxj3hawlIdtVlkbQwLLwlVkX99x1F73uS33IzB ++Y6+ZJ2is7mD839B8fOVd9pvPvBBgahIrw5tzJ/Q+gITuVQd9E6RVXh10/Aw+i/8S ++7tHpEUgP3hBk1P+wRQBWDxbHB28lE+41jvh3JObQWQ== + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa1.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa1.pem +index d0d0b9e6..d32d8890 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa1.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa1.pem +@@ -1,49 +1,49 @@ + -----BEGIN PRIVATE KEY----- +-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDXr9uzB/20QXKC +-xhkfNnJvl2xl1hzdOcrQmAqo+AAAcA/D49ImuJDVQRaK2bcj54XB26i1kXuOrxID +-3/etUb8yudfx8OAVwh8G0xVA4zhr8uXW85W2tBr4v0Lt+W6lSd6Hmfrk4GmE9LTU +-/vzl9HUPW6SZShN1G0nY6oeUXvLi0vasEUKv3a51T6JFYg4c7qt5RCk/w8kwrQ0D +-orQwCdkOPEIiC4b+nPStF12SVm5bx8rbYzioxuY/PdSebvt0APeqgRxSpCxqYnHs +-CoNeHzSrGXcP0COzFeUOz2tdrhmH09JLbGZs4nbojPxMkjpJSv3/ekDG2CHYxXSH +-XxpJstxZAgMBAAECggEASY4xsJaTEPwY3zxLqPdag2/yibBBW7ivz/9p80HQTlXp +-KnbxXj8nNXLjCytAZ8A3P2t316PrrTdLP4ML5lGwkM4MNPhek00GY79syhozTa0i +-cPHVJt+5Kwee/aVI9JmCiGAczh0yHyOM3+6ttIZvvXMVaSl4BUHvJ0ikQBc5YdzL +-s6VM2gCOR6K6n+39QHDI/T7WwO9FFSNnpWFOCHwAWtyBMlleVj+xeZX8OZ/aT+35 +-27yjsGNBftWKku29VDineiQC+o+fZGJs6w4JZHoBSP8TfxP8fRCFVNA281G78Xak +-cEnKXwZ54bpoSa3ThKl+56J6NHkkfRGb8Rgt/ipJYQKBgQD5DKb82mLw85iReqsT +-8bkp408nPOBGz7KYnQsZqAVNGfehM02+dcN5z+w0jOj6GMPLPg5whlEo/O+rt9ze +-j6c2+8/+B4Bt5oqCKoOCIndH68jl65+oUxFkcHYxa3zYKGC9Uvb+x2BtBmYgvDRG +-ew6I2Q3Zyd2ThZhJygUZpsjsbQKBgQDdtNiGTkgWOm+WuqBI1LT5cQfoPfgI7/da +-ZA+37NBUQRe0cM7ddEcNqx7E3uUa1JJOoOYv65VyGI33Ul+evI8h5WE5bupcCEFk +-LolzbMc4YQUlsySY9eUXM8jQtfVtaWhuQaABt97l+9oADkrhA+YNdEu2yiz3T6W+ +-msI5AnvkHQKBgDEjuPMdF/aY6dqSjJzjzfgg3KZOUaZHJuML4XvPdjRPUlfhKo7Q +-55/qUZ3Qy8tFBaTderXjGrJurc+A+LiFOaYUq2ZhDosguOWUA9yydjyfnkUXZ6or +-sbvSoM+BeOGhnezdKNT+e90nLRF6cQoTD7war6vwM6L+8hxlGvqDuRNFAoGAD4K8 +-d0D4yB1Uez4ZQp8m/iCLRhM3zCBFtNw1QU/fD1Xye5w8zL96zRkAsRNLAgKHLdsR +-355iuTXAkOIBcJCOjveGQsdgvAmT0Zdz5FBi663V91o+IDlryqDD1t40CnCKbtRG +-hng/ruVczg4x7OYh7SUKuwIP/UlkNh6LogNreX0CgYBQF9troLex6X94VTi1V5hu +-iCwzDT6AJj63cS3VRO2ait3ZiLdpKdSNNW2WrlZs8FZr/mVutGEcWho8BugGMWST +-1iZkYwly9Xfjnpd0I00ZIlr2/B3+ZsK8w5cOW5Lpb7frol6+BkDnBjbNZI5kQndn +-zQpuMJliRlrq/5JkIbH6SA== ++MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDax3T7alefZcbm ++CcdN0kEoBLwV8H25vre43RYjuPo64TBjeKUy27ayC1TXydF1eYm3HPrFYfkS0fZ6 ++YK0xvwyxiQnesvcfnVe2fpXFPsl5RQvu1JKM7rJAuLC+YTRLez07IHhQnHQ25ZkR +++B4SL5mIhuOSJ9yyFJYJQ3Kdw/aX/jtnWVR8p3FyghJptWIm90ufW4xWFY0yNSW1 ++KmkZuOWF7VPh5RC1C7woB/RHhyD2gOP7tF+eDJ/QbX4iki4gPRFHuNrSV8ZpvDkI ++qqyF5BW8tyJneDkoWW8IuEpmNIzfbOCHvI6y7roeAmRrwH4/o5WxaEIsnQ/3pNvj ++n6+vA+nfAgMBAAECggEAFR5MHQQYCYjDXoDoI7YdgwA+AFIoGLjKYZu5yjX4tZv3 ++gJ/si7sTaMlY5cGTU1HUPirxIVeCjv4Eha31BJ3KsGJ9jj6Gm0nOuzd/O+ctKeRv ++2/HaDvpFlk4dsCrlkjmxteuS9u5l9hygniWYutcBwjY0cRnMScZcm0VO+DVVMDj0 ++9yNrFzhlmqV+ckawjK/J91r0uvnCVIsGA6akhlc5K0gwvFb/CC1WuceEeGx/38k3 ++4OuiHtLyJfIlgyGD8C3QfJlMOBHeQ/DCo6GMqrOAad/chtcO7JklcJ+k2qylP2gu ++e25NJCQVh+L32b9WrH3quH6fbLIg8a8MmUWl6te3FQKBgQDddu0Dp8R8fe2WnAE5 ++oXdASAf2BpthRNqUdYpkkO7gOV0MXCKIEiGZ+WuWEYmNlsXZCJRABprqLw9O/5Td ++2q+rCbdG9mSW2x82t/Ia4zd3r0RSHZyKbtOLtgmWfQkwVHy+rED8Juie5bNzHbjS ++1mYtFP2KDQ5yZA95yFg8ZtXOawKBgQD85VOPnfXGOJ783JHepAn4J2x1Edi+ZDQ+ ++Ml9g2LwetI46dQ0bF6V8RtcyWp0+6+ydX5U4JKhERFDivolD7Z1KFmlNLPs0cqSX ++5g5kzTD+R+zpr9FRragYKyLdHsLP0ur75Rh5FQkUl2DmeKCMvMKAkio0cduVpVXT ++SvWUBtkHXQKBgBy4VoZZ1GZcolocwx/pK6DfdoDWXIIhvsLv91GRZhkX91QqAqRo ++zYi9StF8Vr1Q5zl9HlSrRp3GGpMhG/olaRCiQu1l+KeDpSmgczo/aysPRKntgyaE ++ttRweA/XCUEGQ+MqTYcluJcarMnp+dUFztxb04F6rfvxs/wUGjVDFMkfAoGBAK+F ++wx9UtPZk6gP6Wsu58qlnQ2Flh5dtGM1qTMR86OQu0OBFyVjaaqL8z/NE7Qp02H7J ++jlmvJ5JqD/Gv6Llau+Zl86P66kcWoqJCrA7OU4jJBueSfadA7gAIQGRUK0Xuz+UQ ++tpGjRfAiuMB9TIEhqaVuzRglRhBw9kZ2KkgZEJyJAoGBANrEpEwOhCv8Vt1Yiw6o ++co96wYj+0LARJXw6rIfEuLkthBRRoHqQMKqwIGMrwjHlHXPnQmajONzIJd+u+OS4 ++psCGetAIGegd3xNVpK2uZv9QBWBpQbuofOh/c2Ctmm2phL2sVwCZ0qwIeXuBwJEc ++NOlOojKDO+dELErpShJgFIaU + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBAMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBSU0EgIzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +-AoIBAQDXr9uzB/20QXKCxhkfNnJvl2xl1hzdOcrQmAqo+AAAcA/D49ImuJDVQRaK +-2bcj54XB26i1kXuOrxID3/etUb8yudfx8OAVwh8G0xVA4zhr8uXW85W2tBr4v0Lt +-+W6lSd6Hmfrk4GmE9LTU/vzl9HUPW6SZShN1G0nY6oeUXvLi0vasEUKv3a51T6JF +-Yg4c7qt5RCk/w8kwrQ0DorQwCdkOPEIiC4b+nPStF12SVm5bx8rbYzioxuY/PdSe +-bvt0APeqgRxSpCxqYnHsCoNeHzSrGXcP0COzFeUOz2tdrhmH09JLbGZs4nbojPxM +-kjpJSv3/ekDG2CHYxXSHXxpJstxZAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD +-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBTmjc+lrTQuYx/VBOBGjMvufajvhDAfBgNV +-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA +-dr2IRXcFtlF16kKWs1VTaFIHHNQrfSVHBkhKblPX3f/0s/i3eXgwKUu7Hnb6T3/o +-E8L+e4ioQNhahTLt9ruJNHWA/QDwOfkqM3tshCs2xOD1Cpy7Bd3Dn0YBrHKyNXRK +-WelGp+HetSXJGW4IZJP7iES7Um0DGktLabhZbe25EnthRDBjNnaAmcofHECWESZp +-lEHczGZfS9tRbzOCofxvgLbF64H7wYSyjAe6R8aain0VRbIusiD4tCHX/lOMh9xT +-GNBW8zTL+tV9H1unjPMORLnT0YQ3oAyEND0jCu0ACA1qGl+rzxhF6bQcTUNEbRMu +-9Hjq6s316fk4Ne0EUF3PbA== ++MIIDeTCCAmGgAwIBAgIUM6U1Peo3wzfAJIrzINejJJfmRzkwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxM1oYDzIxMjIw ++NTA5MTUzMzEzWjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgUlNBICMxMIIBIjANBgkqhkiG9w0B ++AQEFAAOCAQ8AMIIBCgKCAQEA2sd0+2pXn2XG5gnHTdJBKAS8FfB9ub63uN0WI7j6 ++OuEwY3ilMtu2sgtU18nRdXmJtxz6xWH5EtH2emCtMb8MsYkJ3rL3H51Xtn6VxT7J ++eUUL7tSSjO6yQLiwvmE0S3s9OyB4UJx0NuWZEfgeEi+ZiIbjkifcshSWCUNyncP2 ++l/47Z1lUfKdxcoISabViJvdLn1uMVhWNMjUltSppGbjlhe1T4eUQtQu8KAf0R4cg ++9oDj+7Rfngyf0G1+IpIuID0RR7ja0lfGabw5CKqsheQVvLciZ3g5KFlvCLhKZjSM ++32zgh7yOsu66HgJka8B+P6OVsWhCLJ0P96Tb45+vrwPp3wIDAQABo2AwXjAMBgNV ++HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUHw4Us7FXwgLtZ1JB ++MOAHSkNYfEkwHwYDVR0jBBgwFoAUFcETIWviVV+nah1XINbP86lzZFkwDQYJKoZI ++hvcNAQELBQADggEBAAMAXEjTNo7evn6BvfEaG2q21q9xfFear/M0zxc5xcTj+WP+ ++BKrlxXg5RlVFyvmzGhwZBERsDMJYa54aw8scDJsy/0zPdWST39dNev7xH13pP8nF ++QF4MGPKIqBzX8iDCqhz70p1w2ndLjz1dvsAqn6z9/Sh3T2kj6DfZY3jA49pMEim1 ++vYd4lWa5AezU3+cLtBbo2c2iyG2W7SFpnNTjLX823f9rbVPnUb93ZI/tDXDIf5hL ++0hocZs+MWdC7Ly1Ru4PXa6+DeOM0z673me/Q27e24OBbG2eq5g7eW5euxJinGkpI ++XGGKTKrBCPxSdTtwSNHU9HsggT8a0wXL2QocZ3w= + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa2.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa2.pem +index 2f17cb29..a7a21fc8 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa2.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa2.pem +@@ -1,49 +1,49 @@ + -----BEGIN PRIVATE KEY----- +-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDcYC4tS2Uvn1Z2 +-iDgtfkJA5tAqgbN6X4yK02RtVH5xekV9+6+eTt/9S+iFAzAnwqR/UB1R67ETrsWq +-V8u9xLg5fHIwIkmu9/6P31UU9cghO7J1lcrhHvooHaFpcXepPWQacpuBq2VvcKRD +-lDfVmdM5z6eS3dSZPTOMMP/xk4nhZB8mcw27qiccPieS0PZ9EZB63T1gmwaK1Rd5 +-U94Pl0+zpDqhViuXmBfiIDWjjz0BzHnHSz5Rg4S3oXF1NcojhptIWyI0r7dgn5J3 +-NxC4kgKdjzysxo6iWd0nLgz7h0jUdj79EOis4fg9G4f0EFWyQf7iDxGaA93Y9ePB +-Jv5iFZVZAgMBAAECggEBAILIPX856EHb0KclbhlpfY4grFcdg9LS04grrcTISQW1 +-J3p9nBpZ+snKe6I8Yx6lf5PiipPsSLlCliHiWpIzJZVQCkAQiSPiHttpEYgP2IYI +-dH8dtznkdVbLRthZs0bnnPmpHCpW+iqpcYJ9eqkz0cvUNUGOjjWmwWmoRqwp/8CW +-3S1qbkQiCh0Mk2fQeGar76R06kXQ9MKDEj14zyS3rJX+cokjEoMSlH8Sbmdh2mJz +-XlNZcvqmeGJZwQWgbVVHOMUuZaKJiFa+lqvOdppbqSx0AsCRq6vjmjEYQEoOefYK +-3IJM9IvqW5UNx0Cy4kQdjhZFFwMO/ALD3QyF21iP4gECgYEA+isQiaWdaY4UYxwK +-Dg+pnSCKD7UGZUaCUIv9ds3CbntMOONFe0FxPsgcc4jRYQYj1rpQiFB8F11+qXGa +-P/IHcnjr2+mTrNY4I9Bt1Lg+pHSS8QCgzeueFybYMLaSsXUo7tGwpvw6UUb6/YWI +-LNCzZbrCLg1KZjGODhhxtvN45ZkCgYEA4YNSe+GMZlxgsvxbLs86WOm6DzJUPvxN +-bWmni0+Oe0cbevgGEUjDVc895uMFnpvlgO49/C0AYJ+VVbStjIMgAeMnWj6OZoSX +-q49rI8KmKUxKgORZiiaMqGWQ7Rxv68+4S8WANsjFxoUrE6dNV3uYDIUsiSLbZeI8 +-38KVTcLohcECgYEAiOdyWHGq0G4xl/9rPUCzCMsa4velNV09yYiiwBZgVgfhsawm +-hQpOSBZJA60XMGqkyEkT81VgY4UF4QLLcD0qeCnWoXWVHFvrQyY4RNZDacpl87/t +-QGO2E2NtolL3umesa+2TJ/8Whw46Iu2llSjtVDm9NGiPk5eA7xPPf1iEi9kCgYAb +-0EmVE91wJoaarLtGS7LDkpgrFacEWbPnAbfzW62UENIX2Y1OBm5pH/Vfi7J+vHWS +-8E9e0eIRCL2vY2hgQy/oa67H151SkZnvQ/IP6Ar8Xvd1bDSK8HQ6tMQqKm63Y9g0 +-KDjHCP4znOsSMnk8h/bZ3HcAtvbeWwftBR/LBnYNQQKBgA1leIXLLHRoX0VtS/7e +-y7Xmn7gepj+gDbSuCs5wGtgw0RB/1z/S3QoS2TCbZzKPBo20+ivoRP7gcuFhduFR +-hT8V87esr/QzLVpjLedQDW8Xb7GiO3BsU/gVC9VcngenbL7JObl3NgvdreIYo6+n +-yrLyf+8hjm6H6zkjqiOkHAl+ ++MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDkoMi4sqj2mN8j ++SaFAibXEfeYYrzBHIdCm/uaXWit81fXOSFVw1rbeAppxz7bOcSEN50lpdP2UX3/b ++FYFD3exHXjvch9NPNgQaNkCqTNTuYa2L9wrpltXnon7tH3W/zZfF+/qpUSu1f6rk ++GyxjVXxLwjIawCX0rbLcdFCVVy+EyvQkvSxXjafrDMzshWzPDbtjUv3SH6avqrPn ++4NX0fv3BdBwTfDLAw/m8nN+9B9Mg0V7UNM1IJY/Vo5pLhv+MrEf8SnAS+1Wt43rT ++3PY9iMZMMWUswdgmPY0yCN95ggwNrSMGV60yvEDxINWuJoR8s0lybDdFa+AB5v4T ++hqKpspFNAgMBAAECggEAZmWu0K5QJ7Y7Rlo9ayLicsFyk36vUESQZ6MF0ybzEEPi ++BkR2ZAX+vDuNQckm1pprlAcRZbactl35bT3Z+fQE1cgaZoC8/x6xwq2m0796pNPB ++v0zjqdBBOLAaSgjLm56wyd88GqZ8vZsTBnw3KrxIYcP13e5OcaJ0V/GOf/yfD0lg ++Tq9i7V5Iq++Fpo2KvJA8FMgqcfhvhdo40rRykoBfzEZpBk4Ia/Yijsbx5sE15pFZ ++DfmsMbD+vViuM8IavHo61mBNyYeydwlgIMqUgP/6xbYUov/XSUojrLG+IQuvDx9D ++xzTHGM+IBJxQZMza/mDVcjUAcDEjWt/Mve8ibTQCbwKBgQDyaiGsURtlf/8xmmvT ++RQQFFFsJ8SXHNYmnceNULIjfDxpLk1yC4kBNUD+liAJscoVlOcByHmXQRtnY1PHq ++AwyrwplGd82773mtriDVFSjhD+GB7I0Hv2j+uiFZury0jR/6/AsWKCtTqd0opyuB ++8rGZjguiwZIjeyxd8mL1dncUHwKBgQDxcNxHUvIeDBvAmtK65xWUuLcqtK9BblBH ++YVA7p93RqX4E+w3J0OCvQRQ3r1GCMMzFEO0oOvNfMucU4rbQmx1pbzF8aQU+8iEW ++kYpaWUbPUQ2hmBblhjGYHsigt/BrzaW0QveVIWcGiyVVX9wiCzJH5moJlCRK2oHR ++B36hdlmNEwKBgQCSlWSpOx4y4RQiHXtn9Eq6+5UVTPGIJTKIwxAwnQFiyFIhMwl0 ++x3UUixsBcF3uz80j6akaGJF+QOmH+TQTSibGUdS3TMhmBSfxwuJtlu7yMNUu6Chb ++b/4AUfLKvGVRVCjrbq8Rhda1L3jhFTz0xhlofgFBOIWy2M96O5BlV24oBwKBgQDs ++cf93ZfawkGEZVUXsPeQ3mlHe48YCCPtbfCSr13B3JErCq+5L52AyoUQgaHQlUI8o ++qrPmQx0V7O662G/6iP3bxEYtNVgq1cqrpGpeorGi1BjKWPyLWMj21abbJmev21xc ++1XxLMsQHd3tfSZp2SIq8OR09NjP4jla1k2Ziz1lRuwKBgQCUJXjhW4dPoOzC7DJK ++u4PsxcKkJDwwtfNudVDaHcbvvaHELTAkE2639vawH0TRwP6TDwmlbTQJP4EW+/0q ++13VcNXVAZSruA9dvxlh4vNUH3PzTDdFIJzGVbYbV9p5t++EQ7gRLuLZqs99BOzM9 ++k6W9F60mEFz1Owh+lQv7WfSIVA== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBBMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBSU0EgIzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +-AoIBAQDcYC4tS2Uvn1Z2iDgtfkJA5tAqgbN6X4yK02RtVH5xekV9+6+eTt/9S+iF +-AzAnwqR/UB1R67ETrsWqV8u9xLg5fHIwIkmu9/6P31UU9cghO7J1lcrhHvooHaFp +-cXepPWQacpuBq2VvcKRDlDfVmdM5z6eS3dSZPTOMMP/xk4nhZB8mcw27qiccPieS +-0PZ9EZB63T1gmwaK1Rd5U94Pl0+zpDqhViuXmBfiIDWjjz0BzHnHSz5Rg4S3oXF1 +-NcojhptIWyI0r7dgn5J3NxC4kgKdjzysxo6iWd0nLgz7h0jUdj79EOis4fg9G4f0 +-EFWyQf7iDxGaA93Y9ePBJv5iFZVZAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD +-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBT0arpyYMHXDPVL7MvzE+lx71L7sjAfBgNV +-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA +-I8nM42am3aImkZyrw8iGkaGhKyi/dfajSWx6B9izBUh+3FleBnUxxOA+mn7M8C47 +-Ne18iaaWK8vEux9KYTIY8BzXQZL1AuZ896cXEc6bGKsME37JSsocfuB5BIGWlYLv +-/ON5/SJ0iVFj4fAp8z7Vn5qxRJj9BhZDxaO1Raa6cz6pm0imJy9v8y01TI6HsK8c +-XJQLs7/U4Qb91K+IDNX/lgW3hzWjifNpIpT5JyY3DUgbkD595LFV5DDMZd0UOqcv +-6cyN42zkX8a0TWr3i5wu7pw4k1oD19RbUyljyleEp0DBauIct4GARdBGgi5y1H2i +-NzYzLAPBkHCMY0Is3KKIBw== ++MIIDeTCCAmGgAwIBAgIUTMQXiTcI/rpzqO91NyFWpjLE3KkwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxM1oYDzIxMjIw ++NTA5MTUzMzEzWjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgUlNBICMyMIIBIjANBgkqhkiG9w0B ++AQEFAAOCAQ8AMIIBCgKCAQEA5KDIuLKo9pjfI0mhQIm1xH3mGK8wRyHQpv7ml1or ++fNX1zkhVcNa23gKacc+2znEhDedJaXT9lF9/2xWBQ93sR1473IfTTzYEGjZAqkzU ++7mGti/cK6ZbV56J+7R91v82Xxfv6qVErtX+q5BssY1V8S8IyGsAl9K2y3HRQlVcv ++hMr0JL0sV42n6wzM7IVszw27Y1L90h+mr6qz5+DV9H79wXQcE3wywMP5vJzfvQfT ++INFe1DTNSCWP1aOaS4b/jKxH/EpwEvtVreN609z2PYjGTDFlLMHYJj2NMgjfeYIM ++Da0jBletMrxA8SDVriaEfLNJcmw3RWvgAeb+E4aiqbKRTQIDAQABo2AwXjAMBgNV ++HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUSJ0v3SKahe6eKssR ++rBvYLBprFTgwHwYDVR0jBBgwFoAUFcETIWviVV+nah1XINbP86lzZFkwDQYJKoZI ++hvcNAQELBQADggEBAKoyszyZ3DfCOIVzeJrnScXuMvRkVqO5aGmgZxtY9r6gPk8v ++gXaEFXDKqRbGqEnuwEjpew+SVZO8nrVpdIP7fydpufy7Cu91Ev4YL1ui5Vc66+IK ++7dXV7eZYcH/dDJBPZddHx9vGhcr0w8B1W9nldM3aQE/RQjOmMRDc7/Hnk0f0RzJp ++LA0adW3ry27z2s4qeCwkV9DNSh1KoGfcLwydBiXmJ1XINMFH/scD4pk9UeJpUL+5 ++zvTaDzUmzLsI1gH3j/rlzJuNJ7EMfggKlfQdit9Qn6+6Gjk6T5jkZfzcq3LszuEA ++EFtkxWyBmmEgh4EmvZGAyrUvne1hIIksKe3iJ+E= + -----END CERTIFICATE----- +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa3.pem b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa3.pem +index 14c27f64..980d3af3 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa3.pem ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa3.pem +@@ -1,49 +1,49 @@ + -----BEGIN PRIVATE KEY----- +-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyK+BTAOJKJjji +-OhY60NeZjzGGZxEBfCm62n0mwkzusW/V/e63uwj6uOVCFoVBz5doMf3M6QIS2jL3 +-Aw6Qs5+vcuLA0gHrqIwjYQz1UZ5ETLKLKbQw6YOIVfsFSTxytUVpfcByrubWiLKX +-63theG1/IVokDK/9/k52Kyt+wcCjuRb7AJQFj2OLDRuWm/gavozkK103gQ+dUq4H +-XamZMtTq1EhQOfc0IUeCOEL6xz4jzlHHfzLdkvb7Enhav2sXDfOmZp/DYf9IqS7l +-vFkkINPVbYFBTexaPZlFwmpGRjkmoyH/w+Jlcpzs+w6p1diWRpaSn62bbkRN49j6 +-L2dVb+DfAgMBAAECggEAciwDl6zdVT6g/PbT/+SMA+7qgYHSN+1koEQaJpgjzGEP +-lUUfj8TewCtzXaIoyj9IepBuXryBg6snNXpT/w3bqgYon/7zFBvxkUpDj4A5tvKf +-BuY2fZFlpBvUu1Ju1eKrFCptBBBoA9mc+BUB/ze4ktrAdJFcxZoMlVScjqGB3GdR +-OHw2x9BdWGCJBhiu9VHhAAb/LVWi6xgDumYSWZwN2yovg+7J91t5bsENeBRHycK+ +-i5dNFh1umIK9N0SH6bpHPnLHrCRchrQ6ZRRxL4ZBKA9jFRDeI7OOsJuCvhGyJ1se +-snsLjr/Ahg00aiHCcC1SPQ6pmXAVBCG7hf4AX82V4QKBgQDaFDE+Fcpv84mFo4s9 +-wn4CZ8ymoNIaf5zPl/gpH7MGots4NT5+Ns+6zzJQ6TEpDjTPx+vDaabP7QGXwVZn +-8NAHYvCQK37b+u9HrOt256YYRDOmnJFSbsJdmqzMEzpTNmQ8GuI37cZCS9CmSMv+ +-ab/plcwuv0cJRSC83NN2AFyu1QKBgQDRJzKIBQlpprF9rA0D5ZjLVW4OH18A0Mmm +-oanw7qVutBaM4taFN4M851WnNIROyYIlkk2fNgW57Y4M8LER4zLrjU5HY4lB0BMX +-LQWDbyz4Y7L4lVnnEKfQxWFt9avNZwiCxCxEKy/n/icmVCzc91j9uwKcupdzrN6E +-yzPd1s5y4wKBgQCkJvzmAdsOp9/Fg1RFWcgmIWHvrzBXl+U+ceLveZf1j9K5nYJ7 +-2OBGer4iH1XM1I+2M4No5XcWHg3L4FEdDixY0wXHT6Y/CcThS+015Kqmq3fBmyrc +-RNjzQoF9X5/QkSmkAIx1kvpgXtcgw70htRIrToGSUpKzDKDW6NYXhbA+PQKBgDJK +-KH5IJ8E9kYPUMLT1Kc4KVpISvPcnPLVSPdhuqVx69MkfadFSTb4BKbkwiXegQCjk +-isFzbeEM25EE9q6EYKP+sAm+RyyJ6W0zKBY4TynSXyAiWSGUAaXTL+AOqCaVVZiL +-rtEdSUGQ/LzclIT0/HLV2oTw4KWxtTdc3LXEhpNdAoGBAM3LckiHENqtoeK2gVNw +-IPeEuruEqoN4n+XltbEEv6Ymhxrs6T6HSKsEsLhqsUiIvIzH43KMm45SNYTn5eZh +-yzYMXLmervN7c1jJe2Y2MYv6hE+Ypj1xGW4w7s8WNKmVzLv97beisD9AZrS7sXfF +-RvOAi5wVkYylDxV4238MAZIq ++MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQD5A/t3norj/167 ++toKG1Ygtg3G+pZ4Nwl5a9flnm8JdSMW5TEEP1TSvDVIEuAVi7xqoAn6heypoaMkB ++GJ+AoSo9R7umdhhq2vnmWFNsdH6oDzynVXixyURo81YrN3sn9Xd55ivTiSpZXldi ++ECr2T0BYvOw0h497bPs6gY9LqgrBHNYVF3lFhdOmYWv+2qSdti+1gV3t24pv1CrK ++2AdX5Epdd5jR+eNnt+suZqoPC0hTcNjszJLcfDYFXHva9BcE0DfrgcYSmoSBU53M ++jt63TClK6ZoVcPJ7vXjFRHncvs1/d+nc9BdL9FsGI1ezspSwcJHqex2wgo76yDrq ++DE4s23rPAgMBAAECggEAEDi+VWD5VUpjD5zWOoPQiRDGBJBhtMAKkl6okxEmXvWb ++Xz3STFnjHgA1JFHW3bRU9BHI9k8vSHmnlnkfKb3V/ZX5IHNcKCHb/x9NBak+QLVQ ++0zLtfE9vxiTC0B/oac+MPaiD4hYFQ81pFwK6VS0Poi8ZCBJtOkRqfUvsyV8zZrgh ++/6cs4mwOVyZPFRgF9eWXYv7PJz8pNRizhII0iv9H/r2I3DzsZLPCg7c29mP+I/SG ++A7Pl82UXjtOc0KurGY2M5VheZjxJT/k/FLMkWY2GS5n6dfcyzsVSKb25HoeuvQsI ++vs1mKs+Onbobdc17hCcKVJzbi3DwXs5XDhrEzfHccQKBgQD88uBxVCRV31PsCN6I ++pKxQDGgz+1BqPqe7KMRiZI7HgDUK0eCM3/oG089/jsBtJcSxnScLSVNBjQ+xGiFi ++YCD4icQoJSzpqJyR6gDq5lTHASAe+9LWRW771MrtyACQWNXowYEyu8AjekrZkCUS ++wIKVpw57oWykzIoS7ixZsJ8gxwKBgQD8BPWqJEsLiQvOlS5E/g88eV1KTpxm9Xs+ ++BbwsDXZ7m4Iw5lYaUu5CwBB/2jkGGRl8Q/EfAdUT7gXv3t6x5b1qMXaIczmRGYto ++NuI3AH2MPxAa7lg5TgBgie1r7PKwyPMfG3CtDx6n8W5sexgJpbIy5u7E+U6d8s1o ++c7EcsefduQKBgCkHJAx9v18GWFBip+W2ABUDzisQSlzRSNd8p03mTZpiWzgkDq4K ++7j0JQhDIkMGjbKH6gYi9Hfn17WOmf1+7g92MSvrP/NbxeGPadsejEIEu14zu/6Wt ++oXDLdRbYZ+8B2cBlEpWuCl42yck8Lic6fnPTou++oSah3otvglYR5d2lAoGACd8L ++3FE1m0sP6lSPjmZBJIZAcDOqDqJY5HIHD9arKGZL8CxlfPx4lqa9PrTGfQWoqORk ++YmmI9hHhq6aYJHGyPKGZWfjhbVyJyFg1/h+Hy2GA+P0S+ZOjkiR050BNtTz5wOMr ++Q6wO8FcVkywzIdWaqEHBYne9a5RiFVBKxKv3QAkCgYBxmCBKajFkMVb4Uc55WqJs ++Add0mctGgmZ1l5vq81eWe3wjM8wgfJgaD3Q3gwx2ABUX/R+OsVWSh4o5ZR86sYoz ++TviknBHF8GeDLjpT49+04fEaz336J2JOptF9zIpz7ZK1nrOEjzaZGtumReVjUP7X ++fNcb5iDYqZRzD8ixBbLxUw== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- +-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBCMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv +-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx +-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU +-ZXN0IFMvTUlNRSBFRSBSU0EgIzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +-AoIBAQCyK+BTAOJKJjjiOhY60NeZjzGGZxEBfCm62n0mwkzusW/V/e63uwj6uOVC +-FoVBz5doMf3M6QIS2jL3Aw6Qs5+vcuLA0gHrqIwjYQz1UZ5ETLKLKbQw6YOIVfsF +-STxytUVpfcByrubWiLKX63theG1/IVokDK/9/k52Kyt+wcCjuRb7AJQFj2OLDRuW +-m/gavozkK103gQ+dUq4HXamZMtTq1EhQOfc0IUeCOEL6xz4jzlHHfzLdkvb7Enha +-v2sXDfOmZp/DYf9IqS7lvFkkINPVbYFBTexaPZlFwmpGRjkmoyH/w+Jlcpzs+w6p +-1diWRpaSn62bbkRN49j6L2dVb+DfAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD +-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBQ6CkW5sa6HrBsWvuPOvMjyL5AnsDAfBgNV +-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA +-JhcrD7AKafVzlncA3cZ6epAruj1xwcfiE+EbuAaeWEGjoSltmevcjgoIxvijRVcp +-sCbNmHJZ/siQlqzWjjf3yoERvLDqngJZZpQeocMIbLRQf4wgLAuiBcvT52wTE+sa +-VexeETDy5J1OW3wE4A3rkdBp6hLaymlijFNnd5z/bP6w3AcIMWm45yPm0skM8RVr +-O3UstEFYD/iy+p+Y/YZDoxYQSW5Vl+NkpGmc5bzet8gQz4JeXtH3z5zUGoDM4XK7 +-tXP3yUi2eecCbyjh/wgaQiVdylr1Kv3mxXcTl+cFO22asDkh0R/y72nTCu5fSILY +-CscFo2Z2pYROGtZDmYqhRw== ++MIIDeTCCAmGgAwIBAgIUIDyc//j/LoNDesZTGbPBoVarv4EwDQYJKoZIhvcNAQEL ++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV ++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MCAXDTIyMDYwMjE1MzMxM1oYDzIxMjIw ++NTA5MTUzMzEzWjBFMQswCQYDVQQGEwJVSzEWMBQGA1UECgwNT3BlblNTTCBHcm91 ++cDEeMBwGA1UEAwwVVGVzdCBTL01JTUUgRUUgUlNBICMzMIIBIjANBgkqhkiG9w0B ++AQEFAAOCAQ8AMIIBCgKCAQEA+QP7d56K4/9eu7aChtWILYNxvqWeDcJeWvX5Z5vC ++XUjFuUxBD9U0rw1SBLgFYu8aqAJ+oXsqaGjJARifgKEqPUe7pnYYatr55lhTbHR+ ++qA88p1V4sclEaPNWKzd7J/V3eeYr04kqWV5XYhAq9k9AWLzsNIePe2z7OoGPS6oK ++wRzWFRd5RYXTpmFr/tqknbYvtYFd7duKb9QqytgHV+RKXXeY0fnjZ7frLmaqDwtI ++U3DY7MyS3Hw2BVx72vQXBNA364HGEpqEgVOdzI7et0wpSumaFXDye714xUR53L7N ++f3fp3PQXS/RbBiNXs7KUsHCR6nsdsIKO+sg66gxOLNt6zwIDAQABo2AwXjAMBgNV ++HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUN9pGq/UFS3o50rTi ++V+AYgAk+3R4wHwYDVR0jBBgwFoAUFcETIWviVV+nah1XINbP86lzZFkwDQYJKoZI ++hvcNAQELBQADggEBAGcOh380/6aJqMpYBssuf2CB3DX/hGKdvEF7fF8iNSfl5HHq ++112kHl3MhbL9Th/safJq9sLDJqjXRNdVCUJJbU4YI2P2gsi04paC0qxWxMLtzQLd ++CE7ki2xH94Fuu/dThbpzZBABROO1RrdI24GDGt9t4Gf0WVkobmT/zNlwGppKTIB2 ++iV/Ug30iKr/C49UzwUIa+XXXujkjPTmGSnrKwVQNxQh81rb+iTL7GEnNuqDsatHW ++ZyLS2SaVdG5tMqDkITPMDGjehUzJcAbVc8Bv4m8Ukuov3uDj2Doc6MxlvrVkV0AE ++BcSCb/bWQJJ/X4LQZlx9cMk4NINxV9UeFPZOefg= + -----END CERTIFICATE----- +-- +2.33.0 + diff --git a/0043-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch b/0043-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch new file mode 100644 index 0000000000000000000000000000000000000000..22a62711ca5a69e35aabcc31b100054b80b87c2d --- /dev/null +++ b/0043-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch @@ -0,0 +1,60 @@ +From 6b25764750b0e484d3fc09f27a75ff2428c46cd6 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Fri, 21 Jul 2023 11:39:41 +0200 +Subject: [PATCH 09/11] DH_check(): Do not try checking q properties if it is + obviously invalid + +If |q| >= |p| then the q value is obviously wrong as q +is supposed to be a prime divisor of p-1. + +We check if p is overly large so this added test implies that +q is not large either when performing subsequent tests using that +q value. + +Otherwise if it is too large these additional checks of the q value +such as the primality test can then trigger DoS by doing overly long +computations. + +Fixes CVE-2023-3817 + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell + +reference: https://github.com/openssl/openssl/pull/21551 +Signed-off-by: yexiao +--- + .../Library/OpensslLib/openssl/crypto/dh/dh_check.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +index e5f9dd50..28543412 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +@@ -97,7 +97,7 @@ int DH_check_ex(const DH *dh) + + int DH_check(const DH *dh, int *ret) + { +- int ok = 0, r; ++ int ok = 0, r, q_good = 0; + BN_CTX *ctx = NULL; + BIGNUM *t1 = NULL, *t2 = NULL; + +@@ -119,7 +119,14 @@ int DH_check(const DH *dh, int *ret) + if (t2 == NULL) + goto err; + +- if (dh->q) { ++ if (dh->q != NULL) { ++ if (BN_ucmp(dh->p, dh->q) > 0) ++ q_good = 1; ++ else ++ *ret |= DH_CHECK_INVALID_Q_VALUE; ++ } ++ ++ if (q_good) { + if (BN_cmp(dh->g, BN_value_one()) <= 0) + *ret |= DH_NOT_SUITABLE_GENERATOR; + else if (BN_cmp(dh->g, dh->p) >= 0) +-- +2.33.0 + diff --git a/0044-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch b/0044-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..08f1c9ff85a779f5d68b87a121c9a72a85b71311 --- /dev/null +++ b/0044-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch @@ -0,0 +1,50 @@ +From 105313716572d888f9b3ed0472f4ce9e15352407 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Tue, 25 Jul 2023 15:56:53 +0200 +Subject: [PATCH 10/11] dhtest.c: Add test of DH_check() with q = p + 1 + +This must fail with DH_CHECK_INVALID_Q_VALUE and +with DH_CHECK_Q_NOT_PRIME unset. + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell + +reference: https://github.com/openssl/openssl/pull/21551 +Signed-off-by: yexiao +--- + CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c +index 00b3c471..d7e10ebd 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c +@@ -123,6 +123,15 @@ static int dh_test(void) + /* check whether the public key was calculated correctly */ + TEST_uint_eq(BN_get_word(pub_key2), 3331L); + ++ if (!TEST_ptr(BN_copy(q, p)) || !TEST_true(BN_add(q, q, BN_value_one()))) ++ goto err3; ++ ++ if (!TEST_true(DH_check(dh, &i))) ++ goto err3; ++ if (!TEST_true(i & DH_CHECK_INVALID_Q_VALUE) ++ || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)) ++ goto err3; ++ + /* Modulus of size: dh check max modulus bits + 1 */ + if (!TEST_true(BN_set_word(p, 1)) + || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) +@@ -134,6 +143,9 @@ static int dh_test(void) + if (!TEST_false(DH_check(dh, &i))) + goto err3; + ++ /* We'll have a stale error on the queue from the above test so clear it */ ++ ERR_clear_error(); ++ + /* + * II) key generation + */ +-- +2.33.0 + diff --git a/0045-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch b/0045-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch new file mode 100644 index 0000000000000000000000000000000000000000..412588918520be15a1be11f2a2ae64d461d3c6a1 --- /dev/null +++ b/0045-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch @@ -0,0 +1,118 @@ +From e4ee767dec6079c8c48ebacea19afdf2856dd755 Mon Sep 17 00:00:00 2001 +From: liwei +Date: Fri, 26 Jan 2024 18:45:28 +0800 +Subject: [PATCH 11/11] Add NULL checks where ContentInfo data can be NULL + +PKCS12 structures contain PKCS7 ContentInfo fields. These fields are +optional and can be NULL even if the "type" is a valid value. OpenSSL +was not properly accounting for this and a NULL dereference can occur +causing a crash. + +fix CVE-2024-0727 + +reference: https://github.com/openssl/openssl/pull/23361 +Signed-off-by: yexiao +--- + .../OpensslLib/openssl/crypto/pkcs12/p12_add.c | 16 ++++++++++++++++ + .../OpensslLib/openssl/crypto/pkcs12/p12_mutl.c | 5 +++++ + .../OpensslLib/openssl/crypto/pkcs12/p12_npas.c | 5 +++-- + .../OpensslLib/openssl/crypto/pkcs7/pk7_mime.c | 8 ++++++-- + 4 files changed, 30 insertions(+), 4 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c +index af184c86..9b40e538 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c +@@ -76,6 +76,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } ++ ++ if (p7->d.data == NULL) { ++ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, PKCS12_R_DECODE_ERROR); ++ return NULL; ++ } ++ + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); + } + +@@ -132,6 +138,11 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + { + if (!PKCS7_type_is_encrypted(p7)) + return NULL; ++ ++ if (p7->d.encrypted == NULL) { ++ return NULL; ++ } ++ + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + ASN1_ITEM_rptr(PKCS12_SAFEBAGS), + pass, passlen, +@@ -159,6 +170,11 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } ++ if (p12->authsafes->d.data == NULL) { ++ PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, PKCS12_R_DECODE_ERROR); ++ return NULL; ++ } ++ + return ASN1_item_unpack(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); + } +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c +index 3658003f..766c9c1e 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c +@@ -93,6 +93,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + return 0; + } + ++ if (p12->authsafes->d.data == NULL) { ++ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_DECODE_ERROR); ++ return 0; ++ } ++ + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + if (!p12->mac->iter) +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c +index 0334289a..13033763 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c +@@ -78,8 +78,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); +- if (!alg_get(p7->d.encrypted->enc_data->algorithm, +- &pbe_nid, &pbe_iter, &pbe_saltlen)) ++ if (p7->d.encrypted == NULL ++ || !alg_get(p7->d.encrypted->enc_data->algorithm, ++ &pbe_nid, &pbe_iter, &pbe_saltlen)) + goto err; + } else { + continue; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c +index 19e68681..b457108c 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c +@@ -30,10 +30,14 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) + { + STACK_OF(X509_ALGOR) *mdalgs; + int ctype_nid = OBJ_obj2nid(p7->type); +- if (ctype_nid == NID_pkcs7_signed) ++ ++ if (ctype_nid == NID_pkcs7_signed) { ++ if (p7->d.sign == NULL) ++ return 0; + mdalgs = p7->d.sign->md_algs; +- else ++ } else { + mdalgs = NULL; ++ } + + flags ^= SMIME_OLDMIME; + +-- +2.33.0 + diff --git a/0046-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0046-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch new file mode 100644 index 0000000000000000000000000000000000000000..97ccb2a7e28f76e1ca6b246b98357e0aed92492e --- /dev/null +++ b/0046-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch @@ -0,0 +1,920 @@ +From ab159257aac77fb718dedbac0c55ab179d1cfcb2 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:01 +0800 +Subject: [PATCH 01/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117 + - CVE 2022-36763 + +This commit contains the patch files and tests for DxeTpm2MeasureBootLib +CVE 2022-36763. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + .../DxeTpm2MeasureBootLib.c | 48 ++- + .../DxeTpm2MeasureBootLib.inf | 4 +- + .../DxeTpm2MeasureBootLibSanitization.c | 275 ++++++++++++++++ + .../DxeTpm2MeasureBootLibSanitization.h | 113 +++++++ + .../DxeTpm2MeasureBootLibSanitizationTest.c | 303 ++++++++++++++++++ + ...Tpm2MeasureBootLibSanitizationTestHost.inf | 28 ++ + 6 files changed, 755 insertions(+), 16 deletions(-) + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 92eac715..72e9f5d3 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -19,6 +19,8 @@ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP
+ SPDX-License-Identifier: BSD-2-Clause-Patent + ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -42,6 +44,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + ++#include "DxeTpm2MeasureBootLibSanitization.h" ++ + // + // Flag to check GPT partition. It only need be measured once. + // +@@ -135,7 +139,8 @@ Tcg2MeasureGptTable ( + UINT32 Index; + EFI_TCG2_EVENT *Tcg2Event; + EFI_GPT_DATA *GptData; +- UINT32 EventSize; ++ UINT32 TcgEventSize; ++ UINT32 AllocSize; + + if (mTcg2MeasureGptCount > 0) { + return EFI_SUCCESS; +@@ -163,15 +168,21 @@ Tcg2MeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status)) { +- DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n")); ++ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } + // + // Read the partition entry. + // +- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); ++ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ if (EFI_ERROR (Status)) { ++ FreePool (PrimaryHeader); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ EntryPtr = (UINT8 *)AllocatePool (AllocSize); + if (EntryPtr == NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; +@@ -180,7 +191,7 @@ Tcg2MeasureGptTable ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), +- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, ++ AllocSize, + EntryPtr + ); + if (EFI_ERROR (Status)) { +@@ -204,16 +215,21 @@ Tcg2MeasureGptTable ( + // + // Prepare Data for Measurement + // +- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) +- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); +- Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event)); ++ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); ++ if (EFI_ERROR (Status)) { ++ FreePool (PrimaryHeader); ++ FreePool (EntryPtr); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ Tcg2Event = (EFI_TCG2_EVENT *) AllocateZeroPool (TcgEventSize); + if (Tcg2Event == NULL) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); + return EFI_OUT_OF_RESOURCES; + } + +- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event); ++ Tcg2Event->Size = TcgEventSize; + Tcg2Event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER); + Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; + Tcg2Event->Header.PCRIndex = 5; +@@ -249,7 +265,7 @@ Tcg2MeasureGptTable ( + Tcg2Protocol, + 0, + (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData, +- (UINT64) EventSize, ++ (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event), + Tcg2Event + ); + if (!EFI_ERROR (Status)) { +@@ -333,11 +349,13 @@ Tcg2MeasurePeImage ( + Tcg2Event->Header.PCRIndex = 2; + break; + default: +- DEBUG (( +- EFI_D_ERROR, +- "Tcg2MeasurePeImage: Unknown subsystem type %d", +- ImageType +- )); ++ DEBUG ( ++ ( ++ DEBUG_ERROR, ++ "Tcg2MeasurePeImage: Unknown subsystem type %d", ++ ImageType ++ ) ++ ); + goto Finish; + } + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +index 2506abbe..30583cf1 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +@@ -37,6 +37,8 @@ + + [Sources] + DxeTpm2MeasureBootLib.c ++ DxeTpm2MeasureBootLibSanitization.c ++ DxeTpm2MeasureBootLibSanitization.h + + [Packages] + MdePkg/MdePkg.dec +@@ -46,6 +48,7 @@ + + [LibraryClasses] + BaseMemoryLib ++ SafeIntLib + DebugLib + MemoryAllocationLib + DevicePathLib +@@ -64,4 +67,3 @@ + gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES +- +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +new file mode 100644 +index 00000000..ef3b77b4 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -0,0 +1,275 @@ ++/** @file ++ The library instance provides security service of TPM2 measure boot and ++ Confidential Computing (CC) measure boot. ++ ++ Caution: This file requires additional review when modified. ++ This library will have external input - PE/COFF image and GPT partition. ++ This external input must be validated carefully to avoid security issue like ++ buffer overflow, integer overflow. ++ ++ This file will pull out the validation logic from the following functions, in an ++ attempt to validate the untrusted input in the form of unit tests ++ ++ These are those functions: ++ ++ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "DxeTpm2MeasureBootLibSanitization.h" ++ ++#define GPT_HEADER_REVISION_V1 0x00010000 ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ) ++{ ++ // ++ // Verify that the input parameters are safe to use ++ // ++ if (PrimaryHeader == NULL) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { ++ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) ++ // ++ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) ++ // ++ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size ++ // ++ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The partition entries should all be before the first usable block ++ // ++ if (PrimaryHeader->FirstUsableLBA <= PrimaryHeader->PartitionEntryLBA) { ++ DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsableLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Check that the PartitionEntryLBA greater than the Max LBA ++ // This will be used later for multiplication ++ // ++ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Check that the number of partition entries is greater than zero ++ // ++ if (PrimaryHeader->NumberOfPartitionEntries == 0) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory ++ // ++ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { ++ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // This check is to prevent overflow when calculating the allocation size for the partition entries ++ // This check will be used later for multiplication ++ // ++ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (AllocationSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Replacing logic: ++ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; ++ // ++ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including ++ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this ++ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) ++ from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ UINT32 SafeNumberOfPartitions; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (EventSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 ++ // ++ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Replacing logic: ++ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ // ++ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // ++ // Replacing logic: ++ // *EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); ++ // ++ Status = SafeUint32Add ( ++ OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions), ++ *EventSize, ++ EventSize ++ ); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +new file mode 100644 +index 00000000..74af8c8b +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -0,0 +1,113 @@ ++/** @file ++ This file includes the function prototypes for the sanitization functions. ++ ++ These are those functions: ++ ++ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ); ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ); ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including ++ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this ++ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) ++ from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +new file mode 100644 +index 00000000..701d1b46 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -0,0 +1,303 @@ ++/** @file ++ This file includes the unit test cases for the DxeTpm2MeasureBootLibSanitizationTest.c. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../DxeTpm2MeasureBootLibSanitization.h" ++ ++#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest" ++#define UNIT_TEST_VERSION "1.0" ++ ++#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 ++#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 ++#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 ++ ++/** ++ This function tests the SanitizeEfiPartitionTableHeader function. ++ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER ++ structure will not cause undefined or unexpected behavior. ++ ++ In general the TPM should still be able to measure the data, but ++ be the header should be sanitized to prevent any unexpected behavior. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizeEfiPartitionTableHeader ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ EFI_BLOCK_IO_PROTOCOL BlockIo; ++ EFI_BLOCK_IO_MEDIA BlockMedia; ++ ++ // Generate EFI_BLOCK_IO_MEDIA test data ++ BlockMedia.MediaId = 1; ++ BlockMedia.RemovableMedia = FALSE; ++ BlockMedia.MediaPresent = TRUE; ++ BlockMedia.LogicalPartition = FALSE; ++ BlockMedia.ReadOnly = FALSE; ++ BlockMedia.WriteCaching = FALSE; ++ BlockMedia.BlockSize = 512; ++ BlockMedia.IoAlign = 1; ++ BlockMedia.LastBlock = 0; ++ ++ // Generate EFI_BLOCK_IO_PROTOCOL test data ++ BlockIo.Revision = 1; ++ BlockIo.Media = &BlockMedia; ++ BlockIo.Reset = NULL; ++ BlockIo.ReadBlocks = NULL; ++ BlockIo.WriteBlocks = NULL; ++ BlockIo.FlushBlocks = NULL; ++ ++ // Geneate EFI_PARTITION_TABLE_HEADER test data ++ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; ++ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ PrimaryHeader.MyLBA = 1; ++ PrimaryHeader.AlternateLBA = 2; ++ PrimaryHeader.FirstUsableLBA = 3; ++ PrimaryHeader.LastUsableLBA = 4; ++ PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid ++ ++ // Calculate the CRC32 of the PrimaryHeader ++ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); ++ ++ // Test that a normal PrimaryHeader passes validation ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" ++ PrimaryHeader.NumberOfPartitionEntries = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header Size!" ++ PrimaryHeader.Header.HeaderSize = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ ++ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR ++ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" ++ PrimaryHeader.SizeOfPartitionEntry = 1; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderAllocationSize function. ++ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER ++ structure will not cause an overflow when calculating the allocation size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderAllocationSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 AllocationSize; ++ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that the allocation size is correct compared to the existing logic ++ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Test that an overflow is detected ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = 5; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the inverse ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the worst case scenario ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderGptEventSize function. ++ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure ++ will not cause an overflow when calculating the event size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderGptEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINT32 ExistingLogicEventSize; ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ UINTN NumberOfPartition; ++ EFI_GPT_DATA *GptData; ++ EFI_TCG2_EVENT *Tcg2Event; ++ ++ Tcg2Event = NULL; ++ GptData = NULL; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // set the number of partitions ++ NumberOfPartition = 13; ++ ++ // that the primary event size is correct ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Calculate the existing logic event size ++ ExistingLogicEventSize = (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions) ++ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Check that the event size is correct ++ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); ++ ++ // Tests that the primary event size may not overflow ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test that the size of partition entries may not overflow ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++// *--------------------------------------------------------------------* ++// * Unit Test Code Main Function ++// *--------------------------------------------------------------------* ++ ++/** ++ This function acts as the entry point for the unit tests. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++ @retval others The test failed. ++**/ ++EFI_STATUS ++EFIAPI ++UefiTestMain ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UNIT_TEST_FRAMEWORK_HANDLE Framework; ++ UNIT_TEST_SUITE_HANDLE Tcg2MeasureBootLibValidationTestSuite; ++ ++ Framework = NULL; ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); ++ ++ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); ++ goto EXIT; ++ } ++ ++ Status = CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBootLibValidation", NULL, NULL); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2MeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); ++ Status = EFI_OUT_OF_RESOURCES; ++ goto EXIT; ++ } ++ ++ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ ++ Status = RunAllTestSuites (Framework); ++ ++EXIT: ++ if (Framework != NULL) { ++ FreeUnitTestFramework (Framework); ++ } ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); ++ return Status; ++} ++ ++/// ++/// Avoid ECC error for function name that starts with lower case letter ++/// ++#define DxeTpm2MeasureBootLibUnitTestMain main ++ ++/** ++ Standard POSIX C entry point for host based unit test execution. ++ ++ @param[in] Argc Number of arguments ++ @param[in] Argv Array of pointers to arguments ++ ++ @retval 0 Success ++ @retval other Error ++**/ ++INT32 ++DxeTpm2MeasureBootLibUnitTestMain ( ++ IN INT32 Argc, ++ IN CHAR8 *Argv[] ++ ) ++{ ++ return (INT32)UefiTestMain (); ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf +new file mode 100644 +index 00000000..4ea55787 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf +@@ -0,0 +1,28 @@ ++## @file ++# This file builds the unit tests for DxeTpm2MeasureBootLib ++# ++# Copyright (C) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++ ++[Defines] ++ INF_VERSION = 0x00010006 ++ BASE_NAME = DxeTpm2MeasuredBootLibTest ++ FILE_GUID = 144d757f-d423-484e-9309-a23695fad5bd ++ MODULE_TYPE = HOST_APPLICATION ++ VERSION_STRING = 1.0 ++ ENTRY_POINT = main ++ ++[Sources] ++ DxeTpm2MeasureBootLibSanitizationTest.c ++ ../DxeTpm2MeasureBootLibSanitization.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ BaseLib ++ DebugLib ++ UnitTestLib ++ PrintLib ++ SafeIntLib +-- +2.33.0 + diff --git a/0047-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch b/0047-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a15747d9baafff0b098d8180862da22c8d7ceb1 --- /dev/null +++ b/0047-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch @@ -0,0 +1,872 @@ +From bde26e1b8957121e956e80b08ac59bfcfb52ffa9 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:02 +0800 +Subject: [PATCH 02/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117 + - CVE 2022-36763 + +This commit contains the patch files and tests for DxeTpmMeasureBootLib +CVE 2022-36763. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao + +ref: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + .../DxeTpmMeasureBootLib.c | 40 ++- + .../DxeTpmMeasureBootLib.inf | 4 +- + .../DxeTpmMeasureBootLibSanitization.c | 241 ++++++++++++++ + .../DxeTpmMeasureBootLibSanitization.h | 114 +++++++ + .../DxeTpmMeasureBootLibSanitizationTest.c | 301 ++++++++++++++++++ + ...eTpmMeasureBootLibSanitizationTestHost.inf | 28 ++ + 6 files changed, 714 insertions(+), 14 deletions(-) + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index d990eb2a..8314d019 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -18,6 +18,8 @@ + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -40,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + ++#include "DxeTpmMeasureBootLibSanitization.h" ++ + // + // Flag to check GPT partition. It only need be measured once. + // +@@ -136,6 +140,9 @@ TcgMeasureGptTable ( + UINT32 EventSize; + UINT32 EventNumber; + EFI_PHYSICAL_ADDRESS EventLogLastEntry; ++ UINT32 AllocSize; ++ ++ GptData = NULL; + + if (mMeasureGptCount > 0) { + return EFI_SUCCESS; +@@ -163,15 +170,21 @@ TcgMeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status)) { +- DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n")); ++ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } + // + // Read the partition entry. + // +- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); ++ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ if (EFI_ERROR (Status)) { ++ FreePool (PrimaryHeader); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ EntryPtr = (UINT8 *)AllocatePool (AllocSize); + if (EntryPtr == NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; +@@ -180,7 +193,7 @@ TcgMeasureGptTable ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), +- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, ++ AllocSize, + EntryPtr + ); + if (EFI_ERROR (Status)) { +@@ -204,9 +217,8 @@ TcgMeasureGptTable ( + // + // Prepare Data for Measurement + // +- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) +- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); +- TcgEvent = (TCG_PCR_EVENT *) AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR)); ++ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); ++ TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); +@@ -215,7 +227,7 @@ TcgMeasureGptTable ( + + TcgEvent->PCRIndex = 5; + TcgEvent->EventType = EV_EFI_GPT_EVENT; +- TcgEvent->EventSize = EventSize; ++ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); + GptData = (EFI_GPT_DATA *) TcgEvent->Event; + + // +@@ -354,11 +366,13 @@ TcgMeasurePeImage ( + TcgEvent->PCRIndex = 2; + break; + default: +- DEBUG (( +- EFI_D_ERROR, +- "TcgMeasurePeImage: Unknown subsystem type %d", +- ImageType +- )); ++ DEBUG ( ++ ( ++ DEBUG_ERROR, ++ "TcgMeasurePeImage: Unknown subsystem type %d", ++ ImageType ++ ) ++ ); + goto Finish; + } + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +index ebab6f7c..21bfd570 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +@@ -32,6 +32,8 @@ + + [Sources] + DxeTpmMeasureBootLib.c ++ DxeTpmMeasureBootLibSanitization.c ++ DxeTpmMeasureBootLibSanitization.h + + [Packages] + MdePkg/MdePkg.dec +@@ -41,6 +43,7 @@ + + [LibraryClasses] + BaseMemoryLib ++ SafeIntLib + DebugLib + MemoryAllocationLib + DevicePathLib +@@ -59,4 +62,3 @@ + gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES +- +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +new file mode 100644 +index 00000000..e009ce46 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -0,0 +1,241 @@ ++/** @file ++ The library instance provides security service of TPM2 measure boot and ++ Confidential Computing (CC) measure boot. ++ ++ Caution: This file requires additional review when modified. ++ This library will have external input - PE/COFF image and GPT partition. ++ This external input must be validated carefully to avoid security issue like ++ buffer overflow, integer overflow. ++ ++ This file will pull out the validation logic from the following functions, in an ++ attempt to validate the untrusted input in the form of unit tests ++ ++ These are those functions: ++ ++ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "DxeTpmMeasureBootLibSanitization.h" ++ ++#define GPT_HEADER_REVISION_V1 0x00010000 ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ) ++{ ++ // Verify that the input parameters are safe to use ++ if (PrimaryHeader == NULL) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { ++ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) ++ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) ++ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size ++ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // check that the PartitionEntryLBA greater than the Max LBA ++ // This will be used later for multiplication ++ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // Check that the number of partition entries is greater than zero ++ if (PrimaryHeader->NumberOfPartitionEntries == 0) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory ++ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { ++ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // This check is to prevent overflow when calculating the allocation size for the partition entries ++ // This check will be used later for multiplication ++ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (AllocationSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // Replacing logic: ++ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; ++ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including the ++ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract ++ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ UINT32 SafeNumberOfPartitions; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (EventSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 ++ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // Replacing logic: ++ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_HDR)); ++ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ Status = SafeUint32Add ( ++ sizeof (TCG_PCR_EVENT_HDR) + ++ OFFSET_OF (EFI_GPT_DATA, Partitions), ++ *EventSize, ++ EventSize ++ ); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +new file mode 100644 +index 00000000..57e05e48 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -0,0 +1,114 @@ ++/** @file ++ This file includes the function prototypes for the sanitization functions. ++ ++ These are those functions: ++ ++ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ TcgMeasurePeImage() function will accept untrusted PE/COFF image and validate its ++ data structure within this image buffer before use. ++ ++ TcgMeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ ++#define DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ); ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ); ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including the ++ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract ++ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +new file mode 100644 +index 00000000..8cd97480 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -0,0 +1,301 @@ ++/** @file ++This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. ++ ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../DxeTpmMeasureBootLibSanitization.h" ++ ++#define UNIT_TEST_NAME "DxeTpmMeasureBootLibSanitizationTest" ++#define UNIT_TEST_VERSION "1.0" ++ ++#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 ++#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 ++#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 ++ ++/** ++ This function tests the SanitizeEfiPartitionTableHeader function. ++ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER ++ structure will not cause undefined or unexpected behavior. ++ ++ In general the TPM should still be able to measure the data, but ++ be the header should be sanitized to prevent any unexpected behavior. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizeEfiPartitionTableHeader ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ EFI_BLOCK_IO_PROTOCOL BlockIo; ++ EFI_BLOCK_IO_MEDIA BlockMedia; ++ ++ // Generate EFI_BLOCK_IO_MEDIA test data ++ BlockMedia.MediaId = 1; ++ BlockMedia.RemovableMedia = FALSE; ++ BlockMedia.MediaPresent = TRUE; ++ BlockMedia.LogicalPartition = FALSE; ++ BlockMedia.ReadOnly = FALSE; ++ BlockMedia.WriteCaching = FALSE; ++ BlockMedia.BlockSize = 512; ++ BlockMedia.IoAlign = 1; ++ BlockMedia.LastBlock = 0; ++ ++ // Generate EFI_BLOCK_IO_PROTOCOL test data ++ BlockIo.Revision = 1; ++ BlockIo.Media = &BlockMedia; ++ BlockIo.Reset = NULL; ++ BlockIo.ReadBlocks = NULL; ++ BlockIo.WriteBlocks = NULL; ++ BlockIo.FlushBlocks = NULL; ++ ++ // Geneate EFI_PARTITION_TABLE_HEADER test data ++ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; ++ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ PrimaryHeader.MyLBA = 1; ++ PrimaryHeader.AlternateLBA = 2; ++ PrimaryHeader.FirstUsableLBA = 3; ++ PrimaryHeader.LastUsableLBA = 4; ++ PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid ++ ++ // Calculate the CRC32 of the PrimaryHeader ++ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); ++ ++ // Test that a normal PrimaryHeader passes validation ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" ++ PrimaryHeader.NumberOfPartitionEntries = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header Size!" ++ PrimaryHeader.Header.HeaderSize = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ ++ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR ++ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" ++ PrimaryHeader.SizeOfPartitionEntry = 1; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderAllocationSize function. ++ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER ++ structure will not cause an overflow when calculating the allocation size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderAllocationSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 AllocationSize; ++ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that the allocation size is correct compared to the existing logic ++ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Test that an overflow is detected ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = 5; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the inverse ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the worst case scenario ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderGptEventSize function. ++ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure ++ will not cause an overflow when calculating the event size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderGptEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINT32 ExistingLogicEventSize; ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ UINTN NumberOfPartition; ++ EFI_GPT_DATA *GptData; ++ ++ GptData = NULL; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // set the number of partitions ++ NumberOfPartition = 13; ++ ++ // that the primary event size is correct ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Calculate the existing logic event size ++ ExistingLogicEventSize = (UINT32)(sizeof (TCG_PCR_EVENT_HDR) + OFFSET_OF (EFI_GPT_DATA, Partitions) ++ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Check that the event size is correct ++ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); ++ ++ // Tests that the primary event size may not overflow ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test that the size of partition entries may not overflow ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++// *--------------------------------------------------------------------* ++// * Unit Test Code Main Function ++// *--------------------------------------------------------------------* ++ ++/** ++ This function acts as the entry point for the unit tests. ++ ++ @param argc - The number of command line arguments ++ @param argv - The command line arguments ++ ++ @return int - The status of the test ++**/ ++EFI_STATUS ++EFIAPI ++UefiTestMain ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UNIT_TEST_FRAMEWORK_HANDLE Framework; ++ UNIT_TEST_SUITE_HANDLE TcgMeasureBootLibValidationTestSuite; ++ ++ Framework = NULL; ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); ++ ++ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); ++ goto EXIT; ++ } ++ ++ Status = CreateUnitTestSuite (&TcgMeasureBootLibValidationTestSuite, Framework, "TcgMeasureBootLibValidationTestSuite", "Common.TcgMeasureBootLibValidation", NULL, NULL); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for TcgMeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); ++ Status = EFI_OUT_OF_RESOURCES; ++ goto EXIT; ++ } ++ ++ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ ++ Status = RunAllTestSuites (Framework); ++ ++EXIT: ++ if (Framework != NULL) { ++ FreeUnitTestFramework (Framework); ++ } ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); ++ return Status; ++} ++ ++/// ++/// Avoid ECC error for function name that starts with lower case letter ++/// ++#define DxeTpmMeasureBootLibUnitTestMain main ++ ++/** ++ Standard POSIX C entry point for host based unit test execution. ++ ++ @param[in] Argc Number of arguments ++ @param[in] Argv Array of pointers to arguments ++ ++ @retval 0 Success ++ @retval other Error ++**/ ++INT32 ++DxeTpmMeasureBootLibUnitTestMain ( ++ IN INT32 Argc, ++ IN CHAR8 *Argv[] ++ ) ++{ ++ return (INT32)UefiTestMain (); ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf +new file mode 100644 +index 00000000..ba4c58cb +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf +@@ -0,0 +1,28 @@ ++## @file ++# This file builds the unit tests for DxeTpmMeasureBootLib ++# ++# Copyright (C) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++ ++[Defines] ++ INF_VERSION = 0x00010006 ++ BASE_NAME = DxeTpmMeasuredBootLibTest ++ FILE_GUID = eb01bc38-309c-4d3e-967e-9f078c90772f ++ MODULE_TYPE = HOST_APPLICATION ++ VERSION_STRING = 1.0 ++ ENTRY_POINT = main ++ ++[Sources] ++ DxeTpmMeasureBootLibSanitizationTest.c ++ ../DxeTpmMeasureBootLibSanitization.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ BaseLib ++ DebugLib ++ UnitTestLib ++ PrintLib ++ SafeIntLib +-- +2.33.0 + diff --git a/0048-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch b/0048-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch new file mode 100644 index 0000000000000000000000000000000000000000..69967fa654d8da8502c5d8024393f7f227f4906b --- /dev/null +++ b/0048-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch @@ -0,0 +1,53 @@ +From e8c20e52c9e7cc55eb3aad1229ec196d39cf119f Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:03 +0800 +Subject: [PATCH 03/10] SecurityPkg: : Adding CVE 2022-36763 to + SecurityFixes.yaml + +This creates / adds a security file that tracks the security fixes +found in this package and can be used to find the fixes that were +applied. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + SecurityPkg/SecurityFixes.yaml | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + create mode 100644 SecurityPkg/SecurityFixes.yaml + +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +new file mode 100644 +index 00000000..36ac267e +--- /dev/null ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -0,0 +1,22 @@ ++## @file ++# Security Fixes for SecurityPkg ++# ++# Copyright (c) Microsoft Corporation ++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++CVE_2022_36763: ++ commit_titles: ++ - "SecurityPkg: DxeTpm2Measurement: SECURITY PATCH 4117 - CVE 2022-36763" ++ - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-36763" ++ - "SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml" ++ cve: CVE-2022-36763 ++ date_reported: 2022-10-25 11:31 UTC ++ description: (CVE-2022-36763) - Heap Buffer Overflow in Tcg2MeasureGptTable() ++ note: This patch is related to and supersedes TCBZ2168 ++ files_impacted: ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 +-- +2.33.0 + diff --git a/0049-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0049-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch new file mode 100644 index 0000000000000000000000000000000000000000..3cee44e5d663d658edb8dfca1b3160343c9d3185 --- /dev/null +++ b/0049-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch @@ -0,0 +1,264 @@ +From 5317710f9c26c80bb10de6e0ed13b246c0e5a107 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:04 +0800 +Subject: [PATCH 04/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 + - CVE 2022-36764 + +This commit contains the patch files and tests for DxeTpm2MeasureBootLib +CVE 2022-36764. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + .../DxeTpm2MeasureBootLib.c | 13 ++-- + .../DxeTpm2MeasureBootLibSanitization.c | 46 +++++++++++++- + .../DxeTpm2MeasureBootLibSanitization.h | 28 ++++++++- + .../DxeTpm2MeasureBootLibSanitizationTest.c | 60 ++++++++++++++++--- + 4 files changed, 132 insertions(+), 15 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 1a7233e6..0121e1ef 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -298,7 +298,6 @@ Tcg2MeasureGptTable ( + @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. + @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format. + @retval other error value +- + **/ + EFI_STATUS + EFIAPI +@@ -317,20 +316,26 @@ Tcg2MeasurePeImage ( + UINT32 FilePathSize; + UINT32 EventSize; + ++ Tcg2Event = NULL; ++ + Status = EFI_UNSUPPORTED; + ImageLoad = NULL; + FilePathSize = (UINT32) GetDevicePathSize (FilePath); ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } + + // + // Determine destination PCR by BootPolicy + // +- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; +- Tcg2Event = AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event)); ++ // from a malicious GPT disk partition ++ Tcg2Event = AllocateZeroPool (EventSize); + if (Tcg2Event == NULL) { + return EFI_OUT_OF_RESOURCES; + } + +- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof(Tcg2Event->Event); ++ Tcg2Event->Size = EventSize; + Tcg2Event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER); + Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; + ImageLoad = (EFI_IMAGE_LOAD_EVENT *) Tcg2Event->Event; +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +index ef3b77b4..bc583c97 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -151,7 +151,7 @@ SanitizeEfiPartitionTableHeader ( + } + + /** +- This function will validate that the allocation size from the primary header is sane ++ This function will validate that the allocation size from the primary header is sane + It will check the following: + - AllocationSize does not overflow + +@@ -273,3 +273,47 @@ SanitizePrimaryHeaderGptEventSize ( + + return EFI_SUCCESS; + } ++ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ // Replacing logic: ++ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; ++ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // Replacing logic: ++ // EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event) ++ Status = SafeUint32Add (*EventSize, OFFSET_OF (EFI_TCG2_EVENT, Event), EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +index 74af8c8b..bfbfb589 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -9,6 +9,9 @@ + Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse + partition data carefully. + ++ Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its ++ data structure within this image buffer before use. ++ + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +@@ -110,4 +113,27 @@ SanitizePrimaryHeaderGptEventSize ( + OUT UINT32 *EventSize + ); + +-#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM2_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +index 701d1b46..8d8c0b26 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -72,10 +72,10 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + PrimaryHeader.MyLBA = 1; +- PrimaryHeader.AlternateLBA = 2; +- PrimaryHeader.FirstUsableLBA = 3; +- PrimaryHeader.LastUsableLBA = 4; +- PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.PartitionEntryLBA = 2; ++ PrimaryHeader.AlternateLBA = 3; ++ PrimaryHeader.FirstUsableLBA = 4; ++ PrimaryHeader.LastUsableLBA = 5; + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid +@@ -187,11 +187,6 @@ TestSanitizePrimaryHeaderGptEventSize ( + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; +- EFI_GPT_DATA *GptData; +- EFI_TCG2_EVENT *Tcg2Event; +- +- Tcg2Event = NULL; +- GptData = NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries = 5; +@@ -225,6 +220,52 @@ TestSanitizePrimaryHeaderGptEventSize ( + return UNIT_TEST_PASSED; + } + ++/** ++ This function tests the SanitizePeImageEventSize function. ++ It's intent is to test that the untrusted input from a file path when generating a ++ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating ++ the event size when allocating space ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePeImageEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINTN ExistingLogicEventSize; ++ UINT32 FilePathSize; ++ EFI_STATUS Status; ++ ++ FilePathSize = 255; ++ ++ // Test that a normal PE image passes validation ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_SUCCESS); ++ ++ // Test that the event size is correct compared to the existing logic ++ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; ++ ExistingLogicEventSize += OFFSET_OF (EFI_TCG2_EVENT, Event); ++ ++ if (EventSize != ExistingLogicEventSize) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); ++ return UNIT_TEST_ERROR_TEST_FAILED; ++ } ++ ++ // Test that the event size may not overflow ++ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ + // *--------------------------------------------------------------------* + // * Unit Test Code Main Function + // *--------------------------------------------------------------------* +@@ -267,6 +308,7 @@ UefiTestMain ( + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); + + Status = RunAllTestSuites (Framework); + +-- +2.33.0 + diff --git a/0050-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch b/0050-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch new file mode 100644 index 0000000000000000000000000000000000000000..054eb34179e203cf46303e864fe3b62f0b7c2f05 --- /dev/null +++ b/0050-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch @@ -0,0 +1,278 @@ +From 4032c37489aecd8b0ccdfd09e0bef1587da69473 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:05 +0800 +Subject: [PATCH 05/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 + - CVE 2022-36764 + +This commit contains the patch files and tests for DxeTpmMeasureBootLib +CVE 2022-36764. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + .../DxeTpmMeasureBootLib.c | 13 ++- + .../DxeTpmMeasureBootLibSanitization.c | 44 +++++++++ + .../DxeTpmMeasureBootLibSanitization.h | 23 +++++ + .../DxeTpmMeasureBootLibSanitizationTest.c | 98 +++++++++++++++++-- + 4 files changed, 168 insertions(+), 10 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index 8314d019..a2c5b36f 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -17,6 +17,7 @@ + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent ++Copyright (c) Microsoft Corporation.
+ + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +@@ -338,18 +339,22 @@ TcgMeasurePeImage ( + ImageLoad = NULL; + SectionHeader = NULL; + Sha1Ctx = NULL; ++ TcgEvent = NULL; + FilePathSize = (UINT32) GetDevicePathSize (FilePath); + +- // + // Determine destination PCR by BootPolicy + // +- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; +- TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ TcgEvent = AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + return EFI_OUT_OF_RESOURCES; + } + +- TcgEvent->EventSize = EventSize; ++ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); + ImageLoad = (EFI_IMAGE_LOAD_EVENT *) TcgEvent->Event; + + switch (ImageType) { +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +index e009ce46..33a230f8 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -239,3 +239,47 @@ SanitizePrimaryHeaderGptEventSize ( + + return EFI_SUCCESS; + } ++ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ // Replacing logic: ++ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; ++ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // Replacing logic: ++ // EventSize + sizeof (TCG_PCR_EVENT_HDR) ++ Status = SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +index 57e05e48..181aba42 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -111,4 +111,27 @@ SanitizePrimaryHeaderGptEventSize ( + OUT UINT32 *EventSize + ); + ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ); ++ + #endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +index 8cd97480..77a67826 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -1,8 +1,8 @@ + /** @file +-This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. ++ This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. + +-Copyright (c) Microsoft Corporation.
+-SPDX-License-Identifier: BSD-2-Clause-Patent ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize ( + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; +- EFI_GPT_DATA *GptData; +- +- GptData = NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries = 5; +@@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize ( + return UNIT_TEST_PASSED; + } + ++/** ++ This function tests the SanitizePeImageEventSize function. ++ It's intent is to test that the untrusted input from a file path for an ++ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating ++ the event size when allocating space. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePeImageEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINTN ExistingLogicEventSize; ++ UINT32 FilePathSize; ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH_PROTOCOL DevicePath; ++ EFI_IMAGE_LOAD_EVENT *ImageLoadEvent; ++ UNIT_TEST_STATUS TestStatus; ++ ++ TestStatus = UNIT_TEST_ERROR_TEST_FAILED; ++ ++ // Generate EFI_DEVICE_PATH_PROTOCOL test data ++ DevicePath.Type = 0; ++ DevicePath.SubType = 0; ++ DevicePath.Length[0] = 0; ++ DevicePath.Length[1] = 0; ++ ++ // Generate EFI_IMAGE_LOAD_EVENT test data ++ ImageLoadEvent = AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ if (ImageLoadEvent == NULL) { ++ DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__)); ++ goto Exit; ++ } ++ ++ // Populate EFI_IMAGE_LOAD_EVENT54 test data ++ ImageLoadEvent->ImageLocationInMemory = (EFI_PHYSICAL_ADDRESS)0x12345678; ++ ImageLoadEvent->ImageLengthInMemory = 0x1000; ++ ImageLoadEvent->ImageLinkTimeAddress = (UINTN)ImageLoadEvent; ++ ImageLoadEvent->LengthOfDevicePath = sizeof (EFI_DEVICE_PATH_PROTOCOL); ++ CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ ++ FilePathSize = 255; ++ ++ // Test that a normal PE image passes validation ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); ++ goto Exit; ++ } ++ ++ // Test that the event size is correct compared to the existing logic ++ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; ++ ExistingLogicEventSize += sizeof (TCG_PCR_EVENT_HDR); ++ ++ if (EventSize != ExistingLogicEventSize) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); ++ goto Exit; ++ } ++ ++ // Test that the event size may not overflow ++ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ if (Status != EFI_BAD_BUFFER_SIZE) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); ++ goto Exit; ++ } ++ ++ TestStatus = UNIT_TEST_PASSED; ++Exit: ++ ++ if (ImageLoadEvent != NULL) { ++ FreePool (ImageLoadEvent); ++ } ++ ++ if (TestStatus == UNIT_TEST_ERROR_TEST_FAILED) { ++ DEBUG ((DEBUG_ERROR, "%a: Test failed\n", __func__)); ++ } else { ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ } ++ ++ return TestStatus; ++} ++ + // *--------------------------------------------------------------------* + // * Unit Test Code Main Function + // *--------------------------------------------------------------------* +@@ -265,6 +350,7 @@ UefiTestMain ( + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); + + Status = RunAllTestSuites (Framework); + +-- +2.33.0 + diff --git a/0051-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch b/0051-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch new file mode 100644 index 0000000000000000000000000000000000000000..016072467081d0d20363c41beab761142c71be42 --- /dev/null +++ b/0051-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch @@ -0,0 +1,46 @@ +From 78b9e1e994fe429f8669c89695193acdb31e3a58 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:06 +0800 +Subject: [PATCH 06/10] SecurityPkg: : Adding CVE 2022-36764 to + SecurityFixes.yaml + +This creates / adds a security file that tracks the security fixes +found in this package and can be used to find the fixes that were +applied. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5264 +Signed-off-by: yexiao +--- + SecurityPkg/SecurityFixes.yaml | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index 36ac267e..ceaaa256 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -20,3 +20,17 @@ CVE_2022_36763: + - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 + - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 + - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 ++CVE_2022_36764: ++ commit_titles: ++ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" ++ cve: CVE-2022-36764 ++ date_reported: 2022-10-25 12:23 UTC ++ description: Heap Buffer Overflow in Tcg2MeasurePeImage() ++ note: ++ files_impacted: ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 +-- +2.33.0 + diff --git a/0052-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch b/0052-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch new file mode 100644 index 0000000000000000000000000000000000000000..9da3a51a65048174b8d07dd35149160cb45c3379 --- /dev/null +++ b/0052-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch @@ -0,0 +1,257 @@ +From 72118d86cc064ce259b4ac3fb81666b4cf84d457 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 17 Jan 2024 14:47:20 -0800 +Subject: [PATCH 07/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH + 4117/4118 symbol rename + +Updates the sanitation function names to be lib unique names + +Cc: Jiewen Yao +Cc: Rahul Kumar + +Signed-off-by: Doug Flick [MSFT] +Message-Id: <7b18434c8a8b561654efd40ced3becb8b378c8f1.1705529990.git.doug.edk2@gmail.com> +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5273 +Signed-off-by: yexiao +--- + .../DxeTpm2MeasureBootLib.c | 8 +++--- + .../DxeTpm2MeasureBootLibSanitization.c | 8 +++--- + .../DxeTpm2MeasureBootLibSanitization.h | 8 +++--- + .../DxeTpm2MeasureBootLibSanitizationTest.c | 26 +++++++++---------- + 4 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 0121e1ef..eb1da757 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -168,7 +168,7 @@ Tcg2MeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -176,7 +176,7 @@ Tcg2MeasureGptTable ( + // + // Read the partition entry. + // +- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_BAD_BUFFER_SIZE; +@@ -215,7 +215,7 @@ Tcg2MeasureGptTable ( + // + // Prepare Data for Measurement + // +- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); +@@ -321,7 +321,7 @@ Tcg2MeasurePeImage ( + Status = EFI_UNSUPPORTED; + ImageLoad = NULL; + FilePathSize = (UINT32) GetDevicePathSize (FilePath); +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +index bc583c97..d911efe6 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -63,7 +63,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++Tpm2SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +@@ -169,7 +169,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++Tpm2SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +@@ -221,7 +221,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++Tpm2SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -292,7 +292,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++Tpm2SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +index bfbfb589..504958f4 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -54,7 +54,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++Tpm2SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); +@@ -78,7 +78,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++Tpm2SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); +@@ -107,7 +107,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++Tpm2SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -131,7 +131,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++Tpm2SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +index 8d8c0b26..0e33fec5 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -84,27 +84,27 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" + PrimaryHeader.NumberOfPartitionEntries = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" + PrimaryHeader.SizeOfPartitionEntry = 1; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -137,7 +137,7 @@ TestSanitizePrimaryHeaderAllocationSize ( + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing logic +@@ -146,19 +146,19 @@ TestSanitizePrimaryHeaderAllocationSize ( + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = 5; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -196,7 +196,7 @@ TestSanitizePrimaryHeaderGptEventSize ( + NumberOfPartition = 13; + + // that the primary event size is correct +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size +@@ -207,12 +207,12 @@ TestSanitizePrimaryHeaderGptEventSize ( + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -245,7 +245,7 @@ TestSanitizePeImageEventSize ( + FilePathSize = 255; + + // Test that a normal PE image passes validation +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_SUCCESS); + + // Test that the event size is correct compared to the existing logic +@@ -258,7 +258,7 @@ TestSanitizePeImageEventSize ( + } + + // Test that the event size may not overflow +- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +-- +2.33.0 + diff --git a/0053-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch b/0053-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch new file mode 100644 index 0000000000000000000000000000000000000000..f14ac55a0351cb261dc11e27de0e743267dccf59 --- /dev/null +++ b/0053-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch @@ -0,0 +1,264 @@ +From 693484899bab5e0fe730604fa71ad1f8cdffecb1 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 17 Jan 2024 14:47:21 -0800 +Subject: [PATCH 08/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH + 4117/4118 symbol rename + +Updates the sanitation function names to be lib unique names + +Cc: Jiewen Yao +Cc: Rahul Kumar + +Signed-off-by: Doug Flick [MSFT] +Message-Id: <355aa846a99ca6ac0f7574cf5982661da0d9fea6.1705529990.git.doug.edk2@gmail.com> +Reviewed-by: Jiewen Yao + +reference: https://github.com/tianocore/edk2/pull/5273 +Signed-off-by: yexiao +--- + .../DxeTpmMeasureBootLib.c | 8 +++--- + .../DxeTpmMeasureBootLibSanitization.c | 10 +++---- + .../DxeTpmMeasureBootLibSanitization.h | 8 +++--- + .../DxeTpmMeasureBootLibSanitizationTest.c | 26 +++++++++---------- + 4 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index a2c5b36f..991fc04e 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -171,7 +171,7 @@ TcgMeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ if (EFI_ERROR (Status) || EFI_ERROR (TpmSanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -179,7 +179,7 @@ TcgMeasureGptTable ( + // + // Read the partition entry. + // +- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -218,7 +218,7 @@ TcgMeasureGptTable ( + // + // Prepare Data for Measurement + // +- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); + TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + FreePool (PrimaryHeader); +@@ -344,7 +344,7 @@ TcgMeasurePeImage ( + + // Determine destination PCR by BootPolicy + // +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +index 33a230f8..c72a3491 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -1,5 +1,5 @@ + /** @file +- The library instance provides security service of TPM2 measure boot and ++ The library instance provides security service of TPM measure boot and + Confidential Computing (CC) measure boot. + + Caution: This file requires additional review when modified. +@@ -63,7 +63,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++TpmSanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +@@ -145,7 +145,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++TpmSanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +@@ -194,7 +194,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++TpmSanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -258,7 +258,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++TpmSanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +index 181aba42..bbde1010 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -53,7 +53,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++TpmSanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); +@@ -77,7 +77,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++TpmSanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); +@@ -105,7 +105,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++TpmSanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -129,7 +129,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++TpmSanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +index 77a67826..e00dfaba 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -83,27 +83,27 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" + PrimaryHeader.NumberOfPartitionEntries = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" + PrimaryHeader.SizeOfPartitionEntry = 1; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -136,7 +136,7 @@ TestSanitizePrimaryHeaderAllocationSize ( + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing logic +@@ -145,19 +145,19 @@ TestSanitizePrimaryHeaderAllocationSize ( + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = 5; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -195,7 +195,7 @@ TestSanitizePrimaryHeaderGptEventSize ( + NumberOfPartition = 13; + + // that the primary event size is correct +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size +@@ -206,12 +206,12 @@ TestSanitizePrimaryHeaderGptEventSize ( + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -269,7 +269,7 @@ TestSanitizePeImageEventSize ( + FilePathSize = 255; + + // Test that a normal PE image passes validation +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); + goto Exit; +@@ -285,7 +285,7 @@ TestSanitizePeImageEventSize ( + } + + // Test that the event size may not overflow +- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ Status = TpmSanitizePeImageEventSize (MAX_UINT32, &EventSize); + if (Status != EFI_BAD_BUFFER_SIZE) { + UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); + goto Exit; +-- +2.33.0 + diff --git a/0054-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch b/0054-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c6f7e04961c4516b5c5a770dd8f6a3a4b08eeb3 --- /dev/null +++ b/0054-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch @@ -0,0 +1,154 @@ +From dc1c1ab453b5b6011e317f08ecabb74d409dfe31 Mon Sep 17 00:00:00 2001 +From: Gua Guo +Date: Thu, 11 Jan 2024 13:07:50 +0800 +Subject: [PATCH 09/10] EmbeddedPkg/Hob: Integer Overflow in CreateHob() + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166 + +Fix integer overflow in various CreateHob instances. +Fixes: CVE-2022-36765 + +The CreateHob() function aligns the requested size to 8 +performing the following operation: +``` +HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); +``` + +No checks are performed to ensure this value doesn't +overflow, and could lead to CreateHob() returning a smaller +HOB than requested, which could lead to OOB HOB accesses. + +Reported-by: Marc Beatove +Cc: Leif Lindholm +Reviewed-by: Ard Biesheuvel +Cc: Abner Chang +Cc: John Mathew +Authored-by: Gerd Hoffmann +Signed-off-by: Gua Guo + +reference: https://github.com/tianocore/edk2/pull/5273 +Signed-off-by: yexiao +--- + EmbeddedPkg/Library/PrePiHobLib/Hob.c | 43 +++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c +index b5cc6c5d..2daf6f56 100644 +--- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c ++++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c +@@ -112,6 +112,13 @@ CreateHob ( + + HandOffHob = GetHobList (); + ++ // ++ // Check Length to avoid data overflow. ++ // ++ if (HobLength > MAX_UINT16 - 0x7) { ++ return NULL; ++ } ++ + HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); + + FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; +@@ -162,6 +169,9 @@ BuildResourceDescriptorHob ( + + Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); + ASSERT(Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->ResourceType = ResourceType; + Hob->ResourceAttribute = ResourceAttribute; +@@ -403,6 +413,10 @@ BuildModuleHob ( + ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); + Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; +@@ -451,6 +465,11 @@ BuildGuidHob ( + ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); + + Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return NULL; ++ } ++ + CopyGuid (&Hob->Name, Guid); + return Hob + 1; + } +@@ -516,6 +535,10 @@ BuildFvHob ( + EFI_HOB_FIRMWARE_VOLUME *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -548,6 +571,10 @@ BuildFv2Hob ( + EFI_HOB_FIRMWARE_VOLUME2 *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -589,6 +616,10 @@ BuildFv3Hob ( + EFI_HOB_FIRMWARE_VOLUME3 *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -645,6 +676,10 @@ BuildCpuHob ( + EFI_HOB_CPU *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->SizeOfMemorySpace = SizeOfMemorySpace; + Hob->SizeOfIoSpace = SizeOfIoSpace; +@@ -681,6 +716,10 @@ BuildStackHob ( + ((Length & (EFI_PAGE_SIZE - 1)) == 0)); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; +@@ -761,6 +800,10 @@ BuildMemoryAllocationHob ( + ((Length & (EFI_PAGE_SIZE - 1)) == 0)); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; +-- +2.33.0 + diff --git a/0055-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch b/0055-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch new file mode 100644 index 0000000000000000000000000000000000000000..0fd362738402406aeab6c6cf342bdd117f2b3c38 --- /dev/null +++ b/0055-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch @@ -0,0 +1,132 @@ +From 94835b890180c90d8d9f76afc6aab5e7f108304e Mon Sep 17 00:00:00 2001 +From: Gua Guo +Date: Thu, 11 Jan 2024 13:03:26 +0800 +Subject: [PATCH 10/10] StandaloneMmPkg/Hob: Integer Overflow in CreateHob() + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166 + +Fix integer overflow in various CreateHob instances. +Fixes: CVE-2022-36765 + +The CreateHob() function aligns the requested size to 8 +performing the following operation: +``` +HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); +``` + +No checks are performed to ensure this value doesn't +overflow, and could lead to CreateHob() returning a smaller +HOB than requested, which could lead to OOB HOB accesses. + +Reported-by: Marc Beatove +Reviewed-by: Ard Biesheuvel +Cc: Sami Mujawar +Reviewed-by: Ray Ni +Cc: John Mathew +Authored-by: Gerd Hoffmann +Signed-off-by: Gua Guo + +reference: https://github.com/tianocore/edk2/pull/5273 +Signed-off-by: yexiao +--- + .../StandaloneMmCoreHobLib.c | 35 +++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.c +index e3d4743b..08963df8 100644 +--- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.c ++++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.c +@@ -216,6 +216,13 @@ CreateHob ( + + HandOffHob = GetHobList (); + ++ // ++ // Check Length to avoid data overflow. ++ // ++ if (HobLength > MAX_UINT16 - 0x7) { ++ return NULL; ++ } ++ + HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); + + FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; +@@ -269,6 +276,10 @@ BuildModuleHob ( + ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); + Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; +@@ -309,6 +320,9 @@ BuildResourceDescriptorHob ( + + Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); + ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->ResourceType = ResourceType; + Hob->ResourceAttribute = ResourceAttribute; +@@ -347,6 +361,11 @@ BuildGuidHob ( + ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); + + Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return NULL; ++ } ++ + CopyGuid (&Hob->Name, Guid); + return Hob + 1; + } +@@ -407,6 +426,10 @@ BuildFvHob ( + EFI_HOB_FIRMWARE_VOLUME *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -437,6 +460,10 @@ BuildFv2Hob ( + EFI_HOB_FIRMWARE_VOLUME2 *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -465,6 +492,10 @@ BuildCpuHob ( + EFI_HOB_CPU *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->SizeOfMemorySpace = SizeOfMemorySpace; + Hob->SizeOfIoSpace = SizeOfIoSpace; +@@ -500,6 +531,10 @@ BuildMemoryAllocationHob ( + ((Length & (EFI_PAGE_SIZE - 1)) == 0)); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; +-- +2.33.0 + diff --git a/0056-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH.patch b/0056-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH.patch new file mode 100644 index 0000000000000000000000000000000000000000..72d10b0fb8e2bffe779dc921069307b45d8e40fe --- /dev/null +++ b/0056-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH.patch @@ -0,0 +1,1591 @@ +From 0a7a6b211d4a997f1a38274560820381a0b56618 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:12:53 +0800 +Subject: [PATCH 01/13] NetworkPkg: Dhcp6Dxe: SECURITY PATCH + +Bug Details: +PixieFail Bug #2 +CVE-2023-45230 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds + of a Memory Buffer + +Changes Overview: +> -UINT8 * +> +EFI_STATUS +> Dhcp6AppendOption ( +> - IN OUT UINT8 *Buf, +> - IN UINT16 OptType, +> - IN UINT16 OptLen, +> - IN UINT8 *Data +> + IN OUT EFI_DHCP6_PACKET *Packet, +> + IN OUT UINT8 **PacketCursor, +> + IN UINT16 OptType, +> + IN UINT16 OptLen, +> + IN UINT8 *Data +> ); + +Dhcp6AppendOption() and variants can return errors now. All callsites +are adapted accordingly. + +It gets passed in EFI_DHCP6_PACKET as additional parameter ... + +> + // +> + // Verify the PacketCursor is within the packet +> + // +> + if ( (*PacketCursor < Packet->Dhcp6.Option) +> + || (*PacketCursor >= Packet->Dhcp6.Option + + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +> + { +> + return EFI_INVALID_PARAMETER; +> + } + +... so it can look at Packet->Size when checking buffer space. +Also to allow Packet->Length updates. + +Lots of checks added. + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/f31453e8d6542461d92d835e0b79fec8b039174d +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 ++++ + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 399 ++++++++++++++++++++--------- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 379 +++++++++++++++++++++------ + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 83 +++--- + 4 files changed, 671 insertions(+), 233 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +index f88b00ad..b3c9784e 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +@@ -47,6 +47,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; + #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') + #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') + ++// ++// For more information on DHCP options see RFC 8415, Section 21.1 ++// ++// The format of DHCP options is: ++// ++// 0 1 2 3 ++// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | option-code | option-len | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | option-data | ++// | (option-len octets) | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) ++#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) ++ ++// ++// Combined size of Code and Length ++// ++#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ ++ DHCP6_SIZE_OF_OPT_LEN) ++ ++STATIC_ASSERT ( ++ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4, ++ "Combined size of Code and Length must be 4 per RFC 8415" ++ ); ++ ++// ++// Offset to the length is just past the code ++// ++#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) ++STATIC_ASSERT ( ++ DHCP6_OPT_LEN_OFFSET (0) == 2, ++ "Offset of length is + 2 past start of option" ++ ); ++ ++#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) ++STATIC_ASSERT ( ++ DHCP6_OPT_DATA_OFFSET (0) == 4, ++ "Offset to option data should be +4 from start of option" ++ ); ++ + #define DHCP6_PACKET_ALL 0 + #define DHCP6_PACKET_STATEFUL 1 + #define DHCP6_PACKET_STATELESS 2 +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index c20876d5..71201ea7 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -3,9 +3,9 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent +- + **/ + + #include "Dhcp6Impl.h" +@@ -946,7 +946,8 @@ Dhcp6SendSolicitMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -960,26 +961,38 @@ Dhcp6SendSolicitMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -987,18 +1000,18 @@ Dhcp6SendSolicitMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption( +- Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1007,8 +1020,7 @@ Dhcp6SendSolicitMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1022,10 +1034,8 @@ Dhcp6SendSolicitMsg ( + Instance->StartTime = 0; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1037,6 +1047,14 @@ Dhcp6SendSolicitMsg ( + Elapsed, + Instance->Config->SolicitRetransmission + ); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1128,7 +1146,8 @@ Dhcp6SendRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1142,33 +1161,49 @@ Dhcp6SendRequestMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -1176,18 +1211,18 @@ Dhcp6SendRequestMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1196,8 +1231,7 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1213,14 +1247,21 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1286,7 +1327,8 @@ Dhcp6SendDeclineMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1300,32 +1342,50 @@ Dhcp6SendDeclineMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } ++ ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ DecIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType); +- +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1334,8 +1394,7 @@ Dhcp6SendDeclineMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1351,14 +1410,21 @@ Dhcp6SendDeclineMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1420,7 +1486,8 @@ Dhcp6SendReleaseMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1434,35 +1501,53 @@ Dhcp6SendReleaseMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // ServerId is extracted from packet, it's network order. + // +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } ++ ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ RelIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType); +- +- // +- // Determine the size/length of packet +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1471,8 +1556,7 @@ Dhcp6SendReleaseMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1484,14 +1568,21 @@ Dhcp6SendReleaseMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1551,7 +1642,8 @@ Dhcp6SendRenewRebindMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1565,26 +1657,38 @@ Dhcp6SendRenewRebindMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + if (!RebindRequest) { + // +@@ -1606,12 +1710,16 @@ Dhcp6SendRenewRebindMsg ( + + ServerId = (EFI_DHCP6_DUID *) (Option + 2); + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + // +@@ -1620,18 +1728,18 @@ Dhcp6SendRenewRebindMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption( +- Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1643,8 +1751,7 @@ Dhcp6SendRenewRebindMsg ( + Status = Dhcp6CallbackUser (Instance, Event, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1663,14 +1770,21 @@ Dhcp6SendRenewRebindMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1834,7 +1948,8 @@ Dhcp6SendInfoRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1851,26 +1966,38 @@ Dhcp6SendInfoRequestMsg ( + + if (SendClientId) { + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + OptionRequest->OpCode, + OptionRequest->OpLen, + OptionRequest->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -1878,18 +2005,18 @@ Dhcp6SendInfoRequestMsg ( + for (Index = 0; Index < OptionCount; Index++) { + + UserOpt = OptionList[Index]; +- Cursor = Dhcp6AppendOption( +- Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1903,14 +2030,21 @@ Dhcp6SendInfoRequestMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1962,7 +2096,8 @@ Dhcp6SendConfirmMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1976,44 +2111,56 @@ Dhcp6SendConfirmMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -2022,8 +2169,7 @@ Dhcp6SendConfirmMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -2039,14 +2185,21 @@ Dhcp6SendConfirmMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index d249a1cc..2b4005b4 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -601,24 +601,33 @@ Dhcp6OnTransmitted ( + + + /** +- Append the option to Buf, and move Buf to the end. ++ Append the option to Buf, update the length of packet, and move Buf to the end. + +- @param[in, out] Buf The pointer to the buffer. +- @param[in] OptType The option type. +- @param[in] OptLen The length of option contents. +- @param[in] Data The pointer to the option content. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. ++ @param[in] OptType The option type. ++ @param[in] OptLen The length of option contents. ++ @param[in] Data The pointer to the option content. + +- @return Buf The position to append the next option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendOption ( +- IN OUT UINT8 *Buf, +- IN UINT16 OptType, +- IN UINT16 OptLen, +- IN UINT8 *Data ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN UINT16 OptType, ++ IN UINT16 OptLen, ++ IN UINT8 *Data + ) + { ++ UINT32 Length; ++ UINT32 BytesNeeded; ++ + // + // The format of Dhcp6 option: + // +@@ -631,35 +640,94 @@ Dhcp6AppendOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + +- ASSERT (OptLen != 0); +- +- WriteUnaligned16 ((UINT16 *) Buf, OptType); +- Buf += 2; +- WriteUnaligned16 ((UINT16 *) Buf, OptLen); +- Buf += 2; +- CopyMem (Buf, Data, NTOHS (OptLen)); +- Buf += NTOHS (OptLen); +- +- return Buf; ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Data == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (OptLen == 0) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Calculate the bytes needed for the option ++ // ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ CopyMem (*PacketCursor, Data, NTOHS (OptLen)); ++ *PacketCursor += NTOHS (OptLen); ++ ++ // Update the packet length by the length of the option + 4 bytes ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + /** + Append the appointed IA Address option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] IaAddr The pointer to the IA Address. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaAddrOption ( +- IN OUT UINT8 *Buf, ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, + IN EFI_DHCP6_IA_ADDRESS *IaAddr, + IN UINT32 MessageType + ) + { ++ UINT32 BytesNeeded; ++ UINT32 Length; + + // The format of the IA Address option is: + // +@@ -682,17 +750,60 @@ Dhcp6AppendIaAddrOption ( + // . . + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (IaAddr == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (EFI_IPv6_ADDRESS); ++ // ++ // Even if the preferred-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->PreferredLifetime); ++ // ++ // Even if the valid-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of Ia Address option type + // +- WriteUnaligned16 ((UINT16 *) Buf, HTONS (Dhcp6OptIaAddr)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + +- WriteUnaligned16 ((UINT16 *) Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + +- CopyMem (Buf, &IaAddr->IpAddress, sizeof(EFI_IPv6_ADDRESS)); +- Buf += sizeof(EFI_IPv6_ADDRESS); ++ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); ++ *PacketCursor += sizeof (EFI_IPv6_ADDRESS); + + // + // Fill the value of preferred-lifetime and valid-lifetime. +@@ -700,43 +811,57 @@ Dhcp6AppendIaAddrOption ( + // should set to 0 when initiate a Confirm message. + // + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *) Buf, HTONL (IaAddr->PreferredLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); + } +- Buf += 4; ++ *PacketCursor += sizeof (IaAddr->PreferredLifetime); + + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *) Buf, HTONL (IaAddr->ValidLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); + } +- Buf += 4; +- +- return Buf; ++ *PacketCursor += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + + /** + Append the appointed Ia option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Ia The pointer to the Ia. + @param[in] T1 The time of T1. + @param[in] T2 The time of T2. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next Ia option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaOption ( +- IN OUT UINT8 *Buf, +- IN EFI_DHCP6_IA *Ia, +- IN UINT32 T1, +- IN UINT32 T2, +- IN UINT32 MessageType ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN EFI_DHCP6_IA *Ia, ++ IN UINT32 T1, ++ IN UINT32 T2, ++ IN UINT32 MessageType + ) + { +- UINT8 *AddrOpt; +- UINT16 *Len; +- UINTN Index; ++ UINT8 *AddrOpt; ++ UINT16 *Len; ++ UINTN Index; ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ EFI_STATUS Status; + + // + // The format of IA_NA and IA_TA option: +@@ -757,32 +882,75 @@ Dhcp6AppendIaOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Ia == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (Ia->Descriptor.IaId); ++ // ++ // + N for the IA_NA-options/IA_TA-options ++ // Dhcp6AppendIaAddrOption will need to check the length for each address ++ // ++ if (Ia->Descriptor.Type == Dhcp6OptIana) { ++ BytesNeeded += sizeof (T1) + sizeof (T2); ++ } ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = (UINT16)(Packet->Size - Packet->Length); ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ ++ + // + // Fill the value of Ia option type + // +- WriteUnaligned16 ((UINT16 *) Buf, HTONS (Ia->Descriptor.Type)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of Ia option later, keep the pointer first + // +- Len = (UINT16 *) Buf; +- Buf += 2; ++ Len = (UINT16 *)*PacketCursor; ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill the value of iaid + // +- WriteUnaligned32 ((UINT32 *) Buf, HTONL (Ia->Descriptor.IaId)); +- Buf += 4; ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); ++ *PacketCursor += sizeof (Ia->Descriptor.IaId); + + // + // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified. + // + if (Ia->Descriptor.Type == Dhcp6OptIana) { +- WriteUnaligned32 ((UINT32 *) Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff)); +- Buf += 4; +- WriteUnaligned32 ((UINT32 *) Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff)); +- Buf += 4; ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); ++ *PacketCursor += sizeof (T1); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); ++ *PacketCursor += sizeof (T2); + } + + // +@@ -790,35 +958,51 @@ Dhcp6AppendIaOption ( + // + for (Index = 0; Index < Ia->IaAddressCount; Index++) { + AddrOpt = (UINT8 *) Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); +- Buf = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *) AddrOpt, MessageType); ++ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } + } + + // + // Fill the value of Ia option length + // +- *Len = HTONS ((UINT16) (Buf - (UINT8 *) Len - 2)); ++ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); ++ ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; + +- return Buf; ++ return EFI_SUCCESS; + } + + /** + Append the appointed Elapsed time option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Instance The pointer to the Dhcp6 instance. + @param[out] Elapsed The pointer to the elapsed time value in +- the generated packet. ++ the generated packet. + +- @return Buf The position to append the next Ia option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendETOption ( +- IN OUT UINT8 *Buf, +- IN DHCP6_INSTANCE *Instance, +- OUT UINT16 **Elapsed ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN DHCP6_INSTANCE *Instance, ++ OUT UINT16 **Elapsed + ) + { ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ + // + // The format of elapsed time option: + // +@@ -830,27 +1014,70 @@ Dhcp6AppendETOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Instance == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((Elapsed == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ // ++ // + 2 for elapsed-time ++ // ++ BytesNeeded += sizeof (UINT16); ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of elapsed-time option type. + // +- WriteUnaligned16 ((UINT16 *) Buf, HTONS (Dhcp6OptElapsedTime)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of elapsed-time option, which is fixed. + // +- WriteUnaligned16 ((UINT16 *) Buf, HTONS(2)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill in elapsed time value with 0 value for now. The actual value is + // filled in later just before the packet is transmitted. + // +- WriteUnaligned16 ((UINT16 *) Buf, HTONS(0)); +- *Elapsed = (UINT16 *) Buf; +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); ++ *Elapsed = (UINT16 *)*PacketCursor; ++ *PacketCursor += sizeof (UINT16); + +- return Buf; ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + /** +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +index 2f18eb36..da351691 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +@@ -161,69 +161,84 @@ Dhcp6OnTransmitted ( + ); + + /** +- Append the appointed option to the buf, and move the buf to the end. +- +- @param[in, out] Buf The pointer to buffer. +- @param[in] OptType The option type. +- @param[in] OptLen The length of option content.s +- @param[in] Data The pointer to the option content. +- +- @return Buf The position to append the next option. +- ++ Append the option to Buf, update the length of packet, and move Buf to the end. ++ ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. ++ @param[in] OptType The option type. ++ @param[in] OptLen The length of option contents. ++ @param[in] Data The pointer to the option content. ++ ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendOption ( +- IN OUT UINT8 *Buf, +- IN UINT16 OptType, +- IN UINT16 OptLen, +- IN UINT8 *Data ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN UINT16 OptType, ++ IN UINT16 OptLen, ++ IN UINT8 *Data + ); + + /** +- Append the Ia option to Buf, and move Buf to the end. +- +- @param[in, out] Buf The pointer to the position to append. ++ Append the appointed Ia option to Buf, update the Ia option length, and move Buf ++ to the end of the option. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Ia The pointer to the Ia. + @param[in] T1 The time of T1. + @param[in] T2 The time of T2. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next Ia option. +- ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaOption ( +- IN OUT UINT8 *Buf, +- IN EFI_DHCP6_IA *Ia, +- IN UINT32 T1, +- IN UINT32 T2, +- IN UINT32 MessageType ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN EFI_DHCP6_IA *Ia, ++ IN UINT32 T1, ++ IN UINT32 T2, ++ IN UINT32 MessageType + ); + + /** + Append the appointed Elapsed time option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Instance The pointer to the Dhcp6 instance. + @param[out] Elapsed The pointer to the elapsed time value in + the generated packet. + +- @return Buf The position to append the next Ia option. +- ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendETOption ( +- IN OUT UINT8 *Buf, +- IN DHCP6_INSTANCE *Instance, +- OUT UINT16 **Elapsed ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN DHCP6_INSTANCE *Instance, ++ OUT UINT16 **Elapsed + ); + + /** + Set the elapsed time based on the given instance and the pointer to the + elapsed time option. + +- @param[in] Elapsed The pointer to the position to append. +- @param[in] Instance The pointer to the Dhcp6 instance. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ + VOID + SetElapsedTime ( +-- +2.33.0 + diff --git a/0057-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch b/0057-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch new file mode 100644 index 0000000000000000000000000000000000000000..63db25ce84932da6e735cd6a1ee410ef032f510e --- /dev/null +++ b/0057-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch @@ -0,0 +1,150 @@ +From 80eb751a77931e65afd37bf371d9b15345abd434 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:15:18 +0800 +Subject: [PATCH 02/13] NetworkPkg: : Add Unit tests to CI and create Host Test + DSC + +Adds Host Based testing to the NetworkPkg + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/8014ac2d7bbbc503f5562b51af46bb20ae3d22ff +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/NetworkPkg.ci.yaml | 7 +- + NetworkPkg/Test/NetworkPkgHostTest.dsc | 98 ++++++++++++++++++++++++++ + 2 files changed, 104 insertions(+), 1 deletion(-) + create mode 100644 NetworkPkg/Test/NetworkPkgHostTest.dsc + +diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml +index 1a3ab717..322ae2b0 100644 +--- a/NetworkPkg/NetworkPkg.ci.yaml ++++ b/NetworkPkg/NetworkPkg.ci.yaml +@@ -23,6 +23,9 @@ + "CompilerPlugin": { + "DscPath": "NetworkPkg.dsc" + }, ++ "HostUnitTestCompilerPlugin": { ++ "DscPath": "Test/NetworkPkgHostTest.dsc" ++ }, + "CharEncodingCheck": { + "IgnoreFiles": [] + }, +@@ -34,7 +37,9 @@ + "CryptoPkg/CryptoPkg.dec" + ], + # For host based unit tests +- "AcceptableDependencies-HOST_APPLICATION":[], ++ "AcceptableDependencies-HOST_APPLICATION":[ ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec ++ ], + # For UEFI shell based apps + "AcceptableDependencies-UEFI_APPLICATION":[ + "ShellPkg/ShellPkg.dec" +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +new file mode 100644 +index 00000000..b74b2048 +--- /dev/null ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -0,0 +1,98 @@ ++## @file ++# NetworkPkgHostTest DSC file used to build host-based unit tests. ++# ++# Copyright (c) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++# ++## ++[Defines] ++ PLATFORM_NAME = NetworkPkgHostTest ++ PLATFORM_GUID = 3b68324e-fc07-4d49-9520-9347ede65879 ++ PLATFORM_VERSION = 0.1 ++ DSC_SPECIFICATION = 0x00010005 ++ OUTPUT_DIRECTORY = Build/NetworkPkg/HostTest ++ SUPPORTED_ARCHITECTURES = IA32|X64|AARCH64 ++ BUILD_TARGETS = NOOPT ++ SKUID_IDENTIFIER = DEFAULT ++ ++!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc ++[Packages] ++ MdePkg/MdePkg.dec ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec ++ ++[Components] ++ # ++ # Build HOST_APPLICATION that tests NetworkPkg ++ # ++ ++# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. ++[LibraryClasses] ++ NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf ++ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf ++ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf ++ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf ++ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf ++ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf ++ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ++ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf ++ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf ++ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf ++ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf ++ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf ++ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf ++ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf ++ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf ++ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf ++ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf ++ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf ++ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf ++ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf ++ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf ++ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf ++ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf ++ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf ++!ifdef CONTINUOUS_INTEGRATION ++ BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf ++ TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf ++!else ++ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf ++ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf ++ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf ++!endif ++ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf ++ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf ++ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf ++ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf ++ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf ++ ++!if $(TOOL_CHAIN_TAG) == VS2019 or $(TOOL_CHAIN_TAG) == VS2022 ++[LibraryClasses.X64] ++ # Provide StackCookie support lib so that we can link to /GS exports for VS builds ++ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf ++!endif ++ ++[LibraryClasses.common.UEFI_DRIVER] ++ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf ++ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf ++ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf ++[LibraryClasses.common.UEFI_APPLICATION] ++ DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf ++ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf ++[LibraryClasses.ARM, LibraryClasses.AARCH64] ++ # ++ # It is not possible to prevent ARM compiler calls to generic intrinsic functions. ++ # This library provides the instrinsic functions generated by a given compiler. ++ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. ++ # ++!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019 ++ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf ++!endif ++ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf ++[LibraryClasses.ARM] ++ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf ++[LibraryClasses.RISCV64] ++ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf ++ ++[PcdsFixedAtBuild] ++ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2 ++ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|0x4 +-- +2.33.0 + diff --git a/0058-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch b/0058-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch new file mode 100644 index 0000000000000000000000000000000000000000..68e88b750a011d8f3ac22cac19dfa259895761c2 --- /dev/null +++ b/0058-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch @@ -0,0 +1,608 @@ +From 820c22ca2efd5ed14ebe410a04ff6a920c6a377b Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:16:43 +0800 +Subject: [PATCH 03/13] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 + Unit Tests + +Confirms that reported issue... + +"Buffer overflow in the DHCPv6 client via a long Server ID option" + +..has been corrected by the provided patch. + +Tests the following functions to ensure they appropriately handle +untrusted data (either too long or too small) to prevent a buffer +overflow: + +Dhcp6AppendOption +Dhcp6AppendETOption +Dhcp6AppendIaOption + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/5f3658197bf29c83b3349b0ab1d99cdb0c3814bc +Signed-off-by: yexiao yexiao7@huawei.com +--- + .../GoogleTest/Dhcp6DxeGoogleTest.cpp | 20 + + .../GoogleTest/Dhcp6DxeGoogleTest.inf | 43 ++ + .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++ + NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + + 4 files changed, 542 insertions(+) + create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp + create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp + +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp +new file mode 100644 +index 00000000..311b3992 +--- /dev/null ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp +@@ -0,0 +1,20 @@ ++/** @file ++ Acts as the main entry point for the tests for the Dhcp6Dxe module. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Run the tests ++//////////////////////////////////////////////////////////////////////////////// ++int ++main ( ++ int argc, ++ char *argv[] ++ ) ++{ ++ testing::InitGoogleTest (&argc, argv); ++ return RUN_ALL_TESTS (); ++} +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf +new file mode 100644 +index 00000000..253c61e8 +--- /dev/null ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf +@@ -0,0 +1,43 @@ ++## @file ++# Unit test suite for the Dhcp6Dxe using Google Test ++# ++# Copyright (c) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++[Defines] ++ INF_VERSION = 0x00010017 ++ BASE_NAME = Dhcp6DxeGoogleTest ++ FILE_GUID = 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9 ++ VERSION_STRING = 1.0 ++ MODULE_TYPE = HOST_APPLICATION ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 AARCH64 ++# ++[Sources] ++ Dhcp6DxeGoogleTest.cpp ++ Dhcp6IoGoogleTest.cpp ++ ../Dhcp6Io.c ++ ../Dhcp6Utility.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec ++ NetworkPkg/NetworkPkg.dec ++ ++[LibraryClasses] ++ GoogleTestLib ++ DebugLib ++ NetLib ++ PcdLib ++ ++[Protocols] ++ gEfiDhcp6ServiceBindingProtocolGuid ++ ++[Pcd] ++ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType ++ ++[Guids] ++ gZeroGuid +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp +new file mode 100644 +index 00000000..a2b8a9f8 +--- /dev/null ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp +@@ -0,0 +1,478 @@ ++/** @file ++ Tests for Dhcp6Io.c. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++extern "C" { ++ #include ++ #include ++ #include ++ #include ++ #include "../Dhcp6Impl.h" ++ #include "../Dhcp6Utility.h" ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Defines ++//////////////////////////////////////////////////////////////////////// ++ ++#define DHCP6_PACKET_MAX_LEN 1500 ++ ++//////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////// ++// Symbol Definitions ++// These functions are not directly under test - but required to compile ++//////////////////////////////////////////////////////////////////////// ++ ++// This definition is used by this test but is also required to compile ++// by Dhcp6Io.c ++EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = { ++ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 } ++}; ++ ++EFI_STATUS ++EFIAPI ++UdpIoSendDatagram ( ++ IN UDP_IO *UdpIo, ++ IN NET_BUF *Packet, ++ IN UDP_END_POINT *EndPoint OPTIONAL, ++ IN EFI_IP_ADDRESS *Gateway OPTIONAL, ++ IN UDP_IO_CALLBACK CallBack, ++ IN VOID *Context ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++EFI_STATUS ++EFIAPI ++UdpIoRecvDatagram ( ++ IN UDP_IO *UdpIo, ++ IN UDP_IO_CALLBACK CallBack, ++ IN VOID *Context, ++ IN UINT32 HeadLen ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Dhcp6AppendOptionTest Tests ++//////////////////////////////////////////////////////////////////////// ++ ++class Dhcp6AppendOptionTest : public ::testing::Test { ++public: ++ UINT8 *Buffer = NULL; ++ EFI_DHCP6_PACKET *Packet; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); ++ ASSERT_NE (Buffer, (UINT8 *)NULL); ++ ++ Packet = (EFI_DHCP6_PACKET *)Buffer; ++ Packet->Size = DHCP6_PACKET_MAX_LEN; ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ if (Buffer != NULL) { ++ FreePool (Buffer); ++ } ++ } ++}; ++ ++// Test Description: ++// Attempt to append an option to a packet that is too small by a duid that is too large ++TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) { ++ UINT8 *Cursor; ++ EFI_DHCP6_DUID *UntrustedDuid; ++ EFI_STATUS Status; ++ ++ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID)); ++ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); ++ ++ UntrustedDuid->Length = NTOHS (0xFFFF); ++ ++ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option; ++ ++ Status = Dhcp6AppendOption ( ++ Dhcp6AppendOptionTest::Packet, ++ &Cursor, ++ HTONS (Dhcp6OptServerId), ++ UntrustedDuid->Length, ++ UntrustedDuid->Duid ++ ); ++ ++ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); ++} ++ ++// Test Description: ++// Attempt to append an option to a packet that is large enough ++TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) { ++ UINT8 *Cursor; ++ EFI_DHCP6_DUID *UntrustedDuid; ++ EFI_STATUS Status; ++ UINTN OriginalLength; ++ ++ UINT8 Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; ++ ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ OriginalLength = Packet->Length; ++ ++ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID)); ++ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); ++ ++ UntrustedDuid->Length = NTOHS (sizeof (Duid)); ++ CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid)); ++ ++ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option; ++ ++ Status = Dhcp6AppendOption ( ++ Dhcp6AppendOptionTest::Packet, ++ &Cursor, ++ HTONS (Dhcp6OptServerId), ++ UntrustedDuid->Length, ++ UntrustedDuid->Duid ++ ); ++ ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ // verify that the pointer to cursor moved by the expected amount ++ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4); ++ ++ // verify that the length of the packet is now the expected amount ++ ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4); ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Dhcp6AppendETOption Tests ++//////////////////////////////////////////////////////////////////////// ++ ++class Dhcp6AppendETOptionTest : public ::testing::Test { ++public: ++ UINT8 *Buffer = NULL; ++ EFI_DHCP6_PACKET *Packet; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); ++ ASSERT_NE (Buffer, (UINT8 *)NULL); ++ ++ Packet = (EFI_DHCP6_PACKET *)Buffer; ++ Packet->Size = DHCP6_PACKET_MAX_LEN; ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ if (Buffer != NULL) { ++ FreePool (Buffer); ++ } ++ } ++}; ++ ++// Test Description: ++// Attempt to append an option to a packet that is too small by a duid that is too large ++TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ DHCP6_INSTANCE Instance; ++ UINT16 ElapsedTimeVal; ++ UINT16 *ElapsedTime; ++ ++ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; ++ ElapsedTime = &ElapsedTimeVal; ++ ++ Packet->Length = Packet->Size - 2; ++ ++ Status = Dhcp6AppendETOption ( ++ Dhcp6AppendETOptionTest::Packet, ++ &Cursor, ++ &Instance, // Instance is not used in this function ++ &ElapsedTime ++ ); ++ ++ // verify that we error out because the packet is too small for the option header ++ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); ++ ++ // reset the length ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++} ++ ++// Test Description: ++// Attempt to append an option to a packet that is large enough ++TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ DHCP6_INSTANCE Instance; ++ UINT16 ElapsedTimeVal; ++ UINT16 *ElapsedTime; ++ UINTN ExpectedSize; ++ UINTN OriginalLength; ++ ++ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; ++ ElapsedTime = &ElapsedTimeVal; ++ ExpectedSize = 6; ++ OriginalLength = Packet->Length; ++ ++ Status = Dhcp6AppendETOption ( ++ Dhcp6AppendETOptionTest::Packet, ++ &Cursor, ++ &Instance, // Instance is not used in this function ++ &ElapsedTime ++ ); ++ ++ // verify that the status is EFI_SUCCESS ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ // verify that the pointer to cursor moved by the expected amount ++ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize); ++ ++ // verify that the length of the packet is now the expected amount ++ ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize); ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Dhcp6AppendIaOption Tests ++//////////////////////////////////////////////////////////////////////// ++ ++class Dhcp6AppendIaOptionTest : public ::testing::Test { ++public: ++ UINT8 *Buffer = NULL; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_IA *Ia; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); ++ ASSERT_NE (Buffer, (UINT8 *)NULL); ++ ++ Packet = (EFI_DHCP6_PACKET *)Buffer; ++ Packet->Size = DHCP6_PACKET_MAX_LEN; ++ ++ Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2); ++ ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL); ++ ++ CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS)); ++ CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS)); ++ ++ Ia->IaAddressCount = 2; ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ if (Buffer != NULL) { ++ FreePool (Buffer); ++ } ++ ++ if (Ia != NULL) { ++ FreePool (Ia); ++ } ++ } ++}; ++ ++// Test Description: ++// Attempt to append an option to a packet that doesn't have enough space ++// for the option header ++TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ ++ Packet->Length = Packet->Size - 2; ++ ++ Ia->Descriptor.Type = Dhcp6OptIana; ++ Ia->Descriptor.IaId = 0x12345678; ++ ++ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; ++ ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6AppendIaOptionTest::Packet, ++ &Cursor, ++ Ia, ++ 0x12345678, ++ 0x11111111, ++ Dhcp6OptIana ++ ); ++ ++ // verify that we error out because the packet is too small for the option header ++ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); ++ ++ // reset the length ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++} ++ ++// Test Description: ++// Attempt to append an option to a packet that doesn't have enough space ++// for the option header ++TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ ++ // Use up nearly all the space in the packet ++ Packet->Length = Packet->Size - 2; ++ ++ Ia->Descriptor.Type = Dhcp6OptIata; ++ Ia->Descriptor.IaId = 0x12345678; ++ ++ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; ++ ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6AppendIaOptionTest::Packet, ++ &Cursor, ++ Ia, ++ 0, ++ 0, ++ Dhcp6OptIata ++ ); ++ ++ // verify that we error out because the packet is too small for the option header ++ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); ++ ++ // reset the length ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++} ++ ++TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ UINTN ExpectedSize; ++ UINTN OriginalLength; ++ ++ // ++ // 2 bytes for the option header type ++ // ++ ExpectedSize = 2; ++ // ++ // 2 bytes for the option header length ++ // ++ ExpectedSize += 2; ++ // ++ // 4 bytes for the IAID ++ // ++ ExpectedSize += 4; ++ // ++ // + 4 bytes for the T1 ++ // ++ ExpectedSize += 4; ++ // ++ // + 4 bytes for the T2 ++ // ++ ExpectedSize += 4; ++ // ++ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; ++ // + 2 bytes for the option header type ++ // + 2 bytes for the option header length ++ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address ++ // ++ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; ++ ++ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; ++ ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ OriginalLength = Packet->Length; ++ ++ Ia->Descriptor.Type = Dhcp6OptIana; ++ Ia->Descriptor.IaId = 0x12345678; ++ ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6AppendIaOptionTest::Packet, ++ &Cursor, ++ Ia, ++ 0x12345678, ++ 0x12345678, ++ Dhcp6OptIana ++ ); ++ ++ // verify that the pointer to cursor moved by the expected amount ++ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize); ++ ++ // verify that the length of the packet is now the expected amount ++ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize); ++ ++ // verify that the status is EFI_SUCCESS ++ ASSERT_EQ (Status, EFI_SUCCESS); ++} ++ ++TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) { ++ UINT8 *Cursor; ++ EFI_STATUS Status; ++ UINTN ExpectedSize; ++ UINTN OriginalLength; ++ ++ // ++ // 2 bytes for the option header type ++ // ++ ExpectedSize = 2; ++ // ++ // 2 bytes for the option header length ++ // ++ ExpectedSize += 2; ++ // ++ // 4 bytes for the IAID ++ // ++ ExpectedSize += 4; ++ // ++ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; ++ // + 2 bytes for the option header type ++ // + 2 bytes for the option header length ++ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address ++ // ++ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; ++ ++ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; ++ ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ OriginalLength = Packet->Length; ++ ++ Ia->Descriptor.Type = Dhcp6OptIata; ++ Ia->Descriptor.IaId = 0x12345678; ++ ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6AppendIaOptionTest::Packet, ++ &Cursor, ++ Ia, ++ 0, ++ 0, ++ Dhcp6OptIata ++ ); ++ ++ // verify that the pointer to cursor moved by the expected amount ++ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize); ++ ++ // verify that the length of the packet is now the expected amount ++ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize); ++ ++ // verify that the status is EFI_SUCCESS ++ ASSERT_EQ (Status, EFI_SUCCESS); ++} +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index b74b2048..7df011c9 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -24,6 +24,7 @@ + # + # Build HOST_APPLICATION that tests NetworkPkg + # ++ NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + + # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. + [LibraryClasses] +-- +2.33.0 + diff --git a/0059-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch b/0059-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch new file mode 100644 index 0000000000000000000000000000000000000000..a9f05083e81207cbef74a6d808fc84bba6f41516 --- /dev/null +++ b/0059-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch @@ -0,0 +1,594 @@ +From c26e6df4c87cceef2ec0675d8f319f0bb937e55f Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:17:52 +0800 +Subject: [PATCH 04/13] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 + Patch + +Bug Details: +PixieFail Bug #1 +CVE-2023-45229 +CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N +CWE-125 Out-of-bounds Read + +Change Overview: + +Introduce Dhcp6SeekInnerOptionSafe which performs checks before seeking +the Inner Option from a DHCP6 Option. + +> +> EFI_STATUS +> Dhcp6SeekInnerOptionSafe ( +> IN UINT16 IaType, +> IN UINT8 *Option, +> IN UINT32 OptionLen, +> OUT UINT8 **IaInnerOpt, +> OUT UINT16 *IaInnerLen +> ); +> + +Lots of code cleanup to improve code readability. + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/1dbb10cc52dc8ef49bb700daa1cefc76b26d52e0 +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 138 +++++++++++++++++++--- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 200 +++++++++++++++++++++----------- + 2 files changed, 253 insertions(+), 85 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +index b3c9784e..dd7afd4a 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +@@ -47,6 +47,20 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; + #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') + #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') + ++#define DHCP6_PACKET_ALL 0 ++#define DHCP6_PACKET_STATEFUL 1 ++#define DHCP6_PACKET_STATELESS 2 ++ ++#define DHCP6_BASE_PACKET_SIZE 1024 ++ ++#define DHCP6_PORT_CLIENT 546 ++#define DHCP6_PORT_SERVER 547 ++ ++#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) ++ ++#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE) ++#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE) ++ + // + // For more information on DHCP options see RFC 8415, Section 21.1 + // +@@ -61,12 +75,10 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; + // | (option-len octets) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // +-#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) +-#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) ++#define DHCP6_SIZE_OF_OPT_CODE (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode)) ++#define DHCP6_SIZE_OF_OPT_LEN (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) + +-// + // Combined size of Code and Length +-// + #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ + DHCP6_SIZE_OF_OPT_LEN) + +@@ -75,34 +87,122 @@ STATIC_ASSERT ( + "Combined size of Code and Length must be 4 per RFC 8415" + ); + +-// + // Offset to the length is just past the code +-// +-#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) ++#define DHCP6_OFFSET_OF_OPT_LEN(a) (a + DHCP6_SIZE_OF_OPT_CODE) + STATIC_ASSERT ( +- DHCP6_OPT_LEN_OFFSET (0) == 2, ++ DHCP6_OFFSET_OF_OPT_LEN (0) == 2, + "Offset of length is + 2 past start of option" + ); + +-#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) ++#define DHCP6_OFFSET_OF_OPT_DATA(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) + STATIC_ASSERT ( +- DHCP6_OPT_DATA_OFFSET (0) == 4, ++ DHCP6_OFFSET_OF_OPT_DATA (0) == 4, + "Offset to option data should be +4 from start of option" + ); ++// ++// Identity Association options (both NA (Non-Temporary) and TA (Temporary Association)) ++// are defined in RFC 8415 and are a deriviation of a TLV stucture ++// For more information on IA_NA see Section 21.4 ++// For more information on IA_TA see Section 21.5 ++// ++// ++// The format of IA_NA and IA_TA option: ++// ++// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | OPTION_IA_NA | option-len | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | IAID (4 octets) | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | T1 (only for IA_NA) | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | T2 (only for IA_NA) | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | | ++// . IA_NA-options/IA_TA-options . ++// . . ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++#define DHCP6_SIZE_OF_IAID (sizeof(UINT32)) ++#define DHCP6_SIZE_OF_TIME_INTERVAL (sizeof(UINT32)) + +-#define DHCP6_PACKET_ALL 0 +-#define DHCP6_PACKET_STATEFUL 1 +-#define DHCP6_PACKET_STATELESS 2 ++// Combined size of IAID, T1, and T2 ++#define DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 (DHCP6_SIZE_OF_IAID + \ ++ DHCP6_SIZE_OF_TIME_INTERVAL + \ ++ DHCP6_SIZE_OF_TIME_INTERVAL) ++STATIC_ASSERT ( ++ DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 == 12, ++ "Combined size of IAID, T1, T2 must be 12 per RFC 8415" ++ ); + +-#define DHCP6_BASE_PACKET_SIZE 1024 ++// This is the size of IA_TA without options ++#define DHCP6_MIN_SIZE_OF_IA_TA (DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ ++ DHCP6_SIZE_OF_IAID) ++STATIC_ASSERT ( ++ DHCP6_MIN_SIZE_OF_IA_TA == 8, ++ "Minimum combined size of IA_TA per RFC 8415" ++ ); + +-#define DHCP6_PORT_CLIENT 546 +-#define DHCP6_PORT_SERVER 547 ++// Offset to a IA_TA inner option ++#define DHCP6_OFFSET_OF_IA_TA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_TA) ++STATIC_ASSERT ( ++ DHCP6_OFFSET_OF_IA_TA_INNER_OPT (0) == 8, ++ "Offset of IA_TA Inner option is + 8 past start of option" ++ ); ++ ++// This is the size of IA_NA without options (16) ++#define DHCP6_MIN_SIZE_OF_IA_NA DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ ++ DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 ++STATIC_ASSERT ( ++ DHCP6_MIN_SIZE_OF_IA_NA == 16, ++ "Minimum combined size of IA_TA per RFC 8415" ++ ); ++ ++#define DHCP6_OFFSET_OF_IA_NA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_NA) ++STATIC_ASSERT ( ++ DHCP6_OFFSET_OF_IA_NA_INNER_OPT (0) == 16, ++ "Offset of IA_NA Inner option is + 16 past start of option" ++ ); ++ ++#define DHCP6_OFFSET_OF_IA_NA_T1(a) (a + \ ++ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ ++ DHCP6_SIZE_OF_IAID) ++STATIC_ASSERT ( ++ DHCP6_OFFSET_OF_IA_NA_T1 (0) == 8, ++ "Offset of IA_NA Inner option is + 8 past start of option" ++ ); + +-#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) ++#define DHCP6_OFFSET_OF_IA_NA_T2(a) (a + \ ++ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN +\ ++ DHCP6_SIZE_OF_IAID + \ ++ DHCP6_SIZE_OF_TIME_INTERVAL) ++STATIC_ASSERT ( ++ DHCP6_OFFSET_OF_IA_NA_T2 (0) == 12, ++ "Offset of IA_NA Inner option is + 12 past start of option" ++ ); + +-#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE) +-#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE) ++// ++// For more information see RFC 8415 Section 21.13 ++// ++// The format of the Status Code Option: ++// ++// 0 1 2 3 ++// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | OPTION_STATUS_CODE | option-len | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | status-code | | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ++// . . ++// . status-message . ++// . . ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++#define DHCP6_OFFSET_OF_STATUS_CODE(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) ++STATIC_ASSERT ( ++ DHCP6_OFFSET_OF_STATUS_CODE (0) == 4, ++ "Offset of status is + 4 past start of option" ++ ); + + extern EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress; + extern EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate; +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index 71201ea7..db1ee4af 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -611,8 +611,8 @@ Dhcp6UpdateIaInfo ( + // The inner options still start with 2 bytes option-code and 2 bytes option-len. + // + if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { +- T1 = NTOHL (ReadUnaligned32 ((UINT32 *) (Option + 8))); +- T2 = NTOHL (ReadUnaligned32 ((UINT32 *) (Option + 12))); ++ T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); ++ T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); + // + // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, + // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes +@@ -621,13 +621,14 @@ Dhcp6UpdateIaInfo ( + if (T1 > T2 && T2 > 0) { + return EFI_DEVICE_ERROR; + } +- IaInnerOpt = Option + 16; +- IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 2))) - 12); ++ IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); ++ IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); + } else { + T1 = 0; + T2 = 0; +- IaInnerOpt = Option + 8; +- IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 2))) - 4); ++ ++ IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); ++ IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); + } + + // +@@ -653,7 +654,7 @@ Dhcp6UpdateIaInfo ( + Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + + if (Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 4))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -673,7 +674,86 @@ Dhcp6UpdateIaInfo ( + return Status; + } + +- ++/** ++ Seeks the Inner Options from a DHCP6 Option ++ ++ @param[in] IaType The type of the IA option. ++ @param[in] Option The pointer to the DHCP6 Option. ++ @param[in] OptionLen The length of the DHCP6 Option. ++ @param[out] IaInnerOpt The pointer to the IA inner option. ++ @param[out] IaInnerLen The length of the IA inner option. ++ ++ @retval EFI_SUCCESS Seek the inner option successfully. ++ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, ++ the pointers are not modified ++**/ ++EFI_STATUS ++Dhcp6SeekInnerOptionSafe ( ++ IN UINT16 IaType, ++ IN UINT8 *Option, ++ IN UINT32 OptionLen, ++ OUT UINT8 **IaInnerOpt, ++ OUT UINT16 *IaInnerLen ++ ) ++{ ++ UINT16 IaInnerLenTmp; ++ UINT8 *IaInnerOptTmp; ++ ++ if (Option == NULL) { ++ ASSERT (Option != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaInnerOpt == NULL) { ++ ASSERT (IaInnerOpt != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaInnerLen == NULL) { ++ ASSERT (IaInnerLen != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaType == Dhcp6OptIana) { ++ // Verify we have a fully formed IA_NA ++ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); ++ ++ // Verify the IaInnerLen is valid. ++ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); ++ if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; ++ } else if (IaType == Dhcp6OptIata) { ++ // Verify the OptionLen is valid. ++ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); ++ ++ // Verify the IaInnerLen is valid. ++ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); ++ if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; ++ } else { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ *IaInnerOpt = IaInnerOptTmp; ++ *IaInnerLen = IaInnerLenTmp; ++ ++ return EFI_SUCCESS; ++} + + /** + Seek StatusCode Option in package. A Status Code option may appear in the +@@ -698,6 +778,12 @@ Dhcp6SeekStsOption ( + UINT8 *IaInnerOpt; + UINT16 IaInnerLen; + UINT16 StsCode; ++ UINT32 OptionLen; ++ ++ // OptionLen is the length of the Options excluding the DHCP header. ++ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last ++ // byte of the Option[] field. ++ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); + + // + // Seek StatusCode option directly in DHCP message body. That is, search in +@@ -705,12 +791,12 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ OptionLen, + Dhcp6OptStatusCode + ); + + if (*Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 4))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -721,7 +807,7 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekIaOption ( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ OptionLen, + &Instance->Config->IaDescriptor + ); + if (*Option == NULL) { +@@ -729,52 +815,34 @@ Dhcp6SeekStsOption ( + } + + // +- // The format of the IA_NA option is: ++ // Calculate the distance from Packet->Dhcp6.Option to the IA option. + // +- // 0 1 2 3 +- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | OPTION_IA_NA | option-len | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | IAID (4 octets) | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | T1 | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | T2 | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | | +- // . IA_NA-options . +- // . . +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // +- // The format of the IA_TA option is: ++ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is ++ // the size of the whole packet, including the DHCP header, and Packet->Length ++ // is the length of the DHCP message body, excluding the DHCP header. + // +- // 0 1 2 3 +- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | OPTION_IA_TA | option-len | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | IAID (4 octets) | +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +- // | | +- // . IA_TA-options . +- // . . +- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of ++ // DHCP6 option area to the start of the IA option. + // +- ++ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the ++ // IA option to the end of the DHCP6 option area, thus subtract the space ++ // up until this option + // +- // sizeof (option-code + option-len + IaId) = 8 +- // sizeof (option-code + option-len + IaId + T1) = 12 +- // sizeof (option-code + option-len + IaId + T1 + T2) = 16 ++ OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option); + // +- // The inner options still start with 2 bytes option-code and 2 bytes option-len. ++ // Seek the inner option + // +- if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { +- IaInnerOpt = *Option + 16; +- IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 2))) - 12); +- } else { +- IaInnerOpt = *Option + 8; +- IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 2))) - 4); ++ if (EFI_ERROR ( ++ Dhcp6SeekInnerOptionSafe ( ++ Instance->Config->IaDescriptor.Type, ++ *Option, ++ OptionLen, ++ &IaInnerOpt, ++ &IaInnerLen ++ ) ++ )) ++ { ++ return EFI_DEVICE_ERROR; + } + + // +@@ -798,7 +866,7 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + if (*Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 4))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -1124,7 +1192,7 @@ Dhcp6SendRequestMsg ( + // + Option = Dhcp6SeekOption ( + Instance->AdSelect->Dhcp6.Option, +- Instance->AdSelect->Length - 4, ++ Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1310,7 +1378,7 @@ Dhcp6SendDeclineMsg ( + // + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - 4, ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1472,7 +1540,7 @@ Dhcp6SendReleaseMsg ( + // + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - 4, ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1700,7 +1768,7 @@ Dhcp6SendRenewRebindMsg ( + + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - 4, ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -2245,7 +2313,7 @@ Dhcp6HandleReplyMsg ( + // + Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptRapidCommit + ); + +@@ -2393,7 +2461,7 @@ Dhcp6HandleReplyMsg ( + // + // Any error status code option is found. + // +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 4))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); + switch (StsCode) { + case Dhcp6StsUnspecFail: + // +@@ -2524,7 +2592,7 @@ Dhcp6SelectAdvertiseMsg ( + // + Option = Dhcp6SeekOption( + AdSelect->Dhcp6.Option, +- AdSelect->Length - 4, ++ AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerUnicast + ); + +@@ -2536,7 +2604,7 @@ Dhcp6SelectAdvertiseMsg ( + return EFI_OUT_OF_RESOURCES; + } + +- CopyMem (Instance->Unicast, Option + 4, sizeof(EFI_IPv6_ADDRESS)); ++ CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); + } + + // +@@ -2590,7 +2658,7 @@ Dhcp6HandleAdvertiseMsg ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptRapidCommit + ); + +@@ -2686,7 +2754,7 @@ Dhcp6HandleAdvertiseMsg ( + CopyMem (Instance->AdSelect, Packet, Packet->Size); + + if (Option != NULL) { +- Instance->AdPref = *(Option + 4); ++ Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); + } + } else { + // +@@ -2757,11 +2825,11 @@ Dhcp6HandleStateful ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptClientId + ); + +- if (Option == NULL || CompareMem (Option + 4, ClientId->Duid, ClientId->Length) != 0) { ++ if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { + goto ON_CONTINUE; + } + +@@ -2770,7 +2838,7 @@ Dhcp6HandleStateful ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptServerId + ); + +@@ -2875,7 +2943,7 @@ Dhcp6HandleStateless ( + // + Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- Packet->Length - 4, ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + +-- +2.33.0 + diff --git a/0060-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch b/0060-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch new file mode 100644 index 0000000000000000000000000000000000000000..101aef67b8a9cc3c07ad9a509a0da10460093928 --- /dev/null +++ b/0060-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch @@ -0,0 +1,530 @@ +From 5dcddb05474ca2cbf4f22141da39aedac62314fc Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:19:24 +0800 +Subject: [PATCH 05/13] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 + Unit Tests + +These tests confirm that the report bug... + +"Out-of-bounds read when processing IA_NA/IA_TA options in a +DHCPv6 Advertise message" + +..has been patched. + +The following functions are tested to confirm an out of bounds read is +patched and that the correct statuses are returned: + +Dhcp6SeekInnerOptionSafe +Dhcp6SeekStsOption + +TCBZ4534 +CVE-2023-45229 +CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N +CWE-125 Out-of-bounds Read + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/07362769ab7a7d74dbea1c7a7a3662c7b5d1f097 +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 2 +- + .../GoogleTest/Dhcp6DxeGoogleTest.inf | 1 + + .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 365 +++++++++++++++++- + .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h | 58 +++ + 4 files changed, 423 insertions(+), 3 deletions(-) + create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index db1ee4af..9a31c118 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -828,7 +828,7 @@ Dhcp6SeekStsOption ( + // IA option to the end of the DHCP6 option area, thus subtract the space + // up until this option + // +- OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option); ++ OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); + // + // Seek the inner option + // +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf +index 253c61e8..94ebdf63 100644 +--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf +@@ -18,6 +18,7 @@ + [Sources] + Dhcp6DxeGoogleTest.cpp + Dhcp6IoGoogleTest.cpp ++ Dhcp6IoGoogleTest.h + ../Dhcp6Io.c + ../Dhcp6Utility.c + +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp +index a2b8a9f8..3bb70371 100644 +--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp +@@ -13,6 +13,7 @@ extern "C" { + #include + #include "../Dhcp6Impl.h" + #include "../Dhcp6Utility.h" ++ #include "Dhcp6IoGoogleTest.h" + } + + //////////////////////////////////////////////////////////////////////// +@@ -21,7 +22,35 @@ extern "C" { + + #define DHCP6_PACKET_MAX_LEN 1500 + ++// This definition is used by this test but is also required to compile ++// by Dhcp6Io.c ++#define DHCPV6_OPTION_IA_NA 3 ++#define DHCPV6_OPTION_IA_TA 4 ++ ++#define SEARCH_PATTERN 0xDEADC0DE ++#define SEARCH_PATTERN_LEN sizeof(SEARCH_PATTERN) ++ + //////////////////////////////////////////////////////////////////////// ++// Test structures for IA_NA and IA_TA options ++//////////////////////////////////////////////////////////////////////// ++typedef struct { ++ UINT16 Code; ++ UINT16 Len; ++ UINT32 IAID; ++} DHCPv6_OPTION; ++ ++typedef struct { ++ DHCPv6_OPTION Header; ++ UINT32 T1; ++ UINT32 T2; ++ UINT8 InnerOptions[0]; ++} DHCPv6_OPTION_IA_NA; ++ ++typedef struct { ++ DHCPv6_OPTION Header; ++ UINT8 InnerOptions[0]; ++} DHCPv6_OPTION_IA_TA; ++ + //////////////////////////////////////////////////////////////////////// + // Symbol Definitions + // These functions are not directly under test - but required to compile +@@ -210,7 +239,7 @@ TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) { + Status = Dhcp6AppendETOption ( + Dhcp6AppendETOptionTest::Packet, + &Cursor, +- &Instance, // Instance is not used in this function ++ &Instance, // Instance is not used in this function + &ElapsedTime + ); + +@@ -240,7 +269,7 @@ TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) { + Status = Dhcp6AppendETOption ( + Dhcp6AppendETOptionTest::Packet, + &Cursor, +- &Instance, // Instance is not used in this function ++ &Instance, // Instance is not used in this function + &ElapsedTime + ); + +@@ -476,3 +505,335 @@ TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) { + // verify that the status is EFI_SUCCESS + ASSERT_EQ (Status, EFI_SUCCESS); + } ++ ++//////////////////////////////////////////////////////////////////////// ++// Dhcp6SeekInnerOptionSafe Tests ++//////////////////////////////////////////////////////////////////////// ++ ++// Define a fixture for your tests if needed ++class Dhcp6SeekInnerOptionSafeTest : public ::testing::Test { ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ } ++}; ++ ++// Test Description: ++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IANA option is found. ++TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAValidOptionExpectSuccess) { ++ EFI_STATUS Result; ++ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 }; ++ UINT32 OptionLength = sizeof (Option); ++ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ ++ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT8 *InnerOptionPtr = NULL; ++ UINT16 InnerOptionLength = 0; ++ ++ OptionPtr->Header.Code = Dhcp6OptIana; ++ OptionPtr->Header.Len = HTONS (4 + 12); // Valid length has to be more than 12 ++ OptionPtr->Header.IAID = 0x12345678; ++ OptionPtr->T1 = 0x11111111; ++ OptionPtr->T2 = 0x22222222; ++ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); ++ ++ Result = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIana, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Result, EFI_SUCCESS); ++ ASSERT_EQ (InnerOptionLength, 4); ++ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0); ++} ++ ++// Test Description: ++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_DEIVCE_ERROR when the IANA option size is invalid. ++TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAInvalidSizeExpectFail) { ++ // Lets add an inner option of bytes we expect to find ++ EFI_STATUS Status; ++ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 }; ++ UINT32 OptionLength = sizeof (Option); ++ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ ++ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT8 *InnerOptionPtr = NULL; ++ UINT16 InnerOptionLength = 0; ++ ++ OptionPtr->Header.Code = Dhcp6OptIana; ++ OptionPtr->Header.Len = HTONS (4); // Set the length to lower than expected (12) ++ OptionPtr->Header.IAID = 0x12345678; ++ OptionPtr->T1 = 0x11111111; ++ OptionPtr->T2 = 0x22222222; ++ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); ++ ++ // Set the InnerOptionLength to be less than the size of the option ++ Status = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIana, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Status, EFI_DEVICE_ERROR); ++ ++ // Now set the OptionLength to be less than the size of the option ++ OptionLength = sizeof (DHCPv6_OPTION_IA_NA) - 1; ++ Status = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIana, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Status, EFI_DEVICE_ERROR); ++} ++ ++// Test Description: ++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option is found ++TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAValidOptionExpectSuccess) { ++ // Lets add an inner option of bytes we expect to find ++ EFI_STATUS Status; ++ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; ++ UINT32 OptionLength = sizeof (Option); ++ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ ++ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT8 *InnerOptionPtr = NULL; ++ UINT16 InnerOptionLength = 0; ++ ++ OptionPtr->Header.Code = Dhcp6OptIata; ++ OptionPtr->Header.Len = HTONS (4 + 4); // Valid length has to be more than 4 ++ OptionPtr->Header.IAID = 0x12345678; ++ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); ++ ++ Status = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIata, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ASSERT_EQ (InnerOptionLength, 4); ++ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0); ++} ++ ++// Test Description: ++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid. ++TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAInvalidSizeExpectFail) { ++ // Lets add an inner option of bytes we expect to find ++ EFI_STATUS Status; ++ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; ++ UINT32 OptionLength = sizeof (Option); ++ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ ++ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT8 *InnerOptionPtr = NULL; ++ UINT16 InnerOptionLength = 0; ++ ++ OptionPtr->Header.Code = Dhcp6OptIata; ++ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4) ++ OptionPtr->Header.IAID = 0x12345678; ++ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); ++ ++ Status = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIata, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Status, EFI_DEVICE_ERROR); ++ ++ // Now lets try modifying the OptionLength to be less than the size of the option ++ OptionLength = sizeof (DHCPv6_OPTION_IA_TA) - 1; ++ Status = Dhcp6SeekInnerOptionSafe ( ++ Dhcp6OptIata, ++ Option, ++ OptionLength, ++ &InnerOptionPtr, ++ &InnerOptionLength ++ ); ++ ASSERT_EQ (Status, EFI_DEVICE_ERROR); ++} ++ ++// Test Description: ++// This test verifies that any other Option Type fails ++TEST_F (Dhcp6SeekInnerOptionSafeTest, InvalidOption) { ++ // Lets add an inner option of bytes we expect to find ++ EFI_STATUS Result; ++ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 }; ++ UINT32 OptionLength = sizeof (Option); ++ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ ++ UINTN SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT8 *InnerOptionPtr = NULL; ++ UINT16 InnerOptionLength = 0; ++ ++ OptionPtr->Header.Code = 0xC0DE; ++ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4) ++ OptionPtr->Header.IAID = 0x12345678; ++ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); ++ ++ Result = Dhcp6SeekInnerOptionSafe (0xC0DE, Option, OptionLength, &InnerOptionPtr, &InnerOptionLength); ++ ASSERT_EQ (Result, EFI_DEVICE_ERROR); ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Dhcp6SeekStsOption Tests ++//////////////////////////////////////////////////////////////////////// ++ ++#define PACKET_SIZE (1500) ++ ++class Dhcp6SeekStsOptionTest : public ::testing::Test { ++public: ++ DHCP6_INSTANCE Instance = { 0 }; ++ EFI_DHCP6_PACKET *Packet = NULL; ++ EFI_DHCP6_CONFIG_DATA Config = { 0 }; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Allocate a packet ++ Packet = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); ++ ASSERT_NE (Packet, nullptr); ++ ++ // Initialize the packet ++ Packet->Size = PACKET_SIZE; ++ ++ Instance.Config = &Config; ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ FreePool (Packet); ++ } ++}; ++ ++// Test Description: ++// This test verifies that Dhcp6SeekStsOption returns EFI_DEVICE_ERROR when the option is invalid ++// This verifies that the calling function is working as expected ++TEST_F (Dhcp6SeekStsOptionTest, SeekIATAOptionExpectFail) { ++ EFI_STATUS Status; ++ UINT8 *Option = NULL; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN; ++ UINT16 *Len = NULL; ++ EFI_DHCP6_IA Ia = { 0 }; ++ ++ Ia.Descriptor.Type = DHCPV6_OPTION_IA_TA; ++ Ia.IaAddressCount = 1; ++ Ia.IaAddress[0].PreferredLifetime = 0xDEADBEEF; ++ Ia.IaAddress[0].ValidLifetime = 0xDEADAAAA; ++ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress; ++ ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ ++ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; ++ ++ // Let's append the option to the packet ++ Status = Dhcp6AppendOption ( ++ Dhcp6SeekStsOptionTest::Packet, ++ &Option, ++ Dhcp6OptStatusCode, ++ SearchPatternLength, ++ (UINT8 *)&SearchPattern ++ ); ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ // Inner option length - this will be overwritten later ++ Len = (UINT16 *)(Option + 2); ++ ++ // Fill in the inner IA option ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6SeekStsOptionTest::Packet, ++ &Option, ++ &Ia, ++ 0x12345678, ++ 0x11111111, ++ 0x22222222 ++ ); ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ // overwrite the len of inner Ia option ++ *Len = HTONS (3); ++ ++ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_TA; ++ ++ Option = NULL; ++ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option); ++ ++ ASSERT_EQ (Status, EFI_DEVICE_ERROR); ++} ++ ++// Test Description: ++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid. ++TEST_F (Dhcp6SeekStsOptionTest, SeekIANAOptionExpectSuccess) { ++ EFI_STATUS Status = EFI_NOT_FOUND; ++ UINT8 *Option = NULL; ++ UINT32 SearchPattern = SEARCH_PATTERN; ++ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN; ++ EFI_DHCP6_IA Ia = { 0 }; ++ ++ Ia.Descriptor.Type = DHCPV6_OPTION_IA_NA; ++ Ia.IaAddressCount = 1; ++ Ia.IaAddress[0].PreferredLifetime = 0x11111111; ++ Ia.IaAddress[0].ValidLifetime = 0x22222222; ++ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress; ++ Packet->Length = sizeof (EFI_DHCP6_HEADER); ++ ++ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; ++ ++ Status = Dhcp6AppendOption ( ++ Dhcp6SeekStsOptionTest::Packet, ++ &Option, ++ Dhcp6OptStatusCode, ++ SearchPatternLength, ++ (UINT8 *)&SearchPattern ++ ); ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ Status = Dhcp6AppendIaOption ( ++ Dhcp6SeekStsOptionTest::Packet, ++ &Option, ++ &Ia, ++ 0x12345678, ++ 0x11111111, ++ 0x22222222 ++ ); ++ ASSERT_EQ (Status, EFI_SUCCESS); ++ ++ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_NA; ++ ++ Option = NULL; ++ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option); ++ ++ ASSERT_EQ (Status, EFI_SUCCESS); ++} +diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h +new file mode 100644 +index 00000000..6801106a +--- /dev/null ++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h +@@ -0,0 +1,58 @@ ++/** @file ++ Acts as header for private functions under test in Dhcp6Io.c ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#ifndef DHCP6_IO_GOOGLE_TEST_H_ ++#define DHCP6_IO_GOOGLE_TEST_H_ ++ ++//////////////////////////////////////////////////////////////////////////////// ++// These are the functions that are being unit tested ++//////////////////////////////////////////////////////////////////////////////// ++ ++#include ++ ++/** ++ Seeks the Inner Options from a DHCP6 Option ++ ++ @param[in] IaType The type of the IA option. ++ @param[in] Option The pointer to the DHCP6 Option. ++ @param[in] OptionLen The length of the DHCP6 Option. ++ @param[out] IaInnerOpt The pointer to the IA inner option. ++ @param[out] IaInnerLen The length of the IA inner option. ++ ++ @retval EFI_SUCCESS Seek the inner option successfully. ++ @retval EFI_DEVICE_ERROR The OptionLen is invalid. ++*/ ++EFI_STATUS ++Dhcp6SeekInnerOptionSafe ( ++ UINT16 IaType, ++ UINT8 *Option, ++ UINT32 OptionLen, ++ UINT8 **IaInnerOpt, ++ UINT16 *IaInnerLen ++ ); ++ ++/** ++ Seek StatusCode Option in package. A Status Code option may appear in the ++ options field of a DHCP message and/or in the options field of another option. ++ See details in section 22.13, RFC3315. ++ ++ @param[in] Instance The pointer to the Dhcp6 instance. ++ @param[in] Packet The pointer to reply messages. ++ @param[out] Option The pointer to status code option. ++ ++ @retval EFI_SUCCESS Seek status code option successfully. ++ @retval EFI_DEVICE_ERROR An unexpected error. ++ ++**/ ++EFI_STATUS ++Dhcp6SeekStsOption ( ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet, ++ OUT UINT8 **Option ++ ); ++ ++#endif // DHCP6_IO_GOOGLE_TEST_H +-- +2.33.0 + diff --git a/0061-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch b/0061-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch new file mode 100644 index 0000000000000000000000000000000000000000..634fbef1c75b272826f653859282b4d54a218679 --- /dev/null +++ b/0061-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch @@ -0,0 +1,56 @@ +From 816a19fcd3a2b9a4b32de4613a9e6dc60814ee4f Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:20:27 +0800 +Subject: [PATCH 06/13] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Patch + +Bug Overview: +PixieFail Bug #3 +CVE-2023-45231 +CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N +CWE-125 Out-of-bounds Read + +Out-of-bounds read when handling a ND Redirect message with truncated +options + +Change Overview: + +Adds a check to prevent truncated options from being parsed ++ // ++ // Cannot process truncated options. ++ // Cannot process options with a length of 0 as there is no Type +field. ++ // ++ if (OptionLen < sizeof (IP6_OPTION_HEADER)) { ++ return FALSE; ++ } + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/bbfee34f4188ac00371abe1389ae9c9fb989a0cd +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Ip6Dxe/Ip6Option.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 6b4b029d..5c48006f 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.c +@@ -138,6 +138,14 @@ Ip6IsNDOptionValid ( + return FALSE; + } + ++ // ++ // Cannot process truncated options. ++ // Cannot process options with a length of 0 as there is no Type field. ++ // ++ if (OptionLen < sizeof (IP6_OPTION_HEADER)) { ++ return FALSE; ++ } ++ + Offset = 0; + + // +-- +2.33.0 + diff --git a/0062-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch b/0062-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch new file mode 100644 index 0000000000000000000000000000000000000000..668291488285bcc5e0574fa69cefb7fa12d81ad3 --- /dev/null +++ b/0062-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch @@ -0,0 +1,255 @@ +From 126878401f5f90c4fe8880bf5145106a3241f70f Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:22:35 +0800 +Subject: [PATCH 07/13] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit + Tests + +Validates that the patch for... + +Out-of-bounds read when handling a ND Redirect message with truncated +options + +.. has been fixed + +Tests the following function to ensure that an out of bounds read does +not occur +Ip6OptionValidation + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/6f77463d72807ec7f4ed6518c3dac29a1040df9f +Signed-off-by: yexiao yexiao7@huawei.com +--- + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++ + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++ + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++ + NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + + 4 files changed, 192 insertions(+) + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp + +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp +new file mode 100644 +index 00000000..9fd81d9c +--- /dev/null ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp +@@ -0,0 +1,20 @@ ++/** @file ++ Acts as the main entry point for the tests for the Ip6Dxe module. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Run the tests ++//////////////////////////////////////////////////////////////////////////////// ++int ++main ( ++ int argc, ++ char *argv[] ++ ) ++{ ++ testing::InitGoogleTest (&argc, argv); ++ return RUN_ALL_TESTS (); ++} +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +new file mode 100644 +index 00000000..60396b05 +--- /dev/null ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +@@ -0,0 +1,42 @@ ++## @file ++# Unit test suite for the Ip6Dxe using Google Test ++# ++# Copyright (c) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++[Defines] ++ INF_VERSION = 0x00010017 ++ BASE_NAME = Ip6DxeUnitTest ++ FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A ++ VERSION_STRING = 1.0 ++ MODULE_TYPE = HOST_APPLICATION ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 AARCH64 ++# ++[Sources] ++ Ip6DxeGoogleTest.cpp ++ Ip6OptionGoogleTest.cpp ++ ../Ip6Option.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec ++ NetworkPkg/NetworkPkg.dec ++ ++[LibraryClasses] ++ GoogleTestLib ++ DebugLib ++ NetLib ++ PcdLib ++ ++[Protocols] ++ gEfiDhcp6ServiceBindingProtocolGuid ++ ++[Pcd] ++ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType ++ ++[Guids] ++ gZeroGuid +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +new file mode 100644 +index 00000000..874400eb +--- /dev/null ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +@@ -0,0 +1,129 @@ ++/** @file ++ Tests for Ip6Option.c. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++extern "C" { ++ #include ++ #include ++ #include ++ #include "../Ip6Impl.h" ++ #include "../Ip6Option.h" ++} ++ ++///////////////////////////////////////////////////////////////////////// ++// Defines ++/////////////////////////////////////////////////////////////////////// ++ ++#define IP6_PREFIX_INFO_OPTION_DATA_LEN 32 ++#define OPTION_HEADER_IP6_PREFIX_DATA_LEN (sizeof (IP6_OPTION_HEADER) + IP6_PREFIX_INFO_OPTION_DATA_LEN) ++ ++//////////////////////////////////////////////////////////////////////// ++// Symbol Definitions ++// These functions are not directly under test - but required to compile ++//////////////////////////////////////////////////////////////////////// ++UINT32 mIp6Id; ++ ++EFI_STATUS ++Ip6SendIcmpError ( ++ IN IP6_SERVICE *IpSb, ++ IN NET_BUF *Packet, ++ IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, ++ IN EFI_IPv6_ADDRESS *DestinationAddress, ++ IN UINT8 Type, ++ IN UINT8 Code, ++ IN UINT32 *Pointer OPTIONAL ++ ) ++{ ++ // .. ++ return EFI_SUCCESS; ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// Ip6OptionValidation Tests ++//////////////////////////////////////////////////////////////////////// ++ ++// Define a fixture for your tests if needed ++class Ip6OptionValidationTest : public ::testing::Test { ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ } ++}; ++ ++// Test Description: ++// Null option should return false ++TEST_F (Ip6OptionValidationTest, NullOptionShouldReturnFalse) { ++ UINT8 *option = nullptr; ++ UINT16 optionLen = 10; // Provide a suitable length ++ ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); ++} ++ ++// Test Description: ++// Truncated option should return false ++TEST_F (Ip6OptionValidationTest, TruncatedOptionShouldReturnFalse) { ++ UINT8 option[] = { 0x01 }; // Provide a truncated option ++ UINT16 optionLen = 1; ++ ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); ++} ++ ++// Test Description: ++// Ip6OptionPrefixInfo Option with zero length should return false ++TEST_F (Ip6OptionValidationTest, OptionWithZeroLengthShouldReturnFalse) { ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = Ip6OptionPrefixInfo; ++ optionHeader.Length = 0; ++ UINT8 option[sizeof (IP6_OPTION_HEADER)]; ++ ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); ++ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); ++ ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); ++} ++ ++// Test Description: ++// Ip6OptionPrefixInfo Option with valid length should return true ++TEST_F (Ip6OptionValidationTest, ValidPrefixInfoOptionShouldReturnTrue) { ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = Ip6OptionPrefixInfo; ++ optionHeader.Length = 4; // Length 4 * 8 = 32 ++ UINT8 option[OPTION_HEADER_IP6_PREFIX_DATA_LEN]; ++ ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); ++ ++ EXPECT_TRUE (Ip6IsNDOptionValid (option, IP6_PREFIX_INFO_OPTION_DATA_LEN)); ++} ++ ++// Test Description: ++// Ip6OptionPrefixInfo Option with invalid length should return false ++TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) { ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = Ip6OptionPrefixInfo; ++ optionHeader.Length = 3; // Length 3 * 8 = 24 (Invalid) ++ UINT8 option[sizeof (IP6_OPTION_HEADER)]; ++ ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); ++ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); ++ ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); ++} +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index 7df011c9..97370120 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -25,6 +25,7 @@ + # Build HOST_APPLICATION that tests NetworkPkg + # + NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf ++ NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf + + # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. + [LibraryClasses] +-- +2.33.0 + diff --git a/0063-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch b/0063-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee1dfb4bf053f47d37d67d674aa66c72f5fb2229 --- /dev/null +++ b/0063-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch @@ -0,0 +1,351 @@ +From fd09edfe7d4717ce3670ba7b289510fd7bf2f86c Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:24:07 +0800 +Subject: [PATCH 08/13] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch + +Bug Details: +PixieFail Bug #4 +CVE-2023-45232 +CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H +CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') + +Infinite loop when parsing unknown options in the Destination Options +header + +PixieFail Bug #5 +CVE-2023-45233 +CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H +CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') + +Infinite loop when parsing a PadN option in the Destination Options +header + +Change Overview: + +Most importantly this change corrects the following incorrect math +and cleans up the code. + +> // It is a PadN option +> // +> - Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); +> + OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; +> + Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + +> case Ip6OptionSkip: +> - Offset = (UINT8)(Offset + *(Option + Offset + 1)); +> OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; +> Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + +Additionally, this change also corrects incorrect math where the calling +function was calculating the HDR EXT optionLen as a uint8 instead of a +uint16 + +> - OptionLen = (UINT8)((*Option + 1) * 8 - 2); +> + OptionLen = IP6_HDR_EXT_LEN (*Option) - +IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; + +Additionally this check adds additional logic to santize the incoming +data + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/4df0229ef992d4f2721a8508787ebf9dc81fbd6e +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Ip6Dxe/Ip6Nd.h | 35 ++++++++++++++++ + NetworkPkg/Ip6Dxe/Ip6Option.c | 76 ++++++++++++++++++++++++++++++----- + NetworkPkg/Ip6Dxe/Ip6Option.h | 72 +++++++++++++++++++++++++++++++++ + 3 files changed, 172 insertions(+), 11 deletions(-) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h +index 5f1bd6fb..7ece8522 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h +@@ -56,13 +56,48 @@ VOID + VOID *Context + ); + ++// ++// Per RFC8200 Section 4.2 ++// ++// Two of the currently-defined extension headers -- the Hop-by-Hop ++// Options header and the Destination Options header -- carry a variable ++// number of type-length-value (TLV) encoded "options", of the following ++// format: ++// ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - ++// | Option Type | Opt Data Len | Option Data ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - ++// ++// Option Type 8-bit identifier of the type of option. ++// ++// Opt Data Len 8-bit unsigned integer. Length of the Option ++// Data field of this option, in octets. ++// ++// Option Data Variable-length field. Option-Type-specific ++// data. ++// + typedef struct _IP6_OPTION_HEADER { ++ /// ++ /// identifier of the type of option. ++ /// + UINT8 Type; ++ /// ++ /// Length of the Option Data field of this option, in octets. ++ /// + UINT8 Length; ++ /// ++ /// Option-Type-specific data. ++ /// + } IP6_OPTION_HEADER; + + STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); + ++#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTION_HEADER) + length) ++STATIC_ASSERT ( ++ IP6_NEXT_OPTION_OFFSET (0, 0) == 2, ++ "The next option is minimally the combined size of the option tag and length" ++ ); ++ + typedef struct _IP6_ETHE_ADDR_OPTION { + UINT8 Type; + UINT8 Length; +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 5c48006f..36e28c8b 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.c +@@ -17,7 +17,8 @@ + @param[in] IpSb The IP6 service data. + @param[in] Packet The to be validated packet. + @param[in] Option The first byte of the option. +- @param[in] OptionLen The length of the whole option. ++ @param[in] OptionLen The length of all options, expressed in byte length of octets. ++ Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255. + @param[in] Pointer Identifies the octet offset within + the invoking packet where the error was detected. + +@@ -31,12 +32,33 @@ Ip6IsOptionValid ( + IN IP6_SERVICE *IpSb, + IN NET_BUF *Packet, + IN UINT8 *Option, +- IN UINT8 OptionLen, ++ IN UINT16 OptionLen, + IN UINT32 Pointer + ) + { +- UINT8 Offset; +- UINT8 OptionType; ++ UINT16 Offset; ++ UINT8 OptionType; ++ UINT8 OptDataLen; ++ ++ if (Option == NULL) { ++ ASSERT (Option != NULL); ++ return FALSE; ++ } ++ ++ if ((OptionLen <= 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) { ++ ASSERT (OptionLen > 0 && OptionLen <= IP6_MAX_EXT_DATA_LENGTH); ++ return FALSE; ++ } ++ ++ if (Packet == NULL) { ++ ASSERT (Packet != NULL); ++ return FALSE; ++ } ++ ++ if (IpSb == NULL) { ++ ASSERT (IpSb != NULL); ++ return FALSE; ++ } + + Offset = 0; + +@@ -54,7 +76,8 @@ Ip6IsOptionValid ( + // + // It is a PadN option + // +- Offset = (UINT8) (Offset + *(Option + Offset + 1) + 2); ++ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; ++ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + break; + case Ip6OptionRouterAlert: + // +@@ -69,7 +92,8 @@ Ip6IsOptionValid ( + // + switch (OptionType & Ip6OptionMask) { + case Ip6OptionSkip: +- Offset = (UINT8) (Offset + *(Option + Offset + 1)); ++ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; ++ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + break; + case Ip6OptionDiscard: + return FALSE; +@@ -305,7 +329,7 @@ Ip6IsExtsValid ( + UINT32 Pointer; + UINT32 Offset; + UINT8 *Option; +- UINT8 OptionLen; ++ UINT16 OptionLen; + BOOLEAN Flag; + UINT8 CountD; + UINT8 CountA; +@@ -380,6 +404,36 @@ Ip6IsExtsValid ( + // Fall through + // + case IP6_DESTINATION: ++ // ++ // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23 ++ // ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ // | Next Header | Hdr Ext Len | | ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++ // | | ++ // . . ++ // . Options . ++ // . . ++ // | | ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ // ++ // ++ // Next Header 8-bit selector. Identifies the type of header ++ // immediately following the Destination Options ++ // header. Uses the same values as the IPv4 ++ // Protocol field [RFC-1700 et seq.]. ++ // ++ // Hdr Ext Len 8-bit unsigned integer. Length of the ++ // Destination Options header in 8-octet units, not ++ // including the first 8 octets. ++ // ++ // Options Variable-length field, of length such that the ++ // complete Destination Options header is an ++ // integer multiple of 8 octets long. Contains one ++ // or more TLV-encoded options, as described in ++ // section 4.2. ++ // ++ + if (*NextHeader == IP6_DESTINATION) { + CountD++; + } +@@ -393,7 +447,7 @@ Ip6IsExtsValid ( + + Offset++; + Option = ExtHdrs + Offset; +- OptionLen = (UINT8) ((*Option + 1) * 8 - 2); ++ OptionLen = IP6_HDR_EXT_LEN (*Option) - sizeof (IP6_EXT_HDR); + Option++; + Offset++; + +@@ -425,7 +479,7 @@ Ip6IsExtsValid ( + // + // Ignore the routing header and proceed to process the next header. + // +- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; ++ Offset = Offset + IP6_HDR_EXT_LEN (RoutingHead->HeaderLen); + + if (UnFragmentLen != NULL) { + *UnFragmentLen = Offset; +@@ -437,7 +491,7 @@ Ip6IsExtsValid ( + // to the packet's source address, pointing to the unrecognized routing + // type. + // +- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); ++ Pointer = Offset + sizeof (IP6_EXT_HDR) + sizeof (EFI_IP6_HEADER); + if ((IpSb != NULL) && (Packet != NULL) && + !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { + Ip6SendIcmpError ( +@@ -521,7 +575,7 @@ Ip6IsExtsValid ( + // + // RFC2402, Payload length is specified in 32-bit words, minus "2". + // +- OptionLen = (UINT8) ((*Option + 2) * 4); ++ OptionLen = ((UINT16)(*Option + 2) * 4); + Offset = Offset + OptionLen; + break; + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h +index c81b3fda..4201bcd4 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.h +@@ -12,6 +12,78 @@ + + #define IP6_FRAGMENT_OFFSET_MASK (~0x3) + ++// ++// For more information see RFC 8200, Section 4.3, 4.4, and 4.6 ++// ++// This example format is from section 4.6 ++// This does not apply to fragment headers ++// ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | Next Header | Hdr Ext Len | | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++// | | ++// . . ++// . Header-Specific Data . ++// . . ++// | | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++// Next Header 8-bit selector. Identifies the type of ++// header immediately following the extension ++// header. Uses the same values as the IPv4 ++// Protocol field [IANA-PN]. ++// ++// Hdr Ext Len 8-bit unsigned integer. Length of the ++// Destination Options header in 8-octet units, ++// not including the first 8 octets. ++ ++// ++// These defines apply to the following: ++// 1. Hop by Hop ++// 2. Routing ++// 3. Destination ++// ++typedef struct _IP6_EXT_HDR { ++ /// ++ /// The Next Header field identifies the type of header immediately ++ /// ++ UINT8 NextHeader; ++ /// ++ /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options ++ /// ++ UINT8 HdrExtLen; ++ /// ++ /// Header-Specific Data ++ /// ++} IP6_EXT_HDR; ++ ++STATIC_ASSERT ( ++ sizeof (IP6_EXT_HDR) == 2, ++ "The combined size of Next Header and Len is two 8 bit fields" ++ ); ++ ++// ++// IPv6 extension headers contain an 8-bit length field which describes the size of ++// the header. However, the length field only includes the size of the extension ++// header options, not the size of the first 8 bytes of the header. Therefore, in ++// order to calculate the full size of the extension header, we add 1 (to account ++// for the first 8 bytes omitted by the length field reporting) and then multiply ++// by 8 (since the size is represented in 8-byte units). ++// ++// a is the length field of the extension header (UINT8) ++// The result may be up to 2046 octets (UINT16) ++// ++#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) ++ ++// This is the maxmimum length permissible by a extension header ++// Length is UINT8 of 8 octets not including the first 8 octets ++#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR)) ++STATIC_ASSERT ( ++ IP6_MAX_EXT_DATA_LENGTH == 2046, ++ "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" ++ ); ++ ++ + typedef struct _IP6_FRAGMENT_HEADER { + UINT8 NextHeader; + UINT8 Reserved; +-- +2.33.0 + diff --git a/0064-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch b/0064-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch new file mode 100644 index 0000000000000000000000000000000000000000..7c5bb1c1072bd3a80435d2c100933c7db42f2e81 --- /dev/null +++ b/0064-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch @@ -0,0 +1,408 @@ +From 7bff8451cd7374c912cf79e13b0a496483252de5 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:25:22 +0800 +Subject: [PATCH 09/13] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit + Tests + +Unit tests to confirm that.. + +Infinite loop when parsing unknown options in the Destination Options +header + +and + +Infinite loop when parsing a PadN option in the Destination Options +header + +... have been patched + +This patch tests the following functions: +Ip6IsOptionValid + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/c9c87f08dd6ace36fa843424522c3558a8374cac +Signed-off-by: yexiao yexiao7@huawei.com +--- + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +- + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 278 ++++++++++++++++++ + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++ + 3 files changed, 324 insertions(+), 4 deletions(-) + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h + +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +index 60396b05..489a45f1 100644 +--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +@@ -1,13 +1,13 @@ + ## @file +-# Unit test suite for the Ip6Dxe using Google Test ++# Unit test suite for the Ip6DxeGoogleTest using Google Test + # + # Copyright (c) Microsoft Corporation.
+ # SPDX-License-Identifier: BSD-2-Clause-Patent + ## + [Defines] + INF_VERSION = 0x00010017 +- BASE_NAME = Ip6DxeUnitTest +- FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A ++ BASE_NAME = Ip6DxeGoogleTest ++ FILE_GUID = AE39981C-B7FE-41A8-A9C2-F41910477CA3 + VERSION_STRING = 1.0 + MODULE_TYPE = HOST_APPLICATION + # +@@ -16,9 +16,11 @@ + # VALID_ARCHITECTURES = IA32 X64 AARCH64 + # + [Sources] ++ ../Ip6Option.c ++ Ip6OptionGoogleTest.h + Ip6DxeGoogleTest.cpp + Ip6OptionGoogleTest.cpp +- ../Ip6Option.c ++ Ip6OptionGoogleTest.h + + [Packages] + MdePkg/MdePkg.dec +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +index 874400eb..c12cbc0d 100644 +--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +@@ -12,6 +12,7 @@ extern "C" { + #include + #include "../Ip6Impl.h" + #include "../Ip6Option.h" ++ #include "Ip6OptionGoogleTest.h" + } + + ///////////////////////////////////////////////////////////////////////// +@@ -127,3 +128,280 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) + + EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); + } ++ ++//////////////////////////////////////////////////////////////////////// ++// Ip6IsOptionValid Tests ++//////////////////////////////////////////////////////////////////////// ++ ++// Define a fixture for your tests if needed ++class Ip6IsOptionValidTest : public ::testing::Test { ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ // Initialize any resources or variables ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ // Clean up any resources or variables ++ } ++}; ++ ++// Test Description ++// Verify that a NULL option is Invalid ++TEST_F (Ip6IsOptionValidTest, NullOptionShouldReturnTrue) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ IP6_SERVICE *IpSb = NULL; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0)); ++} ++ ++// Test Description ++// Verify that an unknown option with a length of 0 and type of does not cause an infinite loop ++TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = 23; // Unknown Option ++ optionHeader.Length = 0; // This will cause an infinite loop if the function is not working correctly ++ ++ // This should be a valid option even though the length is 0 ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify that an unknown option with a length of 1 and type of does not cause an infinite loop ++TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = 23; // Unknown Option ++ optionHeader.Length = 1; // This will cause an infinite loop if the function is not working correctly ++ ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify that an unknown option with a length of 2 and type of does not cause an infinite loop ++TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = 23; // Unknown Option ++ optionHeader.Length = 2; // Valid length for an unknown option ++ ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify that Ip6OptionPad1 is valid with a length of 0 ++TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = Ip6OptionPad1; ++ optionHeader.Length = 0; ++ ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify that Ip6OptionPadN doesn't overflow with various lengths ++TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = Ip6OptionPadN; ++ optionHeader.Length = 0xFF; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFE; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFD; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFC; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify an unknown option doesn't cause an infinite loop with various lengths ++TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAttemptOverflow) { ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ IP6_OPTION_HEADER optionHeader; ++ ++ optionHeader.Type = 23; // Unknown Option ++ optionHeader.Length = 0xFF; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFE; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFD; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++ ++ optionHeader.Length = 0xFC; ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0)); ++} ++ ++// Test Description ++// Verify that the function supports multiple options ++TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) { ++ UINT16 HdrLen; ++ NET_BUF Packet = { 0 }; ++ // we need to define enough of the packet to make the function work ++ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above ++ UINT32 DeadCode = 0xDeadC0de; ++ // Don't actually use this pointer, just pass it to the function, nothing will be done with it ++ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode; ++ ++ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; ++ EFI_IP6_HEADER Ip6Header = { 0 }; ++ ++ Ip6Header.SourceAddress = SourceAddress; ++ Ip6Header.DestinationAddress = DestinationAddress; ++ Packet.Ip.Ip6 = &Ip6Header; ++ ++ UINT8 ExtHdr[1024] = { 0 }; ++ UINT8 *Cursor = ExtHdr; ++ IP6_OPTION_HEADER *Option = (IP6_OPTION_HEADER *)ExtHdr; ++ ++ // Let's start chaining options ++ ++ Option->Type = 23; // Unknown Option ++ Option->Length = 0xFC; ++ ++ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC; ++ ++ Option = (IP6_OPTION_HEADER *)Cursor; ++ Option->Type = Ip6OptionPad1; ++ ++ Cursor += sizeof (1); ++ ++ // Type and length aren't processed, instead it just moves the pointer forward by 4 bytes ++ Option = (IP6_OPTION_HEADER *)Cursor; ++ Option->Type = Ip6OptionRouterAlert; ++ Option->Length = 4; ++ ++ Cursor += sizeof (IP6_OPTION_HEADER) + 4; ++ ++ Option = (IP6_OPTION_HEADER *)Cursor; ++ Option->Type = Ip6OptionPadN; ++ Option->Length = 0xFC; ++ ++ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC; ++ ++ Option = (IP6_OPTION_HEADER *)Cursor; ++ Option->Type = Ip6OptionRouterAlert; ++ Option->Length = 4; ++ ++ Cursor += sizeof (IP6_OPTION_HEADER) + 4; ++ ++ // Total 524 ++ ++ HdrLen = (UINT16)(Cursor - ExtHdr); ++ ++ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0)); ++} +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h +new file mode 100644 +index 00000000..af61f608 +--- /dev/null ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h +@@ -0,0 +1,40 @@ ++/** @file ++ Exposes the functions needed to test the Ip6Option module. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#ifndef IP6_OPTION_HEADER_GOOGLE_TEST_H_ ++#define IP6_OPTION_HEADER_GOOGLE_TEST_H_ ++ ++#include ++#include "../Ip6Impl.h" ++ ++/** ++ Validate the IP6 option format for both the packets we received ++ and that we will transmit. It will compute the ICMPv6 error message fields ++ if the option is malformatted. ++ ++ @param[in] IpSb The IP6 service data. ++ @param[in] Packet The to be validated packet. ++ @param[in] Option The first byte of the option. ++ @param[in] OptionLen The length of the whole option. ++ @param[in] Pointer Identifies the octet offset within ++ the invoking packet where the error was detected. ++ ++ ++ @retval TRUE The option is properly formatted. ++ @retval FALSE The option is malformatted. ++ ++**/ ++BOOLEAN ++Ip6IsOptionValid ( ++ IN IP6_SERVICE *IpSb, ++ IN NET_BUF *Packet, ++ IN UINT8 *Option, ++ IN UINT16 OptionLen, ++ IN UINT32 Pointer ++ ); ++ ++#endif // __IP6_OPTION_HEADER_GOOGLE_TEST_H__ +-- +2.33.0 + diff --git a/0065-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0065-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch new file mode 100644 index 0000000000000000000000000000000000000000..05672e81b9b413df23d835758a1fc75a19b335a8 --- /dev/null +++ b/0065-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch @@ -0,0 +1,144 @@ +From 8b92628f5c3b8e3fd6d3cef0e5060255f936b3e9 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:26:27 +0800 +Subject: [PATCH 10/13] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 + Patch + +Bug Details: +PixieFail Bug #6 +CVE-2023-45234 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds of + a Memory Buffer + +Buffer overflow when processing DNS Servers option in a DHCPv6 +Advertise message + +Change Overview: + +Introduces a function to cache the Dns Server and perform sanitizing +on the incoming DnsServerLen to ensure that the length is valid + +> + EFI_STATUS +> + PxeBcCacheDnsServerAddresses ( +> + IN PXEBC_PRIVATE_DATA *Private, +> + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 +> + ) + +Additional code cleanup + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/1b53515d53d303166b2bbd31e2cc7f16fd0aecd7 +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 69 ++++++++++++++++++++++++++-- + 1 file changed, 64 insertions(+), 5 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 8d71143b..7a20ba56 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -3,6 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent + +@@ -1308,6 +1309,64 @@ PxeBcSelectDhcp6Offer ( + } + } + ++/** ++ Cache the DHCPv6 DNS Server addresses ++ ++ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. ++ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. ++ ++ @retval EFI_SUCCESS Cache the DHCPv6 DNS Server address successfully. ++ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. ++ @retval EFI_DEVICE_ERROR The DNS Server Address Length provided by a untrusted ++ option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)). ++**/ ++EFI_STATUS ++PxeBcCacheDnsServerAddresses ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN PXEBC_DHCP6_PACKET_CACHE *Cache6 ++ ) ++{ ++ UINT16 DnsServerLen; ++ ++ DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen); ++ // ++ // Make sure that the number is nonzero ++ // ++ if (DnsServerLen == 0) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16) ++ // ++ if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // This code is currently written to only support a single DNS Server instead ++ // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior ++ // would be to allocate the full space requested, CopyMem all of the data, ++ // and then add a DnsServerCount field to Private and update additional code ++ // that depends on this. ++ // ++ // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen ++ // ++ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886 ++ // ++ Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); ++ if (Private->DnsServer == NULL) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ // ++ // Intentionally only copy over the first server address. ++ // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen ++ // ++ CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); ++ ++ return EFI_SUCCESS; ++} + + /** + Handle the DHCPv6 offer packet. +@@ -1332,6 +1391,7 @@ PxeBcHandleDhcp6Offer ( + UINT32 SelectIndex; + UINT32 Index; + ++ ASSERT (Private != NULL); + ASSERT (Private->SelectIndex > 0); + SelectIndex = (UINT32) (Private->SelectIndex - 1); + ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM); +@@ -1339,14 +1399,13 @@ PxeBcHandleDhcp6Offer ( + Status = EFI_SUCCESS; + + // +- // First try to cache DNS server address if DHCP6 offer provides. ++ // First try to cache DNS server addresses if DHCP6 offer provides. + // + if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) { +- Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen)); +- if (Private->DnsServer == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = PxeBcCacheDnsServerAddresses (Private, Cache6); ++ if (EFI_ERROR (Status)) { ++ return Status; + } +- CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); + } + + if (Cache6->OfferType == PxeOfferTypeDhcpBinl) { +-- +2.33.0 + diff --git a/0066-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0066-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7a9440242d4f76237f2da818546899cad5d20ac --- /dev/null +++ b/0066-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch @@ -0,0 +1,489 @@ +From dd655085bf631eea1dd8c2ab189dece526d82994 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:27:33 +0800 +Subject: [PATCH 11/13] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 + Unit Tests + +Unit tests to that the bug.. + +Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise +message + +..has been patched + +This contains tests for the following functions: +PxeBcHandleDhcp6Offer +PxeBcCacheDnsServerAddresses + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/458c582685fc0e8057d2511c5a0394078d988c17 +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + + .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 300 ++++++++++++++++++ + .../GoogleTest/PxeBcDhcp6GoogleTest.h | 50 +++ + .../GoogleTest/UefiPxeBcDxeGoogleTest.cpp | 19 ++ + .../GoogleTest/UefiPxeBcDxeGoogleTest.inf | 48 +++ + 5 files changed, 418 insertions(+) + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf + +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index 97370120..ad164c9d 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -26,6 +26,7 @@ + # + NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf ++ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf + + # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. + [LibraryClasses] +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +new file mode 100644 +index 00000000..c66a60bc +--- /dev/null ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +@@ -0,0 +1,300 @@ ++/** @file ++ Host based unit test for PxeBcDhcp6.c. ++ ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++extern "C" { ++ #include ++ #include ++ #include ++ #include "../PxeBcImpl.h" ++ #include "../PxeBcDhcp6.h" ++ #include "PxeBcDhcp6GoogleTest.h" ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Definitions ++/////////////////////////////////////////////////////////////////////////////// ++ ++#define PACKET_SIZE (1500) ++ ++typedef struct { ++ UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03) ++ UINT16 OptionLen; // The length of the option (e.g., 16 bytes) ++ UINT8 ServerId[16]; // The 16-byte DHCPv6 Server Identifier ++} DHCP6_OPTION_SERVER_ID; ++ ++/////////////////////////////////////////////////////////////////////////////// ++/// Symbol Definitions ++/////////////////////////////////////////////////////////////////////////////// ++ ++EFI_STATUS ++MockUdpWrite ( ++ IN EFI_PXE_BASE_CODE_PROTOCOL *This, ++ IN UINT16 OpFlags, ++ IN EFI_IP_ADDRESS *DestIp, ++ IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, ++ IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, ++ IN EFI_IP_ADDRESS *SrcIp OPTIONAL, ++ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, ++ IN UINTN *HeaderSize OPTIONAL, ++ IN VOID *HeaderPtr OPTIONAL, ++ IN UINTN *BufferSize, ++ IN VOID *BufferPtr ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++EFI_STATUS ++MockUdpRead ( ++ IN EFI_PXE_BASE_CODE_PROTOCOL *This, ++ IN UINT16 OpFlags, ++ IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, ++ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, ++ IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, ++ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, ++ IN UINTN *HeaderSize OPTIONAL, ++ IN VOID *HeaderPtr OPTIONAL, ++ IN OUT UINTN *BufferSize, ++ IN VOID *BufferPtr ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++EFI_STATUS ++MockConfigure ( ++ IN EFI_UDP6_PROTOCOL *This, ++ IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++// Needed by PxeBcSupport ++EFI_STATUS ++EFIAPI ++QueueDpc ( ++ IN EFI_TPL DpcTpl, ++ IN EFI_DPC_PROCEDURE DpcProcedure, ++ IN VOID *DpcContext OPTIONAL ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// PxeBcHandleDhcp6OfferTest Tests ++/////////////////////////////////////////////////////////////////////////////// ++ ++class PxeBcHandleDhcp6OfferTest : public ::testing::Test { ++public: ++ PXEBC_PRIVATE_DATA Private = { 0 }; ++ EFI_UDP6_PROTOCOL Udp6Read; ++ EFI_PXE_BASE_CODE_MODE Mode = { 0 }; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); ++ ++ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL ++ // The function under test really only needs the following: ++ // UdpWrite ++ // UdpRead ++ ++ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; ++ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; ++ ++ // Need to setup EFI_UDP6_PROTOCOL ++ // The function under test really only needs the following: ++ // Configure ++ ++ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; ++ Private.Udp6Read = &Udp6Read; ++ ++ // Need to setup the EFI_PXE_BASE_CODE_MODE ++ Private.PxeBc.Mode = &Mode; ++ ++ // for this test it doesn't really matter what the Dhcpv6 ack is set to ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ if (Private.Dhcp6Request != NULL) { ++ FreePool (Private.Dhcp6Request); ++ } ++ ++ // Clean up any resources or variables ++ } ++}; ++ ++// Note: ++// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a ++// properly setup Private structure. Attempting to properly test this function ++// without a signficant refactor is a fools errand. Instead, we will test ++// that we can prevent an overflow in the function. ++TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { ++ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; ++ EFI_DHCP6_PACKET_OPTION Option = { 0 }; ++ ++ Private.SelectIndex = 1; // SelectIndex is 1-based ++ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; ++ ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; ++ // Setup the DHCPv6 offer packet ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337); ++ ++ ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR); ++} ++ ++class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { ++public: ++ PXEBC_PRIVATE_DATA Private = { 0 }; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ } ++}; ++ ++// Test Description ++// Test that we cache the DNS server address from the DHCPv6 offer packet ++TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) { ++ UINT8 SearchPattern[16] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF }; ++ EFI_DHCP6_PACKET_OPTION *Option; ++ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; ++ ++ Option = (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + sizeof (SearchPattern)); ++ ASSERT_NE (Option, nullptr); ++ ++ Option->OpCode = DHCP6_OPT_SERVER_ID; ++ Option->OpLen = NTOHS (sizeof (SearchPattern)); ++ CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern)); ++ ++ Private.SelectIndex = 1; // SelectIndex is 1-based ++ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option; ++ ++ Private.DnsServer = nullptr; ++ ++ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS); ++ ASSERT_NE (Private.DnsServer, nullptr); ++ ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchPattern)), 0); ++ ++ if (Private.DnsServer) { ++ FreePool (Private.DnsServer); ++ } ++ ++ if (Option) { ++ FreePool (Option); ++ } ++} ++// Test Description ++// Test that we can prevent an overflow in the function ++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) { ++ EFI_DHCP6_PACKET_OPTION Option = { 0 }; ++ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; ++ ++ Private.SelectIndex = 1; // SelectIndex is 1-based ++ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; ++ // Setup the DHCPv6 offer packet ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337); ++ ++ Private.DnsServer = NULL; ++ ++ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR); ++ ASSERT_EQ (Private.DnsServer, nullptr); ++ ++ if (Private.DnsServer) { ++ FreePool (Private.DnsServer); ++ } ++} ++ ++// Test Description ++// Test that we can prevent an underflow in the function ++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) { ++ EFI_DHCP6_PACKET_OPTION Option = { 0 }; ++ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; ++ ++ Private.SelectIndex = 1; // SelectIndex is 1-based ++ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; ++ // Setup the DHCPv6 offer packet ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (2); ++ ++ Private.DnsServer = NULL; ++ ++ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR); ++ ASSERT_EQ (Private.DnsServer, nullptr); ++ ++ if (Private.DnsServer) { ++ FreePool (Private.DnsServer); ++ } ++} ++ ++// Test Description ++// Test that we can handle recursive dns (multiple dns entries) ++TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { ++ EFI_DHCP6_PACKET_OPTION Option = { 0 }; ++ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL; ++ ++ Private.SelectIndex = 1; // SelectIndex is 1-based ++ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6; ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option; ++ // Setup the DHCPv6 offer packet ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID; ++ ++ EFI_IPv6_ADDRESS addresses[2] = { ++ // 2001:db8:85a3::8a2e:370:7334 ++ { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }, ++ // fe80::d478:91c3:ecd7:4ff9 ++ { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 } ++ }; ++ ++ CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses)); ++ ++ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses)); ++ ++ Private.DnsServer = NULL; ++ ++ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS); ++ ++ ASSERT_NE (Private.DnsServer, nullptr); ++ ++ // ++ // This is expected to fail until DnsServer supports multiple DNS servers ++ // ++ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886 ++ // ++ // Disabling: ++ // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses)), 0); ++ ++ if (Private.DnsServer) { ++ FreePool (Private.DnsServer); ++ } ++} +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +new file mode 100644 +index 00000000..48ab238d +--- /dev/null ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +@@ -0,0 +1,50 @@ ++/** @file ++ This file exposes the internal interfaces which may be unit tested ++ for the PxeBcDhcp6Dxe driver. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_ ++#define PXE_BC_DHCP6_GOOGLE_TEST_H_ ++ ++// ++// Minimal includes needed to compile ++// ++#include ++#include "../PxeBcImpl.h" ++ ++/** ++ Handle the DHCPv6 offer packet. ++ ++ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. ++ ++ @retval EFI_SUCCESS Handled the DHCPv6 offer packet successfully. ++ @retval EFI_NO_RESPONSE No response to the following request packet. ++ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. ++ @retval EFI_BUFFER_TOO_SMALL Can't cache the offer pacet. ++ ++**/ ++EFI_STATUS ++PxeBcHandleDhcp6Offer ( ++ IN PXEBC_PRIVATE_DATA *Private ++ ); ++ ++/** ++ Cache the DHCPv6 Server address ++ ++ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. ++ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. ++ ++ @retval EFI_SUCCESS Cache the DHCPv6 Server address successfully. ++ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. ++ @retval EFI_DEVICE_ERROR Failed to cache the DHCPv6 Server address. ++**/ ++EFI_STATUS ++PxeBcCacheDnsServerAddresses ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN PXEBC_DHCP6_PACKET_CACHE *Cache6 ++ ); ++ ++#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp +new file mode 100644 +index 00000000..ff159e45 +--- /dev/null ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp +@@ -0,0 +1,19 @@ ++/** @file ++ Acts as the main entry point for the tests for the UefiPxeBcDxe module. ++ Copyright (c) Microsoft Corporation ++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Run the tests ++//////////////////////////////////////////////////////////////////////////////// ++int ++main ( ++ int argc, ++ char *argv[] ++ ) ++{ ++ testing::InitGoogleTest (&argc, argv); ++ return RUN_ALL_TESTS (); ++} +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf +new file mode 100644 +index 00000000..0097142b +--- /dev/null ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf +@@ -0,0 +1,48 @@ ++## @file ++# Unit test suite for the UefiPxeBcDxe using Google Test ++# ++# Copyright (c) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++[Defines] ++INF_VERSION = 0x00010005 ++BASE_NAME = UefiPxeBcDxeGoogleTest ++FILE_GUID = 77D45C64-EC1E-4174-887B-886E89FD1EDF ++MODULE_TYPE = HOST_APPLICATION ++VERSION_STRING = 1.0 ++ ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 ++# ++ ++[Sources] ++ UefiPxeBcDxeGoogleTest.cpp ++ PxeBcDhcp6GoogleTest.cpp ++ PxeBcDhcp6GoogleTest.h ++ ../PxeBcDhcp6.c ++ ../PxeBcSupport.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec ++ NetworkPkg/NetworkPkg.dec ++ ++[LibraryClasses] ++ GoogleTestLib ++ DebugLib ++ NetLib ++ PcdLib ++ ++[Protocols] ++ gEfiDhcp6ServiceBindingProtocolGuid ++ gEfiDns6ServiceBindingProtocolGuid ++ gEfiDns6ProtocolGuid ++ ++[Pcd] ++ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType ++ ++[Guids] ++ gZeroGuid +-- +2.33.0 + diff --git a/0067-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0067-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch new file mode 100644 index 0000000000000000000000000000000000000000..ffed5f0de7b50af55f209fcf2b1869dd75c10b2d --- /dev/null +++ b/0067-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch @@ -0,0 +1,231 @@ +From 0c7c03ee087f10d9ddda8f38d816763211f8b925 Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:28:35 +0800 +Subject: [PATCH 12/13] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 + Patch + +Bug Details: +PixieFail Bug #7 +CVE-2023-45235 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds of + a Memory Buffer + +Buffer overflow when handling Server ID option from a DHCPv6 proxy +Advertise message + +Change Overview: + +Performs two checks + +1. Checks that the length of the duid is accurate +> + // +> + // Check that the minimum and maximum requirements are met +> + // +> + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || +(OpLen > PXEBC_MAX_SIZE_OF_DUID)) { +> + Status = EFI_INVALID_PARAMETER; +> + goto ON_ERROR; +> + } + +2. Ensures that the amount of data written to the buffer is tracked and +never exceeds that +> + // +> + // Check that the option length is valid. +> + // +> + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) + > DiscoverLenNeeded) { +> + Status = EFI_OUT_OF_RESOURCES; +> + goto ON_ERROR; +> + } + +Additional code clean up and fix for memory leak in case Option was NULL + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/fac297724e6cc343430cd0104e55cd7a96d1151e +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 76 ++++++++++++++++++++++------ + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 +++++++ + 2 files changed, 77 insertions(+), 16 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 7a20ba56..578a2615 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -883,6 +883,7 @@ PxeBcRequestBootService ( + EFI_STATUS Status; + EFI_DHCP6_PACKET *IndexOffer; + UINT8 *Option; ++ UINTN DiscoverLenNeeded; + + PxeBc = &Private->PxeBc; + Request = Private->Dhcp6Request; +@@ -895,7 +896,8 @@ PxeBcRequestBootService ( + return EFI_DEVICE_ERROR; + } + +- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); ++ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); ++ Discover = AllocateZeroPool (DiscoverLenNeeded); + if (Discover == NULL) { + return EFI_OUT_OF_RESOURCES; + } +@@ -920,16 +922,33 @@ PxeBcRequestBootService ( + DHCP6_OPT_SERVER_ID + ); + if (Option == NULL) { +- return EFI_NOT_FOUND; ++ Status = EFI_NOT_FOUND; ++ goto ON_ERROR; + } + + // + // Add Server ID Option. + // + OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) Option)->OpLen); +- CopyMem (DiscoverOpt, Option, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ // ++ // Check that the minimum and maximum requirements are met ++ // ++ if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) { ++ Status = EFI_INVALID_PARAMETER; ++ goto ON_ERROR; ++ } ++ ++ // ++ // Check that the option length is valid. ++ // ++ if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ ++ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + while (RequestLen < Request->Length) { +@@ -939,15 +958,23 @@ PxeBcRequestBootService ( + OpCode != EFI_DHCP6_IA_TYPE_TA && + OpCode != DHCP6_OPT_SERVER_ID + ) { ++ // ++ // Check that the option length is valid. ++ // ++ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ + // + // Copy all the options except IA option and Server ID + // +- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } +- RequestOpt += (OpLen + 4); +- RequestLen += (OpLen + 4); ++ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + // +@@ -2135,6 +2162,7 @@ PxeBcDhcp6Discover ( + UINT16 OpLen; + UINT32 Xid; + EFI_STATUS Status; ++ UINTN DiscoverLenNeeded; + + PxeBc = &Private->PxeBc; + Mode = PxeBc->Mode; +@@ -2150,7 +2178,8 @@ PxeBcDhcp6Discover ( + return EFI_DEVICE_ERROR; + } + +- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); ++ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); ++ Discover = AllocateZeroPool (DiscoverLenNeeded); + if (Discover == NULL) { + return EFI_OUT_OF_RESOURCES; + } +@@ -2166,20 +2195,35 @@ PxeBcDhcp6Discover ( + DiscoverLen = sizeof (EFI_DHCP6_HEADER); + RequestLen = DiscoverLen; + ++ // ++ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence, ++ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are ++ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes, ++ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with ++ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously ++ // generated and sent. ++ // ++ // Therefore while this code looks like it could overflow, in practice it's not possible. ++ // + while (RequestLen < Request->Length) { + OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpCode); + OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpLen); + if (OpCode != EFI_DHCP6_IA_TYPE_NA && + OpCode != EFI_DHCP6_IA_TYPE_TA) { ++ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ + // + // Copy all the options except IA option. + // +- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } +- RequestOpt += (OpLen + 4); +- RequestLen += (OpLen + 4); ++ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + Status = PxeBc->UdpWrite ( +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +index ae4be775..fda5f502 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +@@ -35,6 +35,23 @@ + #define PXEBC_ADDR_START_DELIMITER '[' + #define PXEBC_ADDR_END_DELIMITER ']' + ++// ++// A DUID consists of a 2-octet type code represented in network byte ++// order, followed by a variable number of octets that make up the ++// actual identifier. The length of the DUID (not including the type ++// code) is at least 1 octet and at most 128 octets. ++// ++#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1) ++#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128) ++ ++// ++// This define represents the combineds code and length field from ++// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1 ++// ++#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \ ++ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \ ++ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) ++ + #define GET_NEXT_DHCP6_OPTION(Opt) \ + (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \ + sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1) +-- +2.33.0 + diff --git a/0068-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/0068-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch new file mode 100644 index 0000000000000000000000000000000000000000..35c3855642edaa8941701d2607415742abac637d --- /dev/null +++ b/0068-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch @@ -0,0 +1,387 @@ +From ca4fc18dc7b5441236fdf3387703c9162c4ec80c Mon Sep 17 00:00:00 2001 +From: adttil <13380049+adttil@user.noreply.gitee.com> +Date: Sat, 24 Feb 2024 14:30:11 +0800 +Subject: [PATCH 13/13] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 + Unit Tests + +Unit tests to confirm that the bug.. + +Buffer overflow when handling Server ID option from a DHCPv6 proxy +Advertise message + +..has been patched. + +This patch contains unit tests for the following functions: +PxeBcRequestBootService +PxeBcDhcp6Discover + +Signed-off-by: Doug Flick [MSFT] + +ref: https://github.com/tianocore/edk2/commit/ff2986358f75d8f58ef08a66fe673539c9c48f41 +Signed-off-by: yexiao yexiao7@huawei.com +--- + NetworkPkg/Test/NetworkPkgHostTest.dsc | 5 +- + .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++- + .../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++ + 3 files changed, 298 insertions(+), 3 deletions(-) + +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index ad164c9d..d58f54cb 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -26,7 +26,10 @@ + # + NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +- NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf ++ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf { ++ ++ UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf ++ } + + # Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests. + [LibraryClasses] +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +index c66a60bc..d447ac02 100644 +--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +@@ -4,7 +4,9 @@ + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + **/ +-#include ++#include ++#include ++#include + + extern "C" { + #include +@@ -19,7 +21,8 @@ extern "C" { + // Definitions + /////////////////////////////////////////////////////////////////////////////// + +-#define PACKET_SIZE (1500) ++#define PACKET_SIZE (1500) ++#define REQUEST_OPTION_LENGTH (120) + + typedef struct { + UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03) +@@ -76,6 +79,26 @@ MockConfigure ( + } + + // Needed by PxeBcSupport ++EFI_STATUS ++PxeBcDns6 ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN CHAR16 *HostName, ++ OUT EFI_IPv6_ADDRESS *IpAddress ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ ++UINT32 ++PxeBcBuildDhcp6Options ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ OUT EFI_DHCP6_PACKET_OPTION **OptList, ++ IN UINT8 *Buffer ++ ) ++{ ++ return EFI_SUCCESS; ++} ++ + EFI_STATUS + EFIAPI + QueueDpc ( +@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { + ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR); + } + ++/////////////////////////////////////////////////////////////////////////////// ++// PxeBcCacheDnsServerAddresses Tests ++/////////////////////////////////////////////////////////////////////////////// ++ + class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { + public: + PXEBC_PRIVATE_DATA Private = { 0 }; +@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { + FreePool (Private.DnsServer); + } + } ++ ++/////////////////////////////////////////////////////////////////////////////// ++// PxeBcRequestBootServiceTest Test Cases ++/////////////////////////////////////////////////////////////////////////////// ++ ++class PxeBcRequestBootServiceTest : public ::testing::Test { ++public: ++ PXEBC_PRIVATE_DATA Private = { 0 }; ++ EFI_UDP6_PROTOCOL Udp6Read; ++ ++protected: ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); ++ ++ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL ++ // The function under test really only needs the following: ++ // UdpWrite ++ // UdpRead ++ ++ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; ++ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; ++ ++ // Need to setup EFI_UDP6_PROTOCOL ++ // The function under test really only needs the following: ++ // Configure ++ ++ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; ++ Private.Udp6Read = &Udp6Read; ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ if (Private.Dhcp6Request != NULL) { ++ FreePool (Private.Dhcp6Request); ++ } ++ ++ // Clean up any resources or variables ++ } ++}; ++ ++TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) { ++ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl; ++ ++ DHCP6_OPTION_SERVER_ID Server = { 0 }; ++ ++ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID); ++ Server.OptionLen = HTONS (16); // valid length ++ UINT8 Index = 0; ++ ++ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer; ++ ++ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); ++ ++ CopyMem (Cursor, &Server, sizeof (Server)); ++ Cursor += sizeof (Server); ++ ++ // Update the packet length ++ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); ++ Packet->Size = PACKET_SIZE; ++ ++ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS); ++} ++ ++TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) { ++ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl; ++ ++ DHCP6_OPTION_SERVER_ID Server = { 0 }; ++ ++ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID); ++ Server.OptionLen = HTONS (1500); // This length would overflow without a check ++ UINT8 Index = 0; ++ ++ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer; ++ ++ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); ++ ++ CopyMem (Cursor, &Server, sizeof (Server)); ++ Cursor += sizeof (Server); ++ ++ // Update the packet length ++ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); ++ Packet->Size = PACKET_SIZE; ++ ++ // This is going to be stopped by the duid overflow check ++ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER); ++} ++ ++TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) { ++ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter ++ ++ RequestOpt.OpCode = HTONS (0x1337); ++ RequestOpt.OpLen = 0; // valid length ++ ++ UINT8 Index = 0; ++ ++ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index]; ++ ++ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); ++ ++ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); ++ Cursor += sizeof (RequestOpt); ++ ++ // Update the packet length ++ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); ++ Packet->Size = PACKET_SIZE; ++ ++ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS); ++} ++ ++TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) { ++ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter ++ ++ RequestOpt.OpCode = HTONS (0x1337); ++ RequestOpt.OpLen = 1500; // this length would overflow without a check ++ ++ UINT8 Index = 0; ++ ++ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index]; ++ ++ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option); ++ ++ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); ++ Cursor += sizeof (RequestOpt); ++ ++ // Update the packet length ++ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet); ++ Packet->Size = PACKET_SIZE; ++ ++ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// PxeBcDhcp6Discover Test ++/////////////////////////////////////////////////////////////////////////////// ++ ++class PxeBcDhcp6DiscoverTest : public ::testing::Test { ++public: ++ PXEBC_PRIVATE_DATA Private = { 0 }; ++ EFI_UDP6_PROTOCOL Udp6Read; ++ ++protected: ++ MockUefiRuntimeServicesTableLib RtServicesMock; ++ ++ // Add any setup code if needed ++ virtual void ++ SetUp ( ++ ) ++ { ++ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); ++ ++ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL ++ // The function under test really only needs the following: ++ // UdpWrite ++ // UdpRead ++ ++ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; ++ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; ++ ++ // Need to setup EFI_UDP6_PROTOCOL ++ // The function under test really only needs the following: ++ // Configure ++ ++ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure; ++ Private.Udp6Read = &Udp6Read; ++ } ++ ++ // Add any cleanup code if needed ++ virtual void ++ TearDown ( ++ ) ++ { ++ if (Private.Dhcp6Request != NULL) { ++ FreePool (Private.Dhcp6Request); ++ } ++ ++ // Clean up any resources or variables ++ } ++}; ++ ++// Test Description ++// This will cause an overflow by an untrusted packet during the option parsing ++TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) { ++ EFI_IPv6_ADDRESS DestIp = { 0 }; ++ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter ++ ++ RequestOpt.OpCode = HTONS (0x1337); ++ RequestOpt.OpLen = HTONS (0xFFFF); // overflow ++ ++ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); ++ ++ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); ++ Cursor += sizeof (RequestOpt); ++ ++ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request); ++ ++ EXPECT_CALL (RtServicesMock, gRT_GetTime) ++ .WillOnce (::testing::Return (0)); ++ ++ ASSERT_EQ ( ++ PxeBcDhcp6Discover ( ++ &(PxeBcDhcp6DiscoverTest::Private), ++ 0, ++ NULL, ++ FALSE, ++ (EFI_IP_ADDRESS *)&DestIp ++ ), ++ EFI_OUT_OF_RESOURCES ++ ); ++} ++ ++// Test Description ++// This will test that we can handle a packet with a valid option length ++TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) { ++ EFI_IPv6_ADDRESS DestIp = { 0 }; ++ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter ++ ++ RequestOpt.OpCode = HTONS (0x1337); ++ RequestOpt.OpLen = HTONS (0x30); ++ ++ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); ++ ++ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); ++ Cursor += sizeof (RequestOpt); ++ ++ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request); ++ ++ EXPECT_CALL (RtServicesMock, gRT_GetTime) ++ .WillOnce (::testing::Return (0)); ++ ++ ASSERT_EQ ( ++ PxeBcDhcp6Discover ( ++ &(PxeBcDhcp6DiscoverTest::Private), ++ 0, ++ NULL, ++ FALSE, ++ (EFI_IP_ADDRESS *)&DestIp ++ ), ++ EFI_SUCCESS ++ ); ++} +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +index 48ab238d..4c6173de 100644 +--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h ++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +@@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses ( + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 + ); + ++/** ++ Build and send out the request packet for the bootfile, and parse the reply. ++ ++ @param[in] Private The pointer to PxeBc private data. ++ @param[in] Index PxeBc option boot item type. ++ ++ @retval EFI_SUCCESS Successfully discovered the boot file. ++ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. ++ @retval EFI_NOT_FOUND Can't get the PXE reply packet. ++ @retval Others Failed to discover the boot file. ++ ++**/ ++EFI_STATUS ++PxeBcRequestBootService ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN UINT32 Index ++ ); ++ + #endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ +-- +2.33.0 + diff --git a/0069-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch b/0069-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch new file mode 100644 index 0000000000000000000000000000000000000000..30b772b477ccf387c81f35336e73d69fbbe54277 --- /dev/null +++ b/0069-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch @@ -0,0 +1,1569 @@ +From 79b32f0276708a906ced8ce54b307bc42dc6effd Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Tue, 13 Feb 2024 10:46:00 -0800 +Subject: [PATCH 1/3] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 + Related Patch + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4673 +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 + +This was not part of the Quarkslab bugs however the same pattern +as CVE-2023-45229 exists in Dhcp6UpdateIaInfo. + +This patch replaces the code in question with the safe function +created to patch CVE-2023-45229 + +> +> if (EFI_ERROR ( +> Dhcp6SeekInnerOptionSafe ( +> Instance->Config->IaDescriptor.Type, +> Option, +> OptionLen, +> &IaInnerOpt, +> &IaInnerLen +> ) +> )) +> { +> return EFI_DEVICE_ERROR; +> } +> + +Additionally corrects incorrect usage of macro to read the status + +> - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN + (Option))); +> + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) +DHCP6_OFFSET_OF_STATUS_CODE (Option)); + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +Reviewed-by: Leif Lindholm + +reference: https://github.com/tianocore/edk2/pull/5372 +Signed-off-by: yexiao +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 877 ++++++++++++++++++---------------- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.h | 22 + + 2 files changed, 479 insertions(+), 420 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index 9a31c118..5b337a09 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -3,7 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- Copyright (c) Microsoft Corporation ++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent + **/ +@@ -541,13 +541,23 @@ Dhcp6UpdateIaInfo ( + { + EFI_STATUS Status; + UINT8 *Option; ++ UINT32 OptionLen; + UINT8 *IaInnerOpt; + UINT16 IaInnerLen; + UINT16 StsCode; + UINT32 T1; + UINT32 T2; + ++ T1 = 0; ++ T2 = 0; ++ + ASSERT (Instance->Config != NULL); ++ ++ // OptionLen is the length of the Options excluding the DHCP header. ++ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last ++ // byte of the Option[] field. ++ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); ++ + // + // If the reply was received in response to a solicit with rapid commit option, + // request, renew or rebind message, the client updates the information it has +@@ -562,13 +572,29 @@ Dhcp6UpdateIaInfo ( + // + Option = Dhcp6SeekIaOption ( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ OptionLen, + &Instance->Config->IaDescriptor + ); + if (Option == NULL) { + return EFI_DEVICE_ERROR; + } + ++ // ++ // Calculate the distance from Packet->Dhcp6.Option to the IA option. ++ // ++ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is ++ // the size of the whole packet, including the DHCP header, and Packet->Length ++ // is the length of the DHCP message body, excluding the DHCP header. ++ // ++ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of ++ // DHCP6 option area to the start of the IA option. ++ // ++ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the ++ // IA option to the end of the DHCP6 option area, thus subtract the space ++ // up until this option ++ // ++ OptionLen = OptionLen - (UINT32)(Option - Packet->Dhcp6.Option); ++ + // + // The format of the IA_NA option is: + // +@@ -604,31 +630,32 @@ Dhcp6UpdateIaInfo ( + // + + // +- // sizeof (option-code + option-len + IaId) = 8 +- // sizeof (option-code + option-len + IaId + T1) = 12 +- // sizeof (option-code + option-len + IaId + T1 + T2) = 16 +- // +- // The inner options still start with 2 bytes option-code and 2 bytes option-len. ++ // Seek the inner option + // ++ if (EFI_ERROR ( ++ Dhcp6SeekInnerOptionSafe ( ++ Instance->Config->IaDescriptor.Type, ++ Option, ++ OptionLen, ++ &IaInnerOpt, ++ &IaInnerLen ++ ) ++ )) ++ { ++ return EFI_DEVICE_ERROR; ++ } ++ + if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { +- T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); +- T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); ++ T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); ++ T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); + // + // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, + // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes +- // the remainder of the message as though the server had not included the invalid IA_NA option. ++ // the remainder of the message as though the server had not included the invalid IA_NA option. + // + if (T1 > T2 && T2 > 0) { + return EFI_DEVICE_ERROR; + } +- IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); +- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); +- } else { +- T1 = 0; +- T2 = 0; +- +- IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); +- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); + } + + // +@@ -654,7 +681,7 @@ Dhcp6UpdateIaInfo ( + Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + + if (Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (Option)))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -674,86 +701,96 @@ Dhcp6UpdateIaInfo ( + return Status; + } + +-/** +- Seeks the Inner Options from a DHCP6 Option +- +- @param[in] IaType The type of the IA option. +- @param[in] Option The pointer to the DHCP6 Option. +- @param[in] OptionLen The length of the DHCP6 Option. +- @param[out] IaInnerOpt The pointer to the IA inner option. +- @param[out] IaInnerLen The length of the IA inner option. +- +- @retval EFI_SUCCESS Seek the inner option successfully. +- @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, +- the pointers are not modified +-**/ +-EFI_STATUS +-Dhcp6SeekInnerOptionSafe ( +- IN UINT16 IaType, +- IN UINT8 *Option, +- IN UINT32 OptionLen, +- OUT UINT8 **IaInnerOpt, +- OUT UINT16 *IaInnerLen +- ) +-{ +- UINT16 IaInnerLenTmp; +- UINT8 *IaInnerOptTmp; +- +- if (Option == NULL) { +- ASSERT (Option != NULL); +- return EFI_DEVICE_ERROR; +- } +- +- if (IaInnerOpt == NULL) { +- ASSERT (IaInnerOpt != NULL); +- return EFI_DEVICE_ERROR; +- } +- +- if (IaInnerLen == NULL) { +- ASSERT (IaInnerLen != NULL); +- return EFI_DEVICE_ERROR; +- } +- +- if (IaType == Dhcp6OptIana) { +- // Verify we have a fully formed IA_NA +- if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { +- return EFI_DEVICE_ERROR; +- } +- +- // +- IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); +- +- // Verify the IaInnerLen is valid. +- IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); +- if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { +- return EFI_DEVICE_ERROR; +- } +- +- IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; +- } else if (IaType == Dhcp6OptIata) { +- // Verify the OptionLen is valid. +- if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { +- return EFI_DEVICE_ERROR; +- } +- +- IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); +- +- // Verify the IaInnerLen is valid. +- IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); +- if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { +- return EFI_DEVICE_ERROR; +- } +- +- IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; +- } else { +- return EFI_DEVICE_ERROR; +- } +- +- *IaInnerOpt = IaInnerOptTmp; +- *IaInnerLen = IaInnerLenTmp; +- +- return EFI_SUCCESS; +-} ++/** ++ Seeks the Inner Options from a DHCP6 Option ++ ++ @param[in] IaType The type of the IA option. ++ @param[in] Option The pointer to the DHCP6 Option. ++ @param[in] OptionLen The length of the DHCP6 Option. ++ @param[out] IaInnerOpt The pointer to the IA inner option. ++ @param[out] IaInnerLen The length of the IA inner option. ++ ++ @retval EFI_SUCCESS Seek the inner option successfully. ++ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, ++ the pointers are not modified ++**/ ++EFI_STATUS ++Dhcp6SeekInnerOptionSafe ( ++ IN UINT16 IaType, ++ IN UINT8 *Option, ++ IN UINT32 OptionLen, ++ OUT UINT8 **IaInnerOpt, ++ OUT UINT16 *IaInnerLen ++ ) ++{ ++ UINT16 IaInnerLenTmp; ++ UINT8 *IaInnerOptTmp; ++ ++ if (Option == NULL) { ++ ASSERT (Option != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaInnerOpt == NULL) { ++ ASSERT (IaInnerOpt != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaInnerLen == NULL) { ++ ASSERT (IaInnerLen != NULL); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ if (IaType == Dhcp6OptIana) { ++ // ++ // Verify we have a fully formed IA_NA ++ // ++ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Get the IA Inner Option and Length ++ // ++ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); ++ ++ // ++ // Verify the IaInnerLen is valid. ++ // ++ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); ++ if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; ++ } else if (IaType == Dhcp6OptIata) { ++ // ++ // Verify the OptionLen is valid. ++ // ++ if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); ++ ++ // ++ // Verify the IaInnerLen is valid. ++ // ++ IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); ++ if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; ++ } else { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ *IaInnerOpt = IaInnerOptTmp; ++ *IaInnerLen = IaInnerLenTmp; ++ ++ return EFI_SUCCESS; ++} + + /** + Seek StatusCode Option in package. A Status Code option may appear in the +@@ -778,12 +815,12 @@ Dhcp6SeekStsOption ( + UINT8 *IaInnerOpt; + UINT16 IaInnerLen; + UINT16 StsCode; +- UINT32 OptionLen; +- +- // OptionLen is the length of the Options excluding the DHCP header. +- // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last +- // byte of the Option[] field. +- OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); ++ UINT32 OptionLen; ++ ++ // OptionLen is the length of the Options excluding the DHCP header. ++ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last ++ // byte of the Option[] field. ++ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); + + // + // Seek StatusCode option directly in DHCP message body. That is, search in +@@ -791,12 +828,12 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- OptionLen, ++ OptionLen, + Dhcp6OptStatusCode + ); + + if (*Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -807,7 +844,7 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekIaOption ( + Packet->Dhcp6.Option, +- OptionLen, ++ OptionLen, + &Instance->Config->IaDescriptor + ); + if (*Option == NULL) { +@@ -815,34 +852,34 @@ Dhcp6SeekStsOption ( + } + + // +- // Calculate the distance from Packet->Dhcp6.Option to the IA option. ++ // Calculate the distance from Packet->Dhcp6.Option to the IA option. + // +- // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is +- // the size of the whole packet, including the DHCP header, and Packet->Length +- // is the length of the DHCP message body, excluding the DHCP header. ++ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is ++ // the size of the whole packet, including the DHCP header, and Packet->Length ++ // is the length of the DHCP message body, excluding the DHCP header. + // +- // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of +- // DHCP6 option area to the start of the IA option. ++ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of ++ // DHCP6 option area to the start of the IA option. + // +- // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the +- // IA option to the end of the DHCP6 option area, thus subtract the space +- // up until this option ++ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the ++ // IA option to the end of the DHCP6 option area, thus subtract the space ++ // up until this option + // +- OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); ++ OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); + // +- // Seek the inner option ++ // Seek the inner option + // +- if (EFI_ERROR ( +- Dhcp6SeekInnerOptionSafe ( +- Instance->Config->IaDescriptor.Type, +- *Option, +- OptionLen, +- &IaInnerOpt, +- &IaInnerLen +- ) +- )) +- { +- return EFI_DEVICE_ERROR; ++ if (EFI_ERROR ( ++ Dhcp6SeekInnerOptionSafe ( ++ Instance->Config->IaDescriptor.Type, ++ *Option, ++ OptionLen, ++ &IaInnerOpt, ++ &IaInnerLen ++ ) ++ )) ++ { ++ return EFI_DEVICE_ERROR; + } + + // +@@ -866,7 +903,7 @@ Dhcp6SeekStsOption ( + // + *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + if (*Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -1014,8 +1051,8 @@ Dhcp6SendSolicitMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1029,38 +1066,38 @@ Dhcp6SendSolicitMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -1068,16 +1105,16 @@ Dhcp6SendSolicitMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Status = Dhcp6AppendOption( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + ASSERT (Packet->Size > Packet->Length + 8); +@@ -1088,7 +1125,7 @@ Dhcp6SendSolicitMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1103,7 +1140,7 @@ Dhcp6SendSolicitMsg ( + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1115,14 +1152,14 @@ Dhcp6SendSolicitMsg ( + Elapsed, + Instance->Config->SolicitRetransmission + ); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1192,7 +1229,7 @@ Dhcp6SendRequestMsg ( + // + Option = Dhcp6SeekOption ( + Instance->AdSelect->Dhcp6.Option, +- Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), ++ Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1214,8 +1251,8 @@ Dhcp6SendRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1229,49 +1266,49 @@ Dhcp6SendRequestMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -1279,16 +1316,16 @@ Dhcp6SendRequestMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + ASSERT (Packet->Size > Packet->Length + 8); +@@ -1299,7 +1336,7 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1315,21 +1352,21 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1378,7 +1415,7 @@ Dhcp6SendDeclineMsg ( + // + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - sizeof (EFI_DHCP6_HEADER), ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1395,8 +1432,8 @@ Dhcp6SendDeclineMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1410,49 +1447,49 @@ Dhcp6SendDeclineMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } +- +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, +- DecIa, +- 0, +- 0, +- Packet->Dhcp6.Header.MessageType +- ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } ++ ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ DecIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + ASSERT (Packet->Size > Packet->Length + 8); + +@@ -1462,7 +1499,7 @@ Dhcp6SendDeclineMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1478,21 +1515,21 @@ Dhcp6SendDeclineMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1540,7 +1577,7 @@ Dhcp6SendReleaseMsg ( + // + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - sizeof (EFI_DHCP6_HEADER), ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1554,8 +1591,8 @@ Dhcp6SendReleaseMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1569,52 +1606,52 @@ Dhcp6SendReleaseMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // ServerId is extracted from packet, it's network order. + // +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } +- +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, +- RelIa, +- 0, +- 0, +- Packet->Dhcp6.Header.MessageType +- ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } ++ ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ RelIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + ASSERT (Packet->Size > Packet->Length + 8); + +@@ -1624,7 +1661,7 @@ Dhcp6SendReleaseMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1636,21 +1673,21 @@ Dhcp6SendReleaseMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -1710,8 +1747,8 @@ Dhcp6SendRenewRebindMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1725,38 +1762,38 @@ Dhcp6SendRenewRebindMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + if (!RebindRequest) { + // +@@ -1768,7 +1805,7 @@ Dhcp6SendRenewRebindMsg ( + + Option = Dhcp6SeekOption ( + LastReply->Dhcp6.Option, +- LastReply->Length - sizeof (EFI_DHCP6_HEADER), ++ LastReply->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + if (Option == NULL) { +@@ -1778,16 +1815,16 @@ Dhcp6SendRenewRebindMsg ( + + ServerId = (EFI_DHCP6_DUID *) (Option + 2); + +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + // +@@ -1796,16 +1833,16 @@ Dhcp6SendRenewRebindMsg ( + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + + UserOpt = Instance->Config->OptionList[Index]; +- Status = Dhcp6AppendOption( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + ASSERT (Packet->Size > Packet->Length + 8); +@@ -1819,7 +1856,7 @@ Dhcp6SendRenewRebindMsg ( + Status = Dhcp6CallbackUser (Instance, Event, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -1838,21 +1875,21 @@ Dhcp6SendRenewRebindMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -2016,8 +2053,8 @@ Dhcp6SendInfoRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -2034,38 +2071,38 @@ Dhcp6SendInfoRequestMsg ( + + if (SendClientId) { + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + OptionRequest->OpCode, + OptionRequest->OpLen, + OptionRequest->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. +@@ -2073,16 +2110,16 @@ Dhcp6SendInfoRequestMsg ( + for (Index = 0; Index < OptionCount; Index++) { + + UserOpt = OptionList[Index]; +- Status = Dhcp6AppendOption( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + ASSERT (Packet->Size > Packet->Length + 8); +@@ -2098,21 +2135,21 @@ Dhcp6SendInfoRequestMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -2164,8 +2201,8 @@ Dhcp6SendConfirmMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- Status = EFI_OUT_OF_RESOURCES; +- goto ON_ERROR; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -2179,54 +2216,54 @@ Dhcp6SendConfirmMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendETOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Status = Dhcp6AppendIaOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Status = Dhcp6AppendOption ( +- Packet, +- &Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); +- if (EFI_ERROR (Status)) { +- goto ON_ERROR; +- } ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + ASSERT (Packet->Size > Packet->Length + 8); +@@ -2237,7 +2274,7 @@ Dhcp6SendConfirmMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // +@@ -2253,21 +2290,21 @@ Dhcp6SendConfirmMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- goto ON_ERROR; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); +- +-ON_ERROR: +- +- if (Packet) { +- FreePool (Packet); +- } +- +- return Status; ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + +@@ -2313,7 +2350,7 @@ Dhcp6HandleReplyMsg ( + // + Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptRapidCommit + ); + +@@ -2461,7 +2498,7 @@ Dhcp6HandleReplyMsg ( + // + // Any error status code option is found. + // +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); + switch (StsCode) { + case Dhcp6StsUnspecFail: + // +@@ -2592,7 +2629,7 @@ Dhcp6SelectAdvertiseMsg ( + // + Option = Dhcp6SeekOption( + AdSelect->Dhcp6.Option, +- AdSelect->Length - sizeof (EFI_DHCP6_HEADER), ++ AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerUnicast + ); + +@@ -2604,7 +2641,7 @@ Dhcp6SelectAdvertiseMsg ( + return EFI_OUT_OF_RESOURCES; + } + +- CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); ++ CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); + } + + // +@@ -2658,7 +2695,7 @@ Dhcp6HandleAdvertiseMsg ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptRapidCommit + ); + +@@ -2754,7 +2791,7 @@ Dhcp6HandleAdvertiseMsg ( + CopyMem (Instance->AdSelect, Packet, Packet->Size); + + if (Option != NULL) { +- Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); ++ Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); + } + } else { + // +@@ -2825,11 +2862,11 @@ Dhcp6HandleStateful ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, ++ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptClientId + ); + +- if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { ++ if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { + goto ON_CONTINUE; + } + +@@ -2838,7 +2875,7 @@ Dhcp6HandleStateful ( + // + Option = Dhcp6SeekOption( + Packet->Dhcp6.Option, +- Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, ++ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptServerId + ); + +@@ -2943,7 +2980,7 @@ Dhcp6HandleStateless ( + // + Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerId + ); + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h +index 554f0f5e..3243f05b 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h +@@ -218,4 +218,26 @@ Dhcp6OnTimerTick ( + IN VOID *Context + ); + ++/** ++ Seeks the Inner Options from a DHCP6 Option ++ ++ @param[in] IaType The type of the IA option. ++ @param[in] Option The pointer to the DHCP6 Option. ++ @param[in] OptionLen The length of the DHCP6 Option. ++ @param[out] IaInnerOpt The pointer to the IA inner option. ++ @param[out] IaInnerLen The length of the IA inner option. ++ ++ @retval EFI_SUCCESS Seek the inner option successfully. ++ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, ++ the pointers are not modified ++**/ ++EFI_STATUS ++Dhcp6SeekInnerOptionSafe ( ++ IN UINT16 IaType, ++ IN UINT8 *Option, ++ IN UINT32 OptionLen, ++ OUT UINT8 **IaInnerOpt, ++ OUT UINT16 *IaInnerLen ++ ); ++ + #endif +-- +2.33.0 + diff --git a/0070-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch b/0070-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cf15af79cfc0e8378fd1cf4fcd4d55f6877da17 --- /dev/null +++ b/0070-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch @@ -0,0 +1,791 @@ +From 6acd7ea3c036fcd9ac60f990dca2d28a0c3c1cdc Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Tue, 13 Feb 2024 10:46:01 -0800 +Subject: [PATCH 2/3] NetworkPkg: Dhcp6Dxe: Removes duplicate check and + replaces with macro + +Removes duplicate check after merge + +> +> // +> // Verify the PacketCursor is within the packet +> // +> if ( (*PacketCursor < Packet->Dhcp6.Option) +> || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - +sizeof (EFI_DHCP6_HEADER)))) +> { +> return EFI_INVALID_PARAMETER; +> } +> + +Converts the check to a macro and replaces all instances of the check +with the macro + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +Reviewed-by: Leif Lindholm + +reference: https://github.com/tianocore/edk2/pull/5372 +Signed-off-by: yexiao +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 598 ++++++++++++++--------------- + 1 file changed, 295 insertions(+), 303 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index 2b4005b4..eafa72eb 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -10,6 +10,14 @@ + + #include "Dhcp6Impl.h" + ++// ++// Verifies the packet cursor is within the packet ++// otherwise it is invalid ++// ++#define IS_INVALID_PACKET_CURSOR(PacketCursor, Packet) \ ++ (((*PacketCursor) < (Packet)->Dhcp6.Option) || \ ++ ((*PacketCursor) >= (Packet)->Dhcp6.Option + ((Packet)->Size - sizeof(EFI_DHCP6_HEADER))) \ ++ ) + + /** + Generate client Duid in the format of Duid-llt. +@@ -601,33 +609,33 @@ Dhcp6OnTransmitted ( + + + /** +- Append the option to Buf, update the length of packet, and move Buf to the end. ++ Append the option to Buf, update the length of packet, and move Buf to the end. + +- @param[in, out] Packet A pointer to the packet, on success Packet->Length +- will be updated. +- @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor +- will be moved to the end of the option. +- @param[in] OptType The option type. +- @param[in] OptLen The length of option contents. +- @param[in] Data The pointer to the option content. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. ++ @param[in] OptType The option type. ++ @param[in] OptLen The length of option contents. ++ @param[in] Data The pointer to the option content. + +- @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid +- @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. +- @retval EFI_SUCCESS The option is appended successfully. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-EFI_STATUS ++EFI_STATUS + Dhcp6AppendOption ( +- IN OUT EFI_DHCP6_PACKET *Packet, +- IN OUT UINT8 **PacketCursor, +- IN UINT16 OptType, +- IN UINT16 OptLen, +- IN UINT8 *Data ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN UINT16 OptType, ++ IN UINT16 OptLen, ++ IN UINT8 *Data + ) + { +- UINT32 Length; +- UINT32 BytesNeeded; +- ++ UINT32 Length; ++ UINT32 BytesNeeded; ++ + // + // The format of Dhcp6 option: + // +@@ -640,94 +648,83 @@ Dhcp6AppendOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + +- // +- // Verify the arguments are valid +- // +- if (Packet == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { +- return EFI_INVALID_PARAMETER; +- } +- +- if (Data == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if (OptLen == 0) { +- return EFI_INVALID_PARAMETER; +- } +- +- // +- // Verify the PacketCursor is within the packet +- // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { +- return EFI_INVALID_PARAMETER; +- } +- +- // +- // Calculate the bytes needed for the option +- // +- BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); +- +- // +- // Space remaining in the packet +- // +- Length = Packet->Size - Packet->Length; +- if (Length < BytesNeeded) { +- return EFI_BUFFER_TOO_SMALL; +- } +- +- // +- // Verify the PacketCursor is within the packet +- // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { +- return EFI_INVALID_PARAMETER; +- } +- +- WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); +- *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; +- WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); +- *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; +- CopyMem (*PacketCursor, Data, NTOHS (OptLen)); +- *PacketCursor += NTOHS (OptLen); +- +- // Update the packet length by the length of the option + 4 bytes +- Packet->Length += BytesNeeded; +- +- return EFI_SUCCESS; ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Data == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (OptLen == 0) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Calculate the bytes needed for the option ++ // ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ CopyMem (*PacketCursor, Data, NTOHS (OptLen)); ++ *PacketCursor += NTOHS (OptLen); ++ ++ // Update the packet length by the length of the option + 4 bytes ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + /** + Append the appointed IA Address option to Buf, and move Buf to the end. + +- @param[in, out] Packet A pointer to the packet, on success Packet->Length +- will be updated. +- @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor +- will be moved to the end of the option. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] IaAddr The pointer to the IA Address. + @param[in] MessageType Message type of DHCP6 package. + +- @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid +- @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. +- @retval EFI_SUCCESS The option is appended successfully. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-EFI_STATUS ++EFI_STATUS + Dhcp6AppendIaAddrOption ( +- IN OUT EFI_DHCP6_PACKET *Packet, +- IN OUT UINT8 **PacketCursor, ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, + IN EFI_DHCP6_IA_ADDRESS *IaAddr, + IN UINT32 MessageType + ) + { +- UINT32 BytesNeeded; +- UINT32 Length; ++ UINT32 BytesNeeded; ++ UINT32 Length; + + // The format of the IA Address option is: + // +@@ -750,60 +747,58 @@ Dhcp6AppendIaAddrOption ( + // . . + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +- // +- // Verify the arguments are valid +- // +- if (Packet == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { +- return EFI_INVALID_PARAMETER; +- } +- +- if (IaAddr == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- // +- // Verify the PacketCursor is within the packet +- // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { +- return EFI_INVALID_PARAMETER; +- } +- +- BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; +- BytesNeeded += sizeof (EFI_IPv6_ADDRESS); +- // +- // Even if the preferred-lifetime is 0, it still needs to store it. +- // +- BytesNeeded += sizeof (IaAddr->PreferredLifetime); +- // +- // Even if the valid-lifetime is 0, it still needs to store it. +- // +- BytesNeeded += sizeof (IaAddr->ValidLifetime); +- +- // +- // Space remaining in the packet +- // +- Length = Packet->Size - Packet->Length; +- if (Length < BytesNeeded) { +- return EFI_BUFFER_TOO_SMALL; +- } +- ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (IaAddr == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (EFI_IPv6_ADDRESS); ++ // ++ // Even if the preferred-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->PreferredLifetime); ++ // ++ // Even if the valid-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of Ia Address option type + // +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); +- *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); +- *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + +- CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); +- *PacketCursor += sizeof (EFI_IPv6_ADDRESS); ++ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); ++ *PacketCursor += sizeof (EFI_IPv6_ADDRESS); + + // + // Fill the value of preferred-lifetime and valid-lifetime. +@@ -811,57 +806,57 @@ Dhcp6AppendIaAddrOption ( + // should set to 0 when initiate a Confirm message. + // + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); + } +- *PacketCursor += sizeof (IaAddr->PreferredLifetime); ++ *PacketCursor += sizeof (IaAddr->PreferredLifetime); + + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); + } +- *PacketCursor += sizeof (IaAddr->ValidLifetime); +- +- // +- // Update the packet length +- // +- Packet->Length += BytesNeeded; +- +- return EFI_SUCCESS; ++ *PacketCursor += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + + /** + Append the appointed Ia option to Buf, and move Buf to the end. + +- @param[in, out] Packet A pointer to the packet, on success Packet->Length +- will be updated. +- @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor +- will be moved to the end of the option. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Ia The pointer to the Ia. + @param[in] T1 The time of T1. + @param[in] T2 The time of T2. + @param[in] MessageType Message type of DHCP6 package. + +- @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid +- @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. +- @retval EFI_SUCCESS The option is appended successfully. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-EFI_STATUS ++EFI_STATUS + Dhcp6AppendIaOption ( +- IN OUT EFI_DHCP6_PACKET *Packet, +- IN OUT UINT8 **PacketCursor, +- IN EFI_DHCP6_IA *Ia, +- IN UINT32 T1, +- IN UINT32 T2, +- IN UINT32 MessageType ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN EFI_DHCP6_IA *Ia, ++ IN UINT32 T1, ++ IN UINT32 T2, ++ IN UINT32 MessageType + ) + { +- UINT8 *AddrOpt; +- UINT16 *Len; +- UINTN Index; +- UINT32 BytesNeeded; +- UINT32 Length; +- EFI_STATUS Status; ++ UINT8 *AddrOpt; ++ UINT16 *Len; ++ UINTN Index; ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ EFI_STATUS Status; + + // + // The format of IA_NA and IA_TA option: +@@ -882,75 +877,73 @@ Dhcp6AppendIaOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + +- // +- // Verify the arguments are valid +- // +- if (Packet == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { +- return EFI_INVALID_PARAMETER; +- } +- +- if (Ia == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- // +- // Verify the PacketCursor is within the packet +- // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { +- return EFI_INVALID_PARAMETER; +- } +- +- BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; +- BytesNeeded += sizeof (Ia->Descriptor.IaId); +- // +- // + N for the IA_NA-options/IA_TA-options +- // Dhcp6AppendIaAddrOption will need to check the length for each address +- // +- if (Ia->Descriptor.Type == Dhcp6OptIana) { +- BytesNeeded += sizeof (T1) + sizeof (T2); +- } +- +- // +- // Space remaining in the packet +- // +- Length = (UINT16)(Packet->Size - Packet->Length); +- if (Length < BytesNeeded) { +- return EFI_BUFFER_TOO_SMALL; +- } +- +- ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Ia == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (Ia->Descriptor.IaId); ++ // ++ // + N for the IA_NA-options/IA_TA-options ++ // Dhcp6AppendIaAddrOption will need to check the length for each address ++ // ++ if (Ia->Descriptor.Type == Dhcp6OptIana) { ++ BytesNeeded += sizeof (T1) + sizeof (T2); ++ } ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = (UINT16)(Packet->Size - Packet->Length); ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ ++ + // + // Fill the value of Ia option type + // +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); +- *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of Ia option later, keep the pointer first + // +- Len = (UINT16 *)*PacketCursor; +- *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ Len = (UINT16 *)*PacketCursor; ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill the value of iaid + // +- WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); +- *PacketCursor += sizeof (Ia->Descriptor.IaId); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); ++ *PacketCursor += sizeof (Ia->Descriptor.IaId); + + // + // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified. + // + if (Ia->Descriptor.Type == Dhcp6OptIana) { +- WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); +- *PacketCursor += sizeof (T1); +- WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); +- *PacketCursor += sizeof (T2); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); ++ *PacketCursor += sizeof (T1); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); ++ *PacketCursor += sizeof (T2); + } + + // +@@ -958,51 +951,52 @@ Dhcp6AppendIaOption ( + // + for (Index = 0; Index < Ia->IaAddressCount; Index++) { + AddrOpt = (UINT8 *) Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); +- Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); +- if (EFI_ERROR (Status)) { +- return Status; +- } ++ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } + } + ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ + // + // Fill the value of Ia option length + // +- *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); +- +- // +- // Update the packet length +- // +- Packet->Length += BytesNeeded; ++ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); + +- return EFI_SUCCESS; ++ return EFI_SUCCESS; + } + + /** + Append the appointed Elapsed time option to Buf, and move Buf to the end. + +- @param[in, out] Packet A pointer to the packet, on success Packet->Length +- @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor +- will be moved to the end of the option. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Instance The pointer to the Dhcp6 instance. + @param[out] Elapsed The pointer to the elapsed time value in +- the generated packet. ++ the generated packet. + +- @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid +- @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. +- @retval EFI_SUCCESS The option is appended successfully. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-EFI_STATUS ++EFI_STATUS + Dhcp6AppendETOption ( +- IN OUT EFI_DHCP6_PACKET *Packet, +- IN OUT UINT8 **PacketCursor, +- IN DHCP6_INSTANCE *Instance, +- OUT UINT16 **Elapsed ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN DHCP6_INSTANCE *Instance, ++ OUT UINT16 **Elapsed + ) + { +- UINT32 BytesNeeded; +- UINT32 Length; +- ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ + // + // The format of elapsed time option: + // +@@ -1014,70 +1008,68 @@ Dhcp6AppendETOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + +- // +- // Verify the arguments are valid +- // +- if (Packet == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { +- return EFI_INVALID_PARAMETER; +- } +- +- if (Instance == NULL) { +- return EFI_INVALID_PARAMETER; +- } +- +- if ((Elapsed == NULL)) { +- return EFI_INVALID_PARAMETER; +- } +- +- // +- // Verify the PacketCursor is within the packet +- // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { +- return EFI_INVALID_PARAMETER; +- } +- +- BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; +- // +- // + 2 for elapsed-time +- // +- BytesNeeded += sizeof (UINT16); +- // +- // Space remaining in the packet +- // +- Length = Packet->Size - Packet->Length; +- if (Length < BytesNeeded) { +- return EFI_BUFFER_TOO_SMALL; +- } +- ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Instance == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((Elapsed == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ // ++ // + 2 for elapsed-time ++ // ++ BytesNeeded += sizeof (UINT16); ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of elapsed-time option type. + // +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); +- *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of elapsed-time option, which is fixed. + // +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); +- *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill in elapsed time value with 0 value for now. The actual value is + // filled in later just before the packet is transmitted. + // +- WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); +- *Elapsed = (UINT16 *)*PacketCursor; +- *PacketCursor += sizeof (UINT16); ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); ++ *Elapsed = (UINT16 *)*PacketCursor; ++ *PacketCursor += sizeof (UINT16); ++ ++ Packet->Length += BytesNeeded; + +- Packet->Length += BytesNeeded; +- +- return EFI_SUCCESS; ++ return EFI_SUCCESS; + } + + /** +-- +2.33.0 + diff --git a/0071-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch b/0071-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch new file mode 100644 index 0000000000000000000000000000000000000000..a66500f438ee2a64ba952a9c2d3ed4d110528d12 --- /dev/null +++ b/0071-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch @@ -0,0 +1,53 @@ +From 90e12ecf3c9d8a4c13ae2dd9350f86bb47188b2b Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Tue, 13 Feb 2024 10:46:02 -0800 +Subject: [PATCH 3/3] NetworkPkg: Dhcp6Dxe: Packet-Length is not updated before + appending + +In order for Dhcp6AppendIaAddrOption (..) to safely append the IA +Address option, the Packet-Length field must be updated before appending +the option. + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +Reviewed-by: Leif Lindholm + +reference: https://github.com/tianocore/edk2/pull/5372 +Signed-off-by: yexiao +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index eafa72eb..4c1ae0cc 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -946,6 +946,11 @@ Dhcp6AppendIaOption ( + *PacketCursor += sizeof (T2); + } + ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ + // + // Fill all the addresses belong to the Ia + // +@@ -957,11 +962,6 @@ Dhcp6AppendIaOption ( + } + } + +- // +- // Update the packet length +- // +- Packet->Length += BytesNeeded; +- + // + // Fill the value of Ia option length + // +-- +2.33.0 + diff --git a/0072-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch b/0072-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..993acaf1ecab4ef05ee963be746bf2b053c00544 --- /dev/null +++ b/0072-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch @@ -0,0 +1,173 @@ +From 6891715994ab7f5df8f5a2a10d743a24265d0c53 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 5 Mar 2024 15:43:53 +0000 +Subject: [PATCH 1/5] Fix unconstrained session cache growth in TLSv1.3 + +In TLSv1.3 we create a new session object for each ticket that we send. +We do this by duplicating the original session. If SSL_OP_NO_TICKET is in +use then the new session will be added to the session cache. However, if +early data is not in use (and therefore anti-replay protection is being +used), then multiple threads could be resuming from the same session +simultaneously. If this happens and a problem occurs on one of the threads, +then the original session object could be marked as not_resumable. When we +duplicate the session object this not_resumable status gets copied into the +new session object. The new session object is then added to the session +cache even though it is not_resumable. + +Subsequently, another bug means that the session_id_length is set to 0 for +sessions that are marked as not_resumable - even though that session is +still in the cache. Once this happens the session can never be removed from +the cache. When that object gets to be the session cache tail object the +cache never shrinks again and grows indefinitely. + +CVE-2024-2511 + +Reviewed-by: Neil Horman +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/24044) + +(cherry picked from commit 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce) +Signed-off-by: Liu-Ermeng +--- + .../openssl/include/openssl/sslerr.h | 4 +-- + .../Library/OpensslLib/openssl/ssl/ssl_err.c | 5 ++-- + .../Library/OpensslLib/openssl/ssl/ssl_lib.c | 5 ++-- + .../Library/OpensslLib/openssl/ssl/ssl_sess.c | 30 ++++++++++++++----- + .../openssl/ssl/statem/statem_srvr.c | 5 ++-- + 5 files changed, 33 insertions(+), 16 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h +index 82983d3..a3a6f03 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -219,7 +219,7 @@ int ERR_load_SSL_strings(void); + # define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 + # define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 + # define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +-# define SSL_F_SSL_SESSION_DUP 348 ++# define SSL_F_SSL_SESSION_DUP_INTERN 668 + # define SSL_F_SSL_SESSION_NEW 189 + # define SSL_F_SSL_SESSION_PRINT_FP 190 + # define SSL_F_SSL_SESSION_SET1_ID 423 +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c +index 4b12ed1..31435d6 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c +@@ -1,6 +1,6 @@ + /* + * Generated by util/mkerr.pl DO NOT EDIT +- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +@@ -312,7 +312,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "SSL_renegotiate_abbreviated"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, +- {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP_INTERN, 0), ++ "ssl_session_dup_intern"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), + "SSL_SESSION_print_fp"}, +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +index 7c7e597..ae33d18 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +@@ -3445,9 +3445,10 @@ void ssl_update_cache(SSL *s, int mode) + + /* + * If the session_id_length is 0, we are not supposed to cache it, and it +- * would be rather hard to do anyway :-) ++ * would be rather hard to do anyway :-). Also if the session has already ++ * been marked as not_resumable we should not cache it for later reuse. + */ +- if (s->session->session_id_length == 0) ++ if (s->session->session_id_length == 0 || s->session->not_resumable) + return; + + /* +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c +index 40c157b..4e87220 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c +@@ -94,16 +94,11 @@ SSL_SESSION *SSL_SESSION_new(void) + return ss; + } + +-SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) +-{ +- return ssl_session_dup(src, 1); +-} +- + /* + * Create a new SSL_SESSION and duplicate the contents of |src| into it. If + * ticket == 0 then no ticket information is duplicated, otherwise it is. + */ +-SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) ++static SSL_SESSION *ssl_session_dup_intern(SSL_SESSION *src, int ticket) + { + SSL_SESSION *dest; + +@@ -218,11 +213,32 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) + + return dest; + err: +- SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); ++ SSLerr(SSL_F_SSL_SESSION_DUP_INTERN, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(dest); + return NULL; + } + ++SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) ++{ ++ return ssl_session_dup_intern(src, 1); ++} ++ ++/* ++ * Used internally when duplicating a session which might be already shared. ++ * We will have resumed the original session. Subsequently we might have marked ++ * it as non-resumable (e.g. in another thread) - but this copy should be ok to ++ * resume from. ++ */ ++SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) ++{ ++ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket); ++ ++ if (sess != NULL) ++ sess->not_resumable = 0; ++ ++ return sess; ++} ++ + const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) + { + if (len) +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c +index 14cb27e..679855a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c +@@ -2402,9 +2402,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) + * so the following won't overwrite an ID that we're supposed + * to send back. + */ +- if (s->session->not_resumable || +- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) +- && !s->hit)) ++ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) ++ && !s->hit) + s->session->session_id_length = 0; + + if (usetls13) { +-- +2.33.0 + diff --git a/0073-Add-a-test-for-session-cache-handling.patch b/0073-Add-a-test-for-session-cache-handling.patch new file mode 100644 index 0000000000000000000000000000000000000000..9697f2acd983723a842e7d7c9f8573c54de415b1 --- /dev/null +++ b/0073-Add-a-test-for-session-cache-handling.patch @@ -0,0 +1,133 @@ +From 2977116cff409b22ded747f532f7d72b2684da81 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Mon, 4 Mar 2024 13:45:23 +0000 +Subject: [PATCH 2/5] Add a test for session cache handling + +Repeatedly create sessions to be added to the cache and ensure we never +exceed the expected size. + +Related to CVE-2024-2511 + +Reviewed-by: Neil Horman +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/24044) + +(cherry picked from commit 5f5b9e1ca1fad0215f623b8bd4955a2e8101f306) +Signed-off-by: Liu-Ermeng +--- + .../OpensslLib/openssl/test/sslapitest.c | 92 +++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +index 5c11810..89f718f 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +@@ -6471,6 +6471,97 @@ static int test_servername(int tst) + return testresult; + } + ++/* ++ * Test multiple resumptions and cache size handling ++ * Test 0: TLSv1.3 (max_early_data set) ++ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set) ++ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set) ++ * Test 3: TLSv1.2 ++ */ ++static int test_multi_resume(int idx) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *serverssl = NULL, *clientssl = NULL; ++ SSL_SESSION *sess = NULL; ++ int max_version = TLS1_3_VERSION; ++ int i, testresult = 0; ++ ++ if (idx == 3) ++ max_version = TLS1_2_VERSION; ++ ++ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), ++ TLS_client_method(), TLS1_VERSION, ++ max_version, &sctx, &cctx, cert, ++ privkey))) ++ goto end; ++ ++ /* ++ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for ++ * replay protection), or if SSL_OP_NO_TICKET is in use ++ */ ++ if (idx == 0 || idx == 2) { ++ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024))) ++ goto end; ++ } ++ if (idx == 1 || idx == 2) ++ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); ++ ++ SSL_CTX_sess_set_cache_size(sctx, 5); ++ ++ for (i = 0; i < 30; i++) { ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, ++ NULL, NULL)) ++ || !TEST_true(SSL_set_session(clientssl, sess))) ++ goto end; ++ ++ /* ++ * Recreate a bug where dynamically changing the max_early_data value ++ * can cause sessions in the session cache which cannot be deleted. ++ */ ++ if ((idx == 0 || idx == 2) && (i % 3) == 2) ++ SSL_set_max_early_data(serverssl, 0); ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) ++ goto end; ++ ++ if (sess == NULL || (idx == 0 && (i % 3) == 2)) { ++ if (!TEST_false(SSL_session_reused(clientssl))) ++ goto end; ++ } else { ++ if (!TEST_true(SSL_session_reused(clientssl))) ++ goto end; ++ } ++ SSL_SESSION_free(sess); ++ ++ /* Do a full handshake, followed by two resumptions */ ++ if ((i % 3) == 2) { ++ sess = NULL; ++ } else { ++ if (!TEST_ptr((sess = SSL_get1_session(clientssl)))) ++ goto end; ++ } ++ ++ SSL_shutdown(clientssl); ++ SSL_shutdown(serverssl); ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ serverssl = clientssl = NULL; ++ } ++ ++ /* We should never exceed the session cache size limit */ ++ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5)) ++ goto end; ++ ++ testresult = 1; ++ end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ SSL_SESSION_free(sess); ++ return testresult; ++} ++ + int setup_tests(void) + { + if (!TEST_ptr(certsdir = test_get_argument(0)) +@@ -6590,6 +6681,7 @@ int setup_tests(void) + ADD_ALL_TESTS(test_client_cert_cb, 2); + ADD_ALL_TESTS(test_ca_names, 3); + ADD_ALL_TESTS(test_servername, 10); ++ ADD_ALL_TESTS(test_multi_resume, 4); + return 1; + } + +-- +2.33.0 + diff --git a/0074-Extend-the-multi_resume-test-for-simultaneous-resump.patch b/0074-Extend-the-multi_resume-test-for-simultaneous-resump.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee30ded9106fc0c7dfc1635e8de38f444078bc74 --- /dev/null +++ b/0074-Extend-the-multi_resume-test-for-simultaneous-resump.patch @@ -0,0 +1,161 @@ +From 987232cacc779a7df4cf0ddb77b71814c96af16b Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 5 Mar 2024 15:35:51 +0000 +Subject: [PATCH 3/5] Extend the multi_resume test for simultaneous resumptions + +Test what happens if the same session gets resumed multiple times at the +same time - and one of them gets marked as not_resumable. + +Related to CVE-2024-2511 + +Reviewed-by: Neil Horman +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/24044) + +(cherry picked from commit 031b11a4054c972a5e2f07dfa81ce1842453253e) +Signed-off-by: Liu-Ermeng +--- + .../OpensslLib/openssl/test/sslapitest.c | 89 ++++++++++++++++++- + 1 file changed, 85 insertions(+), 4 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +index 89f718f..86f746c 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +@@ -6471,12 +6471,63 @@ static int test_servername(int tst) + return testresult; + } + ++struct resume_servername_cb_data { ++ int i; ++ SSL_CTX *cctx; ++ SSL_CTX *sctx; ++ SSL_SESSION *sess; ++ int recurse; ++}; ++ ++/* ++ * Servername callback. We use it here to run another complete handshake using ++ * the same session - and mark the session as not_resuamble at the end ++ */ ++static int resume_servername_cb(SSL *s, int *ad, void *arg) ++{ ++ struct resume_servername_cb_data *cbdata = arg; ++ SSL *serverssl = NULL, *clientssl = NULL; ++ int ret = SSL_TLSEXT_ERR_ALERT_FATAL; ++ ++ if (cbdata->recurse) ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ ++ if ((cbdata->i % 3) != 1) ++ return SSL_TLSEXT_ERR_OK; ++ ++ cbdata->recurse = 1; ++ ++ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl, ++ &clientssl, NULL, NULL)) ++ || !TEST_true(SSL_set_session(clientssl, cbdata->sess))) ++ goto end; ++ ++ ERR_set_mark(); ++ /* ++ * We expect this to fail - because the servername cb will fail. This will ++ * mark the session as not_resumable. ++ */ ++ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) { ++ ERR_clear_last_mark(); ++ goto end; ++ } ++ ERR_pop_to_mark(); ++ ++ ret = SSL_TLSEXT_ERR_OK; ++ end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ cbdata->recurse = 0; ++ return ret; ++} ++ + /* + * Test multiple resumptions and cache size handling + * Test 0: TLSv1.3 (max_early_data set) + * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set) + * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set) +- * Test 3: TLSv1.2 ++ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes) ++ * Test 4: TLSv1.2 + */ + static int test_multi_resume(int idx) + { +@@ -6485,9 +6536,19 @@ static int test_multi_resume(int idx) + SSL_SESSION *sess = NULL; + int max_version = TLS1_3_VERSION; + int i, testresult = 0; ++ struct resume_servername_cb_data cbdata; + +- if (idx == 3) ++#if defined(OPENSSL_NO_TLS1_2) ++ if (idx == 4) ++ return TEST_skip("TLSv1.2 is disabled in this build"); ++#else ++ if (idx == 4) + max_version = TLS1_2_VERSION; ++#endif ++#if defined(OSSL_NO_USABLE_TLS1_3) ++ if (idx != 4) ++ return TEST_skip("No usable TLSv1.3 in this build"); ++#endif + + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), TLS1_VERSION, +@@ -6503,17 +6564,37 @@ static int test_multi_resume(int idx) + if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024))) + goto end; + } +- if (idx == 1 || idx == 2) ++ if (idx == 1 || idx == 2 || idx == 3) + SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); + + SSL_CTX_sess_set_cache_size(sctx, 5); + ++ if (idx == 3) { ++ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb); ++ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata); ++ cbdata.cctx = cctx; ++ cbdata.sctx = sctx; ++ cbdata.recurse = 0; ++ } ++ + for (i = 0; i < 30; i++) { + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(SSL_set_session(clientssl, sess))) + goto end; + ++ /* ++ * Check simultaneous resumes. We pause the connection part way through ++ * the handshake by (mis)using the servername_cb. The pause occurs after ++ * session resumption has already occurred, but before any session ++ * tickets have been issued. While paused we run another complete ++ * handshake resuming the same session. ++ */ ++ if (idx == 3) { ++ cbdata.i = i; ++ cbdata.sess = sess; ++ } ++ + /* + * Recreate a bug where dynamically changing the max_early_data value + * can cause sessions in the session cache which cannot be deleted. +@@ -6681,7 +6762,7 @@ int setup_tests(void) + ADD_ALL_TESTS(test_client_cert_cb, 2); + ADD_ALL_TESTS(test_ca_names, 3); + ADD_ALL_TESTS(test_servername, 10); +- ADD_ALL_TESTS(test_multi_resume, 4); ++ ADD_ALL_TESTS(test_multi_resume, 5); + return 1; + } + +-- +2.33.0 + diff --git a/0075-Hardening-around-not_resumable-sessions.patch b/0075-Hardening-around-not_resumable-sessions.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a57d69fbb9f0b4dcffd2463e265d37742ebb683 --- /dev/null +++ b/0075-Hardening-around-not_resumable-sessions.patch @@ -0,0 +1,39 @@ +From 161ea825e861895c27499ae3d8f05cbd15b0926a Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 15 Mar 2024 17:58:42 +0000 +Subject: [PATCH 4/5] Hardening around not_resumable sessions + +Make sure we can't inadvertently use a not_resumable session + +Related to CVE-2024-2511 + +Reviewed-by: Neil Horman +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/24044) + +(cherry picked from commit c342f4b8bd2d0b375b0e22337057c2eab47d9b96) +Signed-off-by: Liu-Ermeng +--- + CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c +index 4e87220..9a5b0b8 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c +@@ -465,6 +465,12 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, + ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); + + if (ret != NULL) { ++ if (ret->not_resumable) { ++ /* If its not resumable then ignore this session */ ++ if (!copy) ++ SSL_SESSION_free(ret); ++ return NULL; ++ } + tsan_counter(&s->session_ctx->stats.sess_cb_hit); + + /* +-- +2.33.0 + diff --git a/0076-Add-a-test-for-session-cache-overflow.patch b/0076-Add-a-test-for-session-cache-overflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..407356c8c3eae665b3e3bd27789c06e4a7ba9d63 --- /dev/null +++ b/0076-Add-a-test-for-session-cache-overflow.patch @@ -0,0 +1,186 @@ +From 472c8dbecb85705f39ad87fa07178c2cbb346ec3 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 15 Jul 2022 13:26:33 +0100 +Subject: [PATCH 5/5] Add a test for session cache overflow + +Test sessions behave as we expect even in the case that an overflow +occurs when adding a new session into the session cache. + +Related to CVE-2024-2511 + +Reviewed-by: Neil Horman +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/24044) + +(cherry picked from commit ddead0935d77ba9b771d632ace61b145d7153f18) +Signed-off-by: Liu-Ermeng +--- + .../OpensslLib/openssl/test/sslapitest.c | 133 +++++++++++++++++- + 1 file changed, 130 insertions(+), 3 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +index 86f746c..74bc0af 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +@@ -6317,6 +6317,128 @@ static int test_ca_names(int tst) + return testresult; + } + ++/* ++ * Test that a session cache overflow works as expected ++ * Test 0: TLSv1.3, timeout on new session later than old session ++ * Test 1: TLSv1.2, timeout on new session later than old session ++ * Test 2: TLSv1.3, timeout on new session earlier than old session ++ * Test 3: TLSv1.2, timeout on new session earlier than old session ++ */ ++#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) ++static int test_session_cache_overflow(int idx) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *serverssl = NULL, *clientssl = NULL; ++ int testresult = 0; ++ SSL_SESSION *sess = NULL; ++ ++#ifdef OPENSSL_NO_TLS1_3 ++ /* If no TLSv1.3 available then do nothing in this case */ ++ if (idx % 2 == 0) ++ TEST_info("No TLSv1.3 available"); ++ return 1; ++#endif ++#ifdef OPENSSL_NO_TLS1_2 ++ /* If no TLSv1.2 available then do nothing in this case */ ++ if (idx % 2 == 1) ++ TEST_info("No TLSv1.2 available"); ++ return 1; ++#endif ++ ++ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), ++ TLS_client_method(), TLS1_VERSION, ++ (idx % 2 == 0) ? TLS1_3_VERSION ++ : TLS1_2_VERSION, ++ &sctx, &cctx, cert, privkey)) ++ || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET))) ++ goto end; ++ ++ SSL_CTX_sess_set_get_cb(sctx, get_session_cb); ++ get_sess_val = NULL; ++ ++ SSL_CTX_sess_set_cache_size(sctx, 1); ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, ++ NULL, NULL))) ++ goto end; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) ++ goto end; ++ ++ if (idx > 1) { ++ sess = SSL_get_session(serverssl); ++ if (!TEST_ptr(sess)) ++ goto end; ++ ++ /* ++ * Cause this session to have a longer timeout than the next session to ++ * be added. ++ */ ++ if (!TEST_true(SSL_SESSION_set_timeout(sess, LONG_MAX / 2))) { ++ sess = NULL; ++ goto end; ++ } ++ sess = NULL; ++ } ++ ++ SSL_shutdown(serverssl); ++ SSL_shutdown(clientssl); ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ serverssl = clientssl = NULL; ++ ++ /* ++ * Session cache size is 1 and we already populated the cache with a session ++ * so the next connection should cause an overflow. ++ */ ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, ++ NULL, NULL))) ++ goto end; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) ++ goto end; ++ ++ /* ++ * The session we just negotiated may have been already removed from the ++ * internal cache - but we will return it anyway from our external cache. ++ */ ++ get_sess_val = SSL_get_session(serverssl); ++ if (!TEST_ptr(get_sess_val)) ++ goto end; ++ sess = SSL_get1_session(clientssl); ++ if (!TEST_ptr(sess)) ++ goto end; ++ ++ SSL_shutdown(serverssl); ++ SSL_shutdown(clientssl); ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ serverssl = clientssl = NULL; ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, ++ NULL, NULL))) ++ goto end; ++ ++ if (!TEST_true(SSL_set_session(clientssl, sess))) ++ goto end; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) ++ goto end; ++ ++ testresult = 1; ++ ++ end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ SSL_SESSION_free(sess); ++ ++ return testresult; ++} ++#endif /* !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */ ++ + /* + * Test 0: Client sets servername and server acknowledges it (TLSv1.2) + * Test 1: Client sets servername and server does not acknowledge it (TLSv1.2) +@@ -6540,14 +6662,16 @@ static int test_multi_resume(int idx) + + #if defined(OPENSSL_NO_TLS1_2) + if (idx == 4) +- return TEST_skip("TLSv1.2 is disabled in this build"); ++ TEST_info("TLSv1.2 is disabled in this build"); ++ return 1; + #else + if (idx == 4) + max_version = TLS1_2_VERSION; + #endif +-#if defined(OSSL_NO_USABLE_TLS1_3) ++#if defined(OPENSSL_NO_TLS1_3) + if (idx != 4) +- return TEST_skip("No usable TLSv1.3 in this build"); ++ TEST_info("No usable TLSv1.3 in this build"); ++ return 1; + #endif + + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), +@@ -6752,6 +6876,9 @@ int setup_tests(void) + ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test)); + #if !defined(OPENSSL_NO_SRP) && !defined(OPENSSL_NO_TLS1_2) + ADD_ALL_TESTS(test_srp, 6); ++#endif ++#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) ++ ADD_ALL_TESTS(test_session_cache_overflow, 4); + #endif + ADD_ALL_TESTS(test_info_callback, 6); + ADD_ALL_TESTS(test_ssl_pending, 2); +-- +2.33.0 + diff --git a/0077-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch b/0077-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch new file mode 100644 index 0000000000000000000000000000000000000000..ecc18dea20d84cec6a4b3ff1fa2e1326f3f5f0be --- /dev/null +++ b/0077-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch @@ -0,0 +1,47 @@ +From 413fa91e9a7d28732c55589a7705ae68ec824494 Mon Sep 17 00:00:00 2001 +From: ShenYage +Date: Tue, 11 Jun 2024 14:57:58 +0800 +Subject: [PATCH] MdeModulePkg: Potential UINT32 overflow in S3 ResumeCount + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4677 + +Attacker able to modify physical memory and ResumeCount. +System will crash/DoS when ResumeCount reaches its MAX_UINT32. + +Cc: Zhiguang Liu +Cc: Dandan Bi +Cc: Liming Gao + +Signed-off-by: Pakkirisamy ShanmugavelX +Reviewed-by: Liming Gao +--- + .../FirmwarePerformancePei.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c +index 2f2b2a8..2ba9215 100644 +--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c ++++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c +@@ -112,11 +112,15 @@ FpdtStatusCodeListenerPei ( + // + S3ResumeTotal = MultU64x32 (AcpiS3ResumeRecord->AverageResume, AcpiS3ResumeRecord->ResumeCount); + AcpiS3ResumeRecord->ResumeCount++; +- AcpiS3ResumeRecord->AverageResume = DivU64x32 (S3ResumeTotal + AcpiS3ResumeRecord->FullResume, AcpiS3ResumeRecord->ResumeCount); ++ if (AcpiS3ResumeRecord->ResumeCount > 0) { ++ AcpiS3ResumeRecord->AverageResume = DivU64x32 (S3ResumeTotal + AcpiS3ResumeRecord->FullResume, AcpiS3ResumeRecord->ResumeCount); ++ DEBUG ((EFI_D_INFO, "\nFPDT: S3 Resume Performance - AverageResume = 0x%x\n", AcpiS3ResumeRecord->AverageResume)); ++ } else { ++ DEBUG ((EFI_D_ERROR, "\nFPDT: S3 ResumeCount reaches the MAX_UINT32 value. S3 ResumeCount record reset to Zero.")); ++ } + +- DEBUG ((EFI_D_INFO, "FPDT: S3 Resume Performance - ResumeCount = %d\n", AcpiS3ResumeRecord->ResumeCount)); +- DEBUG ((EFI_D_INFO, "FPDT: S3 Resume Performance - FullResume = %ld\n", AcpiS3ResumeRecord->FullResume)); +- DEBUG ((EFI_D_INFO, "FPDT: S3 Resume Performance - AverageResume = %ld\n", AcpiS3ResumeRecord->AverageResume)); ++ DEBUG ((EFI_D_INFO, "FPDT: S3 Resume Performance - ResumeCount = 0x%x\n", AcpiS3ResumeRecord->ResumeCount)); ++ DEBUG ((EFI_D_INFO, "FPDT: S3 Resume Performance - FullResume = 0x%x\n", AcpiS3ResumeRecord->FullResume)); + + // + // Update S3 Suspend Performance Record. +-- +2.33.0 + diff --git a/0078-Fix-SSL_select_next_proto-and-add-ALPN-validation-in.patch b/0078-Fix-SSL_select_next_proto-and-add-ALPN-validation-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..d7b3049c5ace9ff663cc25d19bb7470b1969f034 --- /dev/null +++ b/0078-Fix-SSL_select_next_proto-and-add-ALPN-validation-in.patch @@ -0,0 +1,168 @@ +From 85365ebf0d57f82fbaf6b04da477dcba4e82e3a4 Mon Sep 17 00:00:00 2001 +From: xuhuiyue +Date: Fri, 28 Jun 2024 17:31:29 +0800 +Subject: [PATCH 1/2] Fix SSL_select_next_proto and add ALPN validation in the + client + +Fix CVE-2024-5535. + +Signed-off-by: xuhuiyue +--- + .../Library/OpensslLib/openssl/ssl/ssl_lib.c | 63 ++++++++++++------- + .../openssl/ssl/statem/extensions_clnt.c | 27 +++++++- + .../openssl/ssl/statem/extensions_srvr.c | 3 +- + 3 files changed, 68 insertions(+), 25 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +index ae33d18..cc3f588 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +@@ -2731,37 +2731,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + unsigned int server_len, + const unsigned char *client, unsigned int client_len) + { +- unsigned int i, j; +- const unsigned char *result; +- int status = OPENSSL_NPN_UNSUPPORTED; ++ PACKET cpkt, csubpkt, spkt, ssubpkt; ++ ++ if (!PACKET_buf_init(&cpkt, client, client_len) ++ || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt) ++ || PACKET_remaining(&csubpkt) == 0) { ++ *out = NULL; ++ *outlen = 0; ++ return OPENSSL_NPN_NO_OVERLAP; ++ } ++ ++ /* ++ * Set the default opportunistic protocol. Will be overwritten if we find ++ * a match. ++ */ ++ *out = (unsigned char *)PACKET_data(&csubpkt); ++ *outlen = (unsigned char)PACKET_remaining(&csubpkt); + + /* + * For each protocol in server preference order, see if we support it. + */ +- for (i = 0; i < server_len;) { +- for (j = 0; j < client_len;) { +- if (server[i] == client[j] && +- memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { +- /* We found a match */ +- result = &server[i]; +- status = OPENSSL_NPN_NEGOTIATED; +- goto found; ++ if (PACKET_buf_init(&spkt, server, server_len)) { ++ while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) { ++ if (PACKET_remaining(&ssubpkt) == 0) ++ continue; /* Invalid - ignore it */ ++ if (PACKET_buf_init(&cpkt, client, client_len)) { ++ while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) { ++ if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt), ++ PACKET_remaining(&ssubpkt))) { ++ /* We found a match */ ++ *out = (unsigned char *)PACKET_data(&ssubpkt); ++ *outlen = (unsigned char)PACKET_remaining(&ssubpkt); ++ return OPENSSL_NPN_NEGOTIATED; ++ } ++ } ++ /* Ignore spurious trailing bytes in the client list */ ++ } else { ++ /* This should never happen */ ++ return OPENSSL_NPN_NO_OVERLAP; + } +- j += client[j]; +- j++; + } +- i += server[i]; +- i++; ++ /* Ignore spurious trailing bytes in the server list */ + } + +- /* There's no overlap between our protocols and the server's list. */ +- result = client; +- status = OPENSSL_NPN_NO_OVERLAP; +- +- found: +- *out = (unsigned char *)result + 1; +- *outlen = result[0]; +- return status; ++ /* ++ * There's no overlap between our protocols and the server's list. We use ++ * the default opportunistic protocol selected earlier ++ */ ++ return OPENSSL_NPN_NO_OVERLAP; + } + + #ifndef OPENSSL_NO_NEXTPROTONEG +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_clnt.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_clnt.c +index bcce0f1..a307294 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_clnt.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_clnt.c +@@ -1579,7 +1579,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + PACKET_data(pkt), + PACKET_remaining(pkt), + s->ctx->ext.npn_select_cb_arg) != +- SSL_TLSEXT_ERR_OK) { ++ SSL_TLSEXT_ERR_OK ++ || selected_len == 0) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_STOC_NPN, + SSL_R_BAD_EXTENSION); + return 0; +@@ -1609,6 +1610,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + size_t chainidx) + { + size_t len; ++ PACKET confpkt, protpkt; ++ int valid = 0; + + /* We must have requested it. */ + if (!s->s3->alpn_sent) { +@@ -1629,6 +1632,28 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + SSL_R_BAD_EXTENSION); + return 0; + } ++ ++ /* It must be a protocol that we sent */ ++ if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) { ++ if (PACKET_remaining(&protpkt) != len) ++ continue; ++ if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) { ++ /* Valid protocol found */ ++ valid = 1; ++ break; ++ } ++ } ++ ++ if (!valid) { ++ /* The protocol sent from the server does not match one we advertised */ ++ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, SSL_R_BAD_EXTENSION); ++ return 0; ++ } ++ + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = OPENSSL_malloc(len); + if (s->s3->alpn_selected == NULL) { +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_srvr.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_srvr.c +index 3b07c6b..0c9b839 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_srvr.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/extensions_srvr.c +@@ -1559,9 +1559,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, + return EXT_RETURN_FAIL; + } + s->s3->npn_seen = 1; ++ return EXT_RETURN_SENT; + } + +- return EXT_RETURN_SENT; ++ return EXT_RETURN_NOT_SENT; + } + #endif + +-- +2.33.0 + diff --git a/0079-Add-a-test-for-ALPN-and-NPN.patch b/0079-Add-a-test-for-ALPN-and-NPN.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b7efcddc972cfb31cde6ec1e127d16b5534c475 --- /dev/null +++ b/0079-Add-a-test-for-ALPN-and-NPN.patch @@ -0,0 +1,1786 @@ +From 4467abc6d77dc859e96243a2022c2d8549523685 Mon Sep 17 00:00:00 2001 +From: xuhuiyue +Date: Fri, 28 Jun 2024 18:56:36 +0800 +Subject: [PATCH 2/2] Add a test for ALPN and NPN + +1. Add a test for SSL_select_next_proto +2. Add a test for empty ALPV/NPN message + +Signed-off-by: xuhuiyue +--- + .../doc/man3/SSL_CTX_set_alpn_select_cb.pod | 26 +- + .../openssl/test/handshake_helper.c | 6 + + .../openssl/test/recipes/70-test_npn.t | 73 +++ + .../openssl/test/ssl-tests/08-npn.conf | 553 ++++++++++-------- + .../openssl/test/ssl-tests/08-npn.conf.in | 35 ++ + .../openssl/test/ssl-tests/09-alpn.conf | 66 ++- + .../openssl/test/ssl-tests/09-alpn.conf.in | 33 ++ + .../OpensslLib/openssl/test/sslapitest.c | 366 ++++++++++++ + .../openssl/util/perl/TLSProxy/Message.pm | 9 + + .../openssl/util/perl/TLSProxy/NextProto.pm | 54 ++ + .../openssl/util/perl/TLSProxy/Proxy.pm | 1 + + 11 files changed, 970 insertions(+), 252 deletions(-) + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_npn.t + create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/NextProto.pm + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/man3/SSL_CTX_set_alpn_select_cb.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/man3/SSL_CTX_set_alpn_select_cb.pod +index 56c8609..37d9fe4 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/doc/man3/SSL_CTX_set_alpn_select_cb.pod ++++ b/CryptoPkg/Library/OpensslLib/openssl/doc/man3/SSL_CTX_set_alpn_select_cb.pod +@@ -52,7 +52,8 @@ SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated + SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to + set the list of protocols available to be negotiated. The B must be in + protocol-list format, described below. The length of B is specified in +-B. ++B. Setting B to 0 clears any existing list of ALPN ++protocols and no ALPN extension will be sent to the server. + + SSL_CTX_set_alpn_select_cb() sets the application callback B used by a + server to select which protocol to use for the incoming connection. When B +@@ -73,9 +74,16 @@ B and B, B must be in the protocol-list format + described below. The first item in the B, B list that + matches an item in the B, B list is selected, and returned + in B, B. The B value will point into either B or +-B, so it should be copied immediately. If no match is found, the first +-item in B, B is returned in B, B. This +-function can also be used in the NPN callback. ++B, so it should be copied immediately. The client list must include at ++least one valid (nonempty) protocol entry in the list. ++ ++The SSL_select_next_proto() helper function can be useful from either the ALPN ++callback or the NPN callback (described below). If no match is found, the first ++item in B, B is returned in B, B and ++B is returned. This can be useful when implementating ++the NPN callback. In the ALPN case, the value returned in B and B ++must be ignored if B has been returned from ++SSL_select_next_proto(). + + SSL_CTX_set_next_proto_select_cb() sets a callback B that is called when a + client needs to select a protocol from the server's provided list, and a +@@ -85,9 +93,10 @@ must be set to point to the selected protocol (which may be within B). + The length of the protocol name must be written into B. The + server's advertised protocols are provided in B and B. The + callback can assume that B is syntactically valid. The client must +-select a protocol. It is fatal to the connection if this callback returns +-a value other than B. The B parameter is the pointer +-set via SSL_CTX_set_next_proto_select_cb(). ++select a protocol (although it may be an empty, zero length protocol). It is ++fatal to the connection if this callback returns a value other than ++B or if the zero length protocol is selected. The B ++parameter is the pointer set via SSL_CTX_set_next_proto_select_cb(). + + SSL_CTX_set_next_protos_advertised_cb() sets a callback B that is called + when a TLS server needs a list of supported protocols for Next Protocol +@@ -149,7 +158,8 @@ A match was found and is returned in B, B. + =item OPENSSL_NPN_NO_OVERLAP + + No match was found. The first item in B, B is returned in +-B, B. ++B, B (or B and 0 in the case where the first entry in ++B is invalid). + + =back + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.c b/CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.c +index 1742004..429f6f5 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.c +@@ -341,6 +341,12 @@ static int parse_protos(const char *protos, unsigned char **out, size_t *outlen) + + len = strlen(protos); + ++ if (len == 0) { ++ *out = NULL; ++ *outlen = 0; ++ return 1; ++ } ++ + /* Should never have reuse. */ + if (!TEST_ptr_null(*out) + /* Test values are small, so we omit length limit checks. */ +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_npn.t b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_npn.t +new file mode 100644 +index 0000000..f82e71a +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_npn.t +@@ -0,0 +1,73 @@ ++#! /usr/bin/env perl ++# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++use strict; ++use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file/; ++use OpenSSL::Test::Utils; ++ ++use TLSProxy::Proxy; ++ ++my $test_name = "test_npn"; ++setup($test_name); ++ ++plan skip_all => "TLSProxy isn't usable on $^O" ++ if $^O =~ /^(VMS)$/; ++ ++plan skip_all => "$test_name needs the dynamic engine feature enabled" ++ if disabled("engine") || disabled("dynamic-engine"); ++ ++plan skip_all => "$test_name needs the sock feature enabled" ++ if disabled("sock"); ++ ++plan skip_all => "$test_name needs NPN enabled" ++ if disabled("nextprotoneg"); ++ ++plan skip_all => "$test_name needs TLSv1.2 enabled" ++ if disabled("tls1_2"); ++ ++my $proxy = TLSProxy::Proxy->new( ++ undef, ++ cmdstr(app(["openssl"]), display => 1), ++ srctop_file("apps", "server.pem"), ++ (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) ++); ++ ++$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; ++plan tests => 1; ++ ++my $npnseen = 0; ++ ++# Test 1: Check sending an empty NextProto message from the client works. This is ++# valid as per the spec, but OpenSSL does not allow you to send it. ++# Therefore we must be prepared to receive such a message but we cannot ++# generate it except via TLSProxy ++$proxy->clear(); ++$proxy->filter(\&npn_filter); ++$proxy->clientflags("-nextprotoneg foo -no_tls1_3"); ++$proxy->serverflags("-nextprotoneg foo"); ++$proxy->start(); ++ok($npnseen && TLSProxy::Message->success(), "Empty NPN message"); ++ ++sub npn_filter ++{ ++ my $proxy = shift; ++ my $message; ++ ++ # The NextProto message always appears in flight 2 ++ return if $proxy->flight != 2; ++ ++ foreach my $message (@{$proxy->message_list}) { ++ if ($message->mt == TLSProxy::Message::MT_NEXT_PROTO) { ++ # Our TLSproxy NextProto message support doesn't support parsing of ++ # the message. If we repack it just creates an empty NextProto ++ # message - which is exactly the scenario we want to test here. ++ $message->repack(); ++ $npnseen = 1; ++ } ++ } ++} +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf +index f38b3f6..1931d02 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf +@@ -1,6 +1,6 @@ + # Generated with generate_ssl_tests.pl + +-num_tests = 20 ++num_tests = 22 + + test-0 = 0-npn-simple + test-1 = 1-npn-client-finds-match +@@ -8,20 +8,22 @@ test-2 = 2-npn-client-honours-server-pref + test-3 = 3-npn-client-first-pref-on-mismatch + test-4 = 4-npn-no-server-support + test-5 = 5-npn-no-client-support +-test-6 = 6-npn-with-sni-no-context-switch +-test-7 = 7-npn-with-sni-context-switch +-test-8 = 8-npn-selected-sni-server-supports-npn +-test-9 = 9-npn-selected-sni-server-does-not-support-npn +-test-10 = 10-alpn-preferred-over-npn +-test-11 = 11-sni-npn-preferred-over-alpn +-test-12 = 12-npn-simple-resumption +-test-13 = 13-npn-server-switch-resumption +-test-14 = 14-npn-client-switch-resumption +-test-15 = 15-npn-client-first-pref-on-mismatch-resumption +-test-16 = 16-npn-no-server-support-resumption +-test-17 = 17-npn-no-client-support-resumption +-test-18 = 18-alpn-preferred-over-npn-resumption +-test-19 = 19-npn-used-if-alpn-not-supported-resumption ++test-6 = 6-npn-empty-client-list ++test-7 = 7-npn-empty-server-list ++test-8 = 8-npn-with-sni-no-context-switch ++test-9 = 9-npn-with-sni-context-switch ++test-10 = 10-npn-selected-sni-server-supports-npn ++test-11 = 11-npn-selected-sni-server-does-not-support-npn ++test-12 = 12-alpn-preferred-over-npn ++test-13 = 13-sni-npn-preferred-over-alpn ++test-14 = 14-npn-simple-resumption ++test-15 = 15-npn-server-switch-resumption ++test-16 = 16-npn-client-switch-resumption ++test-17 = 17-npn-client-first-pref-on-mismatch-resumption ++test-18 = 18-npn-no-server-support-resumption ++test-19 = 19-npn-no-client-support-resumption ++test-20 = 20-alpn-preferred-over-npn-resumption ++test-21 = 21-npn-used-if-alpn-not-supported-resumption + # =========================================================== + + [0-npn-simple] +@@ -206,253 +208,318 @@ NPNProtocols = foo + + # =========================================================== + +-[6-npn-with-sni-no-context-switch] +-ssl_conf = 6-npn-with-sni-no-context-switch-ssl ++[6-npn-empty-client-list] ++ssl_conf = 6-npn-empty-client-list-ssl + +-[6-npn-with-sni-no-context-switch-ssl] +-server = 6-npn-with-sni-no-context-switch-server +-client = 6-npn-with-sni-no-context-switch-client +-server2 = 6-npn-with-sni-no-context-switch-server2 ++[6-npn-empty-client-list-ssl] ++server = 6-npn-empty-client-list-server ++client = 6-npn-empty-client-list-client + +-[6-npn-with-sni-no-context-switch-server] ++[6-npn-empty-client-list-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[6-npn-with-sni-no-context-switch-server2] ++[6-npn-empty-client-list-client] ++CipherString = DEFAULT ++MaxProtocol = TLSv1.2 ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-6] ++ExpectedClientAlert = HandshakeFailure ++ExpectedResult = ClientFail ++server = 6-npn-empty-client-list-server-extra ++client = 6-npn-empty-client-list-client-extra ++ ++[6-npn-empty-client-list-server-extra] ++NPNProtocols = foo ++ ++[6-npn-empty-client-list-client-extra] ++NPNProtocols = ++ ++ ++# =========================================================== ++ ++[7-npn-empty-server-list] ++ssl_conf = 7-npn-empty-server-list-ssl ++ ++[7-npn-empty-server-list-ssl] ++server = 7-npn-empty-server-list-server ++client = 7-npn-empty-server-list-client ++ ++[7-npn-empty-server-list-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[6-npn-with-sni-no-context-switch-client] ++[7-npn-empty-server-list-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-6] ++[test-7] ++ExpectedNPNProtocol = foo ++server = 7-npn-empty-server-list-server-extra ++client = 7-npn-empty-server-list-client-extra ++ ++[7-npn-empty-server-list-server-extra] ++NPNProtocols = ++ ++[7-npn-empty-server-list-client-extra] ++NPNProtocols = foo ++ ++ ++# =========================================================== ++ ++[8-npn-with-sni-no-context-switch] ++ssl_conf = 8-npn-with-sni-no-context-switch-ssl ++ ++[8-npn-with-sni-no-context-switch-ssl] ++server = 8-npn-with-sni-no-context-switch-server ++client = 8-npn-with-sni-no-context-switch-client ++server2 = 8-npn-with-sni-no-context-switch-server2 ++ ++[8-npn-with-sni-no-context-switch-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[8-npn-with-sni-no-context-switch-server2] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[8-npn-with-sni-no-context-switch-client] ++CipherString = DEFAULT ++MaxProtocol = TLSv1.2 ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-8] + ExpectedNPNProtocol = foo + ExpectedServerName = server1 +-server = 6-npn-with-sni-no-context-switch-server-extra +-server2 = 6-npn-with-sni-no-context-switch-server2-extra +-client = 6-npn-with-sni-no-context-switch-client-extra ++server = 8-npn-with-sni-no-context-switch-server-extra ++server2 = 8-npn-with-sni-no-context-switch-server2-extra ++client = 8-npn-with-sni-no-context-switch-client-extra + +-[6-npn-with-sni-no-context-switch-server-extra] ++[8-npn-with-sni-no-context-switch-server-extra] + NPNProtocols = foo + ServerNameCallback = IgnoreMismatch + +-[6-npn-with-sni-no-context-switch-server2-extra] ++[8-npn-with-sni-no-context-switch-server2-extra] + NPNProtocols = bar + +-[6-npn-with-sni-no-context-switch-client-extra] ++[8-npn-with-sni-no-context-switch-client-extra] + NPNProtocols = foo,bar + ServerName = server1 + + + # =========================================================== + +-[7-npn-with-sni-context-switch] +-ssl_conf = 7-npn-with-sni-context-switch-ssl ++[9-npn-with-sni-context-switch] ++ssl_conf = 9-npn-with-sni-context-switch-ssl + +-[7-npn-with-sni-context-switch-ssl] +-server = 7-npn-with-sni-context-switch-server +-client = 7-npn-with-sni-context-switch-client +-server2 = 7-npn-with-sni-context-switch-server2 ++[9-npn-with-sni-context-switch-ssl] ++server = 9-npn-with-sni-context-switch-server ++client = 9-npn-with-sni-context-switch-client ++server2 = 9-npn-with-sni-context-switch-server2 + +-[7-npn-with-sni-context-switch-server] ++[9-npn-with-sni-context-switch-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[7-npn-with-sni-context-switch-server2] ++[9-npn-with-sni-context-switch-server2] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[7-npn-with-sni-context-switch-client] ++[9-npn-with-sni-context-switch-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-7] ++[test-9] + ExpectedNPNProtocol = bar + ExpectedServerName = server2 +-server = 7-npn-with-sni-context-switch-server-extra +-server2 = 7-npn-with-sni-context-switch-server2-extra +-client = 7-npn-with-sni-context-switch-client-extra ++server = 9-npn-with-sni-context-switch-server-extra ++server2 = 9-npn-with-sni-context-switch-server2-extra ++client = 9-npn-with-sni-context-switch-client-extra + +-[7-npn-with-sni-context-switch-server-extra] ++[9-npn-with-sni-context-switch-server-extra] + NPNProtocols = foo + ServerNameCallback = IgnoreMismatch + +-[7-npn-with-sni-context-switch-server2-extra] ++[9-npn-with-sni-context-switch-server2-extra] + NPNProtocols = bar + +-[7-npn-with-sni-context-switch-client-extra] ++[9-npn-with-sni-context-switch-client-extra] + NPNProtocols = foo,bar + ServerName = server2 + + + # =========================================================== + +-[8-npn-selected-sni-server-supports-npn] +-ssl_conf = 8-npn-selected-sni-server-supports-npn-ssl ++[10-npn-selected-sni-server-supports-npn] ++ssl_conf = 10-npn-selected-sni-server-supports-npn-ssl + +-[8-npn-selected-sni-server-supports-npn-ssl] +-server = 8-npn-selected-sni-server-supports-npn-server +-client = 8-npn-selected-sni-server-supports-npn-client +-server2 = 8-npn-selected-sni-server-supports-npn-server2 ++[10-npn-selected-sni-server-supports-npn-ssl] ++server = 10-npn-selected-sni-server-supports-npn-server ++client = 10-npn-selected-sni-server-supports-npn-client ++server2 = 10-npn-selected-sni-server-supports-npn-server2 + +-[8-npn-selected-sni-server-supports-npn-server] ++[10-npn-selected-sni-server-supports-npn-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[8-npn-selected-sni-server-supports-npn-server2] ++[10-npn-selected-sni-server-supports-npn-server2] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[8-npn-selected-sni-server-supports-npn-client] ++[10-npn-selected-sni-server-supports-npn-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-8] ++[test-10] + ExpectedNPNProtocol = bar + ExpectedServerName = server2 +-server = 8-npn-selected-sni-server-supports-npn-server-extra +-server2 = 8-npn-selected-sni-server-supports-npn-server2-extra +-client = 8-npn-selected-sni-server-supports-npn-client-extra ++server = 10-npn-selected-sni-server-supports-npn-server-extra ++server2 = 10-npn-selected-sni-server-supports-npn-server2-extra ++client = 10-npn-selected-sni-server-supports-npn-client-extra + +-[8-npn-selected-sni-server-supports-npn-server-extra] ++[10-npn-selected-sni-server-supports-npn-server-extra] + ServerNameCallback = IgnoreMismatch + +-[8-npn-selected-sni-server-supports-npn-server2-extra] ++[10-npn-selected-sni-server-supports-npn-server2-extra] + NPNProtocols = bar + +-[8-npn-selected-sni-server-supports-npn-client-extra] ++[10-npn-selected-sni-server-supports-npn-client-extra] + NPNProtocols = foo,bar + ServerName = server2 + + + # =========================================================== + +-[9-npn-selected-sni-server-does-not-support-npn] +-ssl_conf = 9-npn-selected-sni-server-does-not-support-npn-ssl ++[11-npn-selected-sni-server-does-not-support-npn] ++ssl_conf = 11-npn-selected-sni-server-does-not-support-npn-ssl + +-[9-npn-selected-sni-server-does-not-support-npn-ssl] +-server = 9-npn-selected-sni-server-does-not-support-npn-server +-client = 9-npn-selected-sni-server-does-not-support-npn-client +-server2 = 9-npn-selected-sni-server-does-not-support-npn-server2 ++[11-npn-selected-sni-server-does-not-support-npn-ssl] ++server = 11-npn-selected-sni-server-does-not-support-npn-server ++client = 11-npn-selected-sni-server-does-not-support-npn-client ++server2 = 11-npn-selected-sni-server-does-not-support-npn-server2 + +-[9-npn-selected-sni-server-does-not-support-npn-server] ++[11-npn-selected-sni-server-does-not-support-npn-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[9-npn-selected-sni-server-does-not-support-npn-server2] ++[11-npn-selected-sni-server-does-not-support-npn-server2] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[9-npn-selected-sni-server-does-not-support-npn-client] ++[11-npn-selected-sni-server-does-not-support-npn-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-9] ++[test-11] + ExpectedServerName = server2 +-server = 9-npn-selected-sni-server-does-not-support-npn-server-extra +-client = 9-npn-selected-sni-server-does-not-support-npn-client-extra ++server = 11-npn-selected-sni-server-does-not-support-npn-server-extra ++client = 11-npn-selected-sni-server-does-not-support-npn-client-extra + +-[9-npn-selected-sni-server-does-not-support-npn-server-extra] ++[11-npn-selected-sni-server-does-not-support-npn-server-extra] + NPNProtocols = bar + ServerNameCallback = IgnoreMismatch + +-[9-npn-selected-sni-server-does-not-support-npn-client-extra] ++[11-npn-selected-sni-server-does-not-support-npn-client-extra] + NPNProtocols = foo,bar + ServerName = server2 + + + # =========================================================== + +-[10-alpn-preferred-over-npn] +-ssl_conf = 10-alpn-preferred-over-npn-ssl ++[12-alpn-preferred-over-npn] ++ssl_conf = 12-alpn-preferred-over-npn-ssl + +-[10-alpn-preferred-over-npn-ssl] +-server = 10-alpn-preferred-over-npn-server +-client = 10-alpn-preferred-over-npn-client ++[12-alpn-preferred-over-npn-ssl] ++server = 12-alpn-preferred-over-npn-server ++client = 12-alpn-preferred-over-npn-client + +-[10-alpn-preferred-over-npn-server] ++[12-alpn-preferred-over-npn-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[10-alpn-preferred-over-npn-client] ++[12-alpn-preferred-over-npn-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-10] ++[test-12] + ExpectedALPNProtocol = foo +-server = 10-alpn-preferred-over-npn-server-extra +-client = 10-alpn-preferred-over-npn-client-extra ++server = 12-alpn-preferred-over-npn-server-extra ++client = 12-alpn-preferred-over-npn-client-extra + +-[10-alpn-preferred-over-npn-server-extra] ++[12-alpn-preferred-over-npn-server-extra] + ALPNProtocols = foo + NPNProtocols = bar + +-[10-alpn-preferred-over-npn-client-extra] ++[12-alpn-preferred-over-npn-client-extra] + ALPNProtocols = foo + NPNProtocols = bar + + + # =========================================================== + +-[11-sni-npn-preferred-over-alpn] +-ssl_conf = 11-sni-npn-preferred-over-alpn-ssl ++[13-sni-npn-preferred-over-alpn] ++ssl_conf = 13-sni-npn-preferred-over-alpn-ssl + +-[11-sni-npn-preferred-over-alpn-ssl] +-server = 11-sni-npn-preferred-over-alpn-server +-client = 11-sni-npn-preferred-over-alpn-client +-server2 = 11-sni-npn-preferred-over-alpn-server2 ++[13-sni-npn-preferred-over-alpn-ssl] ++server = 13-sni-npn-preferred-over-alpn-server ++client = 13-sni-npn-preferred-over-alpn-client ++server2 = 13-sni-npn-preferred-over-alpn-server2 + +-[11-sni-npn-preferred-over-alpn-server] ++[13-sni-npn-preferred-over-alpn-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[11-sni-npn-preferred-over-alpn-server2] ++[13-sni-npn-preferred-over-alpn-server2] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[11-sni-npn-preferred-over-alpn-client] ++[13-sni-npn-preferred-over-alpn-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-11] ++[test-13] + ExpectedNPNProtocol = bar + ExpectedServerName = server2 +-server = 11-sni-npn-preferred-over-alpn-server-extra +-server2 = 11-sni-npn-preferred-over-alpn-server2-extra +-client = 11-sni-npn-preferred-over-alpn-client-extra ++server = 13-sni-npn-preferred-over-alpn-server-extra ++server2 = 13-sni-npn-preferred-over-alpn-server2-extra ++client = 13-sni-npn-preferred-over-alpn-client-extra + +-[11-sni-npn-preferred-over-alpn-server-extra] ++[13-sni-npn-preferred-over-alpn-server-extra] + ALPNProtocols = foo + ServerNameCallback = IgnoreMismatch + +-[11-sni-npn-preferred-over-alpn-server2-extra] ++[13-sni-npn-preferred-over-alpn-server2-extra] + NPNProtocols = bar + +-[11-sni-npn-preferred-over-alpn-client-extra] ++[13-sni-npn-preferred-over-alpn-client-extra] + ALPNProtocols = foo + NPNProtocols = bar + ServerName = server2 +@@ -460,356 +527,356 @@ ServerName = server2 + + # =========================================================== + +-[12-npn-simple-resumption] +-ssl_conf = 12-npn-simple-resumption-ssl ++[14-npn-simple-resumption] ++ssl_conf = 14-npn-simple-resumption-ssl + +-[12-npn-simple-resumption-ssl] +-server = 12-npn-simple-resumption-server +-client = 12-npn-simple-resumption-client +-resume-server = 12-npn-simple-resumption-server +-resume-client = 12-npn-simple-resumption-client ++[14-npn-simple-resumption-ssl] ++server = 14-npn-simple-resumption-server ++client = 14-npn-simple-resumption-client ++resume-server = 14-npn-simple-resumption-server ++resume-client = 14-npn-simple-resumption-client + +-[12-npn-simple-resumption-server] ++[14-npn-simple-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[12-npn-simple-resumption-client] ++[14-npn-simple-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-12] ++[test-14] + ExpectedNPNProtocol = foo + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 12-npn-simple-resumption-server-extra +-resume-server = 12-npn-simple-resumption-server-extra +-client = 12-npn-simple-resumption-client-extra +-resume-client = 12-npn-simple-resumption-client-extra ++server = 14-npn-simple-resumption-server-extra ++resume-server = 14-npn-simple-resumption-server-extra ++client = 14-npn-simple-resumption-client-extra ++resume-client = 14-npn-simple-resumption-client-extra + +-[12-npn-simple-resumption-server-extra] ++[14-npn-simple-resumption-server-extra] + NPNProtocols = foo + +-[12-npn-simple-resumption-client-extra] ++[14-npn-simple-resumption-client-extra] + NPNProtocols = foo + + + # =========================================================== + +-[13-npn-server-switch-resumption] +-ssl_conf = 13-npn-server-switch-resumption-ssl ++[15-npn-server-switch-resumption] ++ssl_conf = 15-npn-server-switch-resumption-ssl + +-[13-npn-server-switch-resumption-ssl] +-server = 13-npn-server-switch-resumption-server +-client = 13-npn-server-switch-resumption-client +-resume-server = 13-npn-server-switch-resumption-resume-server +-resume-client = 13-npn-server-switch-resumption-client ++[15-npn-server-switch-resumption-ssl] ++server = 15-npn-server-switch-resumption-server ++client = 15-npn-server-switch-resumption-client ++resume-server = 15-npn-server-switch-resumption-resume-server ++resume-client = 15-npn-server-switch-resumption-client + +-[13-npn-server-switch-resumption-server] ++[15-npn-server-switch-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[13-npn-server-switch-resumption-resume-server] ++[15-npn-server-switch-resumption-resume-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[13-npn-server-switch-resumption-client] ++[15-npn-server-switch-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-13] ++[test-15] + ExpectedNPNProtocol = baz + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 13-npn-server-switch-resumption-server-extra +-resume-server = 13-npn-server-switch-resumption-resume-server-extra +-client = 13-npn-server-switch-resumption-client-extra +-resume-client = 13-npn-server-switch-resumption-client-extra ++server = 15-npn-server-switch-resumption-server-extra ++resume-server = 15-npn-server-switch-resumption-resume-server-extra ++client = 15-npn-server-switch-resumption-client-extra ++resume-client = 15-npn-server-switch-resumption-client-extra + +-[13-npn-server-switch-resumption-server-extra] ++[15-npn-server-switch-resumption-server-extra] + NPNProtocols = bar,foo + +-[13-npn-server-switch-resumption-resume-server-extra] ++[15-npn-server-switch-resumption-resume-server-extra] + NPNProtocols = baz,foo + +-[13-npn-server-switch-resumption-client-extra] ++[15-npn-server-switch-resumption-client-extra] + NPNProtocols = foo,bar,baz + + + # =========================================================== + +-[14-npn-client-switch-resumption] +-ssl_conf = 14-npn-client-switch-resumption-ssl ++[16-npn-client-switch-resumption] ++ssl_conf = 16-npn-client-switch-resumption-ssl + +-[14-npn-client-switch-resumption-ssl] +-server = 14-npn-client-switch-resumption-server +-client = 14-npn-client-switch-resumption-client +-resume-server = 14-npn-client-switch-resumption-server +-resume-client = 14-npn-client-switch-resumption-resume-client ++[16-npn-client-switch-resumption-ssl] ++server = 16-npn-client-switch-resumption-server ++client = 16-npn-client-switch-resumption-client ++resume-server = 16-npn-client-switch-resumption-server ++resume-client = 16-npn-client-switch-resumption-resume-client + +-[14-npn-client-switch-resumption-server] ++[16-npn-client-switch-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[14-npn-client-switch-resumption-client] ++[16-npn-client-switch-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[14-npn-client-switch-resumption-resume-client] ++[16-npn-client-switch-resumption-resume-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-14] ++[test-16] + ExpectedNPNProtocol = bar + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 14-npn-client-switch-resumption-server-extra +-resume-server = 14-npn-client-switch-resumption-server-extra +-client = 14-npn-client-switch-resumption-client-extra +-resume-client = 14-npn-client-switch-resumption-resume-client-extra ++server = 16-npn-client-switch-resumption-server-extra ++resume-server = 16-npn-client-switch-resumption-server-extra ++client = 16-npn-client-switch-resumption-client-extra ++resume-client = 16-npn-client-switch-resumption-resume-client-extra + +-[14-npn-client-switch-resumption-server-extra] ++[16-npn-client-switch-resumption-server-extra] + NPNProtocols = foo,bar,baz + +-[14-npn-client-switch-resumption-client-extra] ++[16-npn-client-switch-resumption-client-extra] + NPNProtocols = foo,baz + +-[14-npn-client-switch-resumption-resume-client-extra] ++[16-npn-client-switch-resumption-resume-client-extra] + NPNProtocols = bar,baz + + + # =========================================================== + +-[15-npn-client-first-pref-on-mismatch-resumption] +-ssl_conf = 15-npn-client-first-pref-on-mismatch-resumption-ssl ++[17-npn-client-first-pref-on-mismatch-resumption] ++ssl_conf = 17-npn-client-first-pref-on-mismatch-resumption-ssl + +-[15-npn-client-first-pref-on-mismatch-resumption-ssl] +-server = 15-npn-client-first-pref-on-mismatch-resumption-server +-client = 15-npn-client-first-pref-on-mismatch-resumption-client +-resume-server = 15-npn-client-first-pref-on-mismatch-resumption-resume-server +-resume-client = 15-npn-client-first-pref-on-mismatch-resumption-client ++[17-npn-client-first-pref-on-mismatch-resumption-ssl] ++server = 17-npn-client-first-pref-on-mismatch-resumption-server ++client = 17-npn-client-first-pref-on-mismatch-resumption-client ++resume-server = 17-npn-client-first-pref-on-mismatch-resumption-resume-server ++resume-client = 17-npn-client-first-pref-on-mismatch-resumption-client + +-[15-npn-client-first-pref-on-mismatch-resumption-server] ++[17-npn-client-first-pref-on-mismatch-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[15-npn-client-first-pref-on-mismatch-resumption-resume-server] ++[17-npn-client-first-pref-on-mismatch-resumption-resume-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[15-npn-client-first-pref-on-mismatch-resumption-client] ++[17-npn-client-first-pref-on-mismatch-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-15] ++[test-17] + ExpectedNPNProtocol = foo + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 15-npn-client-first-pref-on-mismatch-resumption-server-extra +-resume-server = 15-npn-client-first-pref-on-mismatch-resumption-resume-server-extra +-client = 15-npn-client-first-pref-on-mismatch-resumption-client-extra +-resume-client = 15-npn-client-first-pref-on-mismatch-resumption-client-extra ++server = 17-npn-client-first-pref-on-mismatch-resumption-server-extra ++resume-server = 17-npn-client-first-pref-on-mismatch-resumption-resume-server-extra ++client = 17-npn-client-first-pref-on-mismatch-resumption-client-extra ++resume-client = 17-npn-client-first-pref-on-mismatch-resumption-client-extra + +-[15-npn-client-first-pref-on-mismatch-resumption-server-extra] ++[17-npn-client-first-pref-on-mismatch-resumption-server-extra] + NPNProtocols = bar + +-[15-npn-client-first-pref-on-mismatch-resumption-resume-server-extra] ++[17-npn-client-first-pref-on-mismatch-resumption-resume-server-extra] + NPNProtocols = baz + +-[15-npn-client-first-pref-on-mismatch-resumption-client-extra] ++[17-npn-client-first-pref-on-mismatch-resumption-client-extra] + NPNProtocols = foo,bar + + + # =========================================================== + +-[16-npn-no-server-support-resumption] +-ssl_conf = 16-npn-no-server-support-resumption-ssl ++[18-npn-no-server-support-resumption] ++ssl_conf = 18-npn-no-server-support-resumption-ssl + +-[16-npn-no-server-support-resumption-ssl] +-server = 16-npn-no-server-support-resumption-server +-client = 16-npn-no-server-support-resumption-client +-resume-server = 16-npn-no-server-support-resumption-resume-server +-resume-client = 16-npn-no-server-support-resumption-client ++[18-npn-no-server-support-resumption-ssl] ++server = 18-npn-no-server-support-resumption-server ++client = 18-npn-no-server-support-resumption-client ++resume-server = 18-npn-no-server-support-resumption-resume-server ++resume-client = 18-npn-no-server-support-resumption-client + +-[16-npn-no-server-support-resumption-server] ++[18-npn-no-server-support-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[16-npn-no-server-support-resumption-resume-server] ++[18-npn-no-server-support-resumption-resume-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[16-npn-no-server-support-resumption-client] ++[18-npn-no-server-support-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-16] ++[test-18] + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 16-npn-no-server-support-resumption-server-extra +-client = 16-npn-no-server-support-resumption-client-extra +-resume-client = 16-npn-no-server-support-resumption-client-extra ++server = 18-npn-no-server-support-resumption-server-extra ++client = 18-npn-no-server-support-resumption-client-extra ++resume-client = 18-npn-no-server-support-resumption-client-extra + +-[16-npn-no-server-support-resumption-server-extra] ++[18-npn-no-server-support-resumption-server-extra] + NPNProtocols = foo + +-[16-npn-no-server-support-resumption-client-extra] ++[18-npn-no-server-support-resumption-client-extra] + NPNProtocols = foo + + + # =========================================================== + +-[17-npn-no-client-support-resumption] +-ssl_conf = 17-npn-no-client-support-resumption-ssl ++[19-npn-no-client-support-resumption] ++ssl_conf = 19-npn-no-client-support-resumption-ssl + +-[17-npn-no-client-support-resumption-ssl] +-server = 17-npn-no-client-support-resumption-server +-client = 17-npn-no-client-support-resumption-client +-resume-server = 17-npn-no-client-support-resumption-server +-resume-client = 17-npn-no-client-support-resumption-resume-client ++[19-npn-no-client-support-resumption-ssl] ++server = 19-npn-no-client-support-resumption-server ++client = 19-npn-no-client-support-resumption-client ++resume-server = 19-npn-no-client-support-resumption-server ++resume-client = 19-npn-no-client-support-resumption-resume-client + +-[17-npn-no-client-support-resumption-server] ++[19-npn-no-client-support-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[17-npn-no-client-support-resumption-client] ++[19-npn-no-client-support-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[17-npn-no-client-support-resumption-resume-client] ++[19-npn-no-client-support-resumption-resume-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-17] ++[test-19] + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 17-npn-no-client-support-resumption-server-extra +-resume-server = 17-npn-no-client-support-resumption-server-extra +-client = 17-npn-no-client-support-resumption-client-extra ++server = 19-npn-no-client-support-resumption-server-extra ++resume-server = 19-npn-no-client-support-resumption-server-extra ++client = 19-npn-no-client-support-resumption-client-extra + +-[17-npn-no-client-support-resumption-server-extra] ++[19-npn-no-client-support-resumption-server-extra] + NPNProtocols = foo + +-[17-npn-no-client-support-resumption-client-extra] ++[19-npn-no-client-support-resumption-client-extra] + NPNProtocols = foo + + + # =========================================================== + +-[18-alpn-preferred-over-npn-resumption] +-ssl_conf = 18-alpn-preferred-over-npn-resumption-ssl ++[20-alpn-preferred-over-npn-resumption] ++ssl_conf = 20-alpn-preferred-over-npn-resumption-ssl + +-[18-alpn-preferred-over-npn-resumption-ssl] +-server = 18-alpn-preferred-over-npn-resumption-server +-client = 18-alpn-preferred-over-npn-resumption-client +-resume-server = 18-alpn-preferred-over-npn-resumption-resume-server +-resume-client = 18-alpn-preferred-over-npn-resumption-client ++[20-alpn-preferred-over-npn-resumption-ssl] ++server = 20-alpn-preferred-over-npn-resumption-server ++client = 20-alpn-preferred-over-npn-resumption-client ++resume-server = 20-alpn-preferred-over-npn-resumption-resume-server ++resume-client = 20-alpn-preferred-over-npn-resumption-client + +-[18-alpn-preferred-over-npn-resumption-server] ++[20-alpn-preferred-over-npn-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[18-alpn-preferred-over-npn-resumption-resume-server] ++[20-alpn-preferred-over-npn-resumption-resume-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[18-alpn-preferred-over-npn-resumption-client] ++[20-alpn-preferred-over-npn-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-18] ++[test-20] + ExpectedALPNProtocol = foo + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 18-alpn-preferred-over-npn-resumption-server-extra +-resume-server = 18-alpn-preferred-over-npn-resumption-resume-server-extra +-client = 18-alpn-preferred-over-npn-resumption-client-extra +-resume-client = 18-alpn-preferred-over-npn-resumption-client-extra ++server = 20-alpn-preferred-over-npn-resumption-server-extra ++resume-server = 20-alpn-preferred-over-npn-resumption-resume-server-extra ++client = 20-alpn-preferred-over-npn-resumption-client-extra ++resume-client = 20-alpn-preferred-over-npn-resumption-client-extra + +-[18-alpn-preferred-over-npn-resumption-server-extra] ++[20-alpn-preferred-over-npn-resumption-server-extra] + NPNProtocols = bar + +-[18-alpn-preferred-over-npn-resumption-resume-server-extra] ++[20-alpn-preferred-over-npn-resumption-resume-server-extra] + ALPNProtocols = foo + NPNProtocols = baz + +-[18-alpn-preferred-over-npn-resumption-client-extra] ++[20-alpn-preferred-over-npn-resumption-client-extra] + ALPNProtocols = foo + NPNProtocols = bar,baz + + + # =========================================================== + +-[19-npn-used-if-alpn-not-supported-resumption] +-ssl_conf = 19-npn-used-if-alpn-not-supported-resumption-ssl ++[21-npn-used-if-alpn-not-supported-resumption] ++ssl_conf = 21-npn-used-if-alpn-not-supported-resumption-ssl + +-[19-npn-used-if-alpn-not-supported-resumption-ssl] +-server = 19-npn-used-if-alpn-not-supported-resumption-server +-client = 19-npn-used-if-alpn-not-supported-resumption-client +-resume-server = 19-npn-used-if-alpn-not-supported-resumption-resume-server +-resume-client = 19-npn-used-if-alpn-not-supported-resumption-client ++[21-npn-used-if-alpn-not-supported-resumption-ssl] ++server = 21-npn-used-if-alpn-not-supported-resumption-server ++client = 21-npn-used-if-alpn-not-supported-resumption-client ++resume-server = 21-npn-used-if-alpn-not-supported-resumption-resume-server ++resume-client = 21-npn-used-if-alpn-not-supported-resumption-client + +-[19-npn-used-if-alpn-not-supported-resumption-server] ++[21-npn-used-if-alpn-not-supported-resumption-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[19-npn-used-if-alpn-not-supported-resumption-resume-server] ++[21-npn-used-if-alpn-not-supported-resumption-resume-server] + Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem + CipherString = DEFAULT + PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +-[19-npn-used-if-alpn-not-supported-resumption-client] ++[21-npn-used-if-alpn-not-supported-resumption-client] + CipherString = DEFAULT + MaxProtocol = TLSv1.2 + VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem + VerifyMode = Peer + +-[test-19] ++[test-21] + ExpectedNPNProtocol = baz + HandshakeMode = Resume + ResumptionExpected = Yes +-server = 19-npn-used-if-alpn-not-supported-resumption-server-extra +-resume-server = 19-npn-used-if-alpn-not-supported-resumption-resume-server-extra +-client = 19-npn-used-if-alpn-not-supported-resumption-client-extra +-resume-client = 19-npn-used-if-alpn-not-supported-resumption-client-extra ++server = 21-npn-used-if-alpn-not-supported-resumption-server-extra ++resume-server = 21-npn-used-if-alpn-not-supported-resumption-resume-server-extra ++client = 21-npn-used-if-alpn-not-supported-resumption-client-extra ++resume-client = 21-npn-used-if-alpn-not-supported-resumption-client-extra + +-[19-npn-used-if-alpn-not-supported-resumption-server-extra] ++[21-npn-used-if-alpn-not-supported-resumption-server-extra] + ALPNProtocols = foo + NPNProtocols = bar + +-[19-npn-used-if-alpn-not-supported-resumption-resume-server-extra] ++[21-npn-used-if-alpn-not-supported-resumption-resume-server-extra] + NPNProtocols = baz + +-[19-npn-used-if-alpn-not-supported-resumption-client-extra] ++[21-npn-used-if-alpn-not-supported-resumption-client-extra] + ALPNProtocols = foo + NPNProtocols = bar,baz + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf.in b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf.in +index b5df13d..8e4d0fc 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf.in ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf.in +@@ -110,6 +110,41 @@ our @tests = ( + "ExpectedNPNProtocol" => undef, + }, + }, ++ { ++ name => "npn-empty-client-list", ++ server => { ++ extra => { ++ "NPNProtocols" => "foo", ++ }, ++ }, ++ client => { ++ extra => { ++ "NPNProtocols" => "", ++ }, ++ "MaxProtocol" => "TLSv1.2" ++ }, ++ test => { ++ "ExpectedResult" => "ClientFail", ++ "ExpectedClientAlert" => "HandshakeFailure" ++ }, ++ }, ++ { ++ name => "npn-empty-server-list", ++ server => { ++ extra => { ++ "NPNProtocols" => "", ++ }, ++ }, ++ client => { ++ extra => { ++ "NPNProtocols" => "foo", ++ }, ++ "MaxProtocol" => "TLSv1.2" ++ }, ++ test => { ++ "ExpectedNPNProtocol" => "foo" ++ }, ++ }, + { + name => "npn-with-sni-no-context-switch", + server => { +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf +index e7e6cb9..dd66873 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf +@@ -1,6 +1,6 @@ + # Generated with generate_ssl_tests.pl + +-num_tests = 16 ++num_tests = 18 + + test-0 = 0-alpn-simple + test-1 = 1-alpn-server-finds-match +@@ -18,6 +18,8 @@ test-12 = 12-alpn-client-switch-resumption + test-13 = 13-alpn-alert-on-mismatch-resumption + test-14 = 14-alpn-no-server-support-resumption + test-15 = 15-alpn-no-client-support-resumption ++test-16 = 16-alpn-empty-client-list ++test-17 = 17-alpn-empty-server-list + # =========================================================== + + [0-alpn-simple] +@@ -617,3 +619,65 @@ ALPNProtocols = foo + ALPNProtocols = foo + + ++# =========================================================== ++ ++[16-alpn-empty-client-list] ++ssl_conf = 16-alpn-empty-client-list-ssl ++ ++[16-alpn-empty-client-list-ssl] ++server = 16-alpn-empty-client-list-server ++client = 16-alpn-empty-client-list-client ++ ++[16-alpn-empty-client-list-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[16-alpn-empty-client-list-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-16] ++server = 16-alpn-empty-client-list-server-extra ++client = 16-alpn-empty-client-list-client-extra ++ ++[16-alpn-empty-client-list-server-extra] ++ALPNProtocols = foo ++ ++[16-alpn-empty-client-list-client-extra] ++ALPNProtocols = ++ ++ ++# =========================================================== ++ ++[17-alpn-empty-server-list] ++ssl_conf = 17-alpn-empty-server-list-ssl ++ ++[17-alpn-empty-server-list-ssl] ++server = 17-alpn-empty-server-list-server ++client = 17-alpn-empty-server-list-client ++ ++[17-alpn-empty-server-list-server] ++Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem ++CipherString = DEFAULT ++PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem ++ ++[17-alpn-empty-server-list-client] ++CipherString = DEFAULT ++VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem ++VerifyMode = Peer ++ ++[test-17] ++ExpectedResult = ServerFail ++ExpectedServerAlert = NoApplicationProtocol ++server = 17-alpn-empty-server-list-server-extra ++client = 17-alpn-empty-server-list-client-extra ++ ++[17-alpn-empty-server-list-server-extra] ++ALPNProtocols = ++ ++[17-alpn-empty-server-list-client-extra] ++ALPNProtocols = foo ++ ++ +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf.in b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf.in +index 6e86375..301a707 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf.in ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf.in +@@ -322,4 +322,37 @@ our @tests = ( + "ExpectedALPNProtocol" => undef, + }, + }, ++ { ++ name => "alpn-empty-client-list", ++ server => { ++ extra => { ++ "ALPNProtocols" => "foo", ++ }, ++ }, ++ client => { ++ extra => { ++ "ALPNProtocols" => "", ++ }, ++ }, ++ test => { ++ "ExpectedALPNProtocol" => undef, ++ }, ++ }, ++ { ++ name => "alpn-empty-server-list", ++ server => { ++ extra => { ++ "ALPNProtocols" => "", ++ }, ++ }, ++ client => { ++ extra => { ++ "ALPNProtocols" => "foo", ++ }, ++ }, ++ test => { ++ "ExpectedResult" => "ServerFail", ++ "ExpectedServerAlert" => "NoApplicationProtocol", ++ }, ++ }, + ); +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +index 74bc0af..00097e4 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c +@@ -6767,6 +6767,367 @@ static int test_multi_resume(int idx) + return testresult; + } + ++static struct next_proto_st { ++ int serverlen; ++ unsigned char server[40]; ++ int clientlen; ++ unsigned char client[40]; ++ int expected_ret; ++ size_t selectedlen; ++ unsigned char selected[40]; ++} next_proto_tests[] = { ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b' }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c', }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b', }, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 7, { 2, 'b', 'c', 3, 'a', 'b', 'c' }, ++ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 10, { 2, 'b', 'c', 3, 'a', 'b', 'c', 2, 'a', 'b' }, ++ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'}, ++ OPENSSL_NPN_NEGOTIATED, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 4, { 3, 'b', 'c', 'd' }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 0, { 0 }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ -1, { 0 }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ 0, { 0 }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 0, { 0 } ++ }, ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ -1, { 0 }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 0, { 0 } ++ }, ++ { ++ 3, { 3, 'a', 'b', 'c' }, ++ 4, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 3, { 'a', 'b', 'c' } ++ }, ++ { ++ 4, { 3, 'a', 'b', 'c' }, ++ 3, { 3, 'a', 'b', 'c' }, ++ OPENSSL_NPN_NO_OVERLAP, ++ 0, { 0 } ++ } ++}; ++ ++static int test_select_next_proto(int idx) ++{ ++ struct next_proto_st *np = &next_proto_tests[idx]; ++ int ret = 0; ++ unsigned char *out, *client, *server; ++ unsigned char outlen; ++ unsigned int clientlen, serverlen; ++ ++ if (np->clientlen == -1) { ++ client = NULL; ++ clientlen = 0; ++ } else { ++ client = np->client; ++ clientlen = (unsigned int)np->clientlen; ++ } ++ if (np->serverlen == -1) { ++ server = NULL; ++ serverlen = 0; ++ } else { ++ server = np->server; ++ serverlen = (unsigned int)np->serverlen; ++ } ++ ++ if (!TEST_int_eq(SSL_select_next_proto(&out, &outlen, server, serverlen, ++ client, clientlen), ++ np->expected_ret)) ++ goto err; ++ ++ if (np->selectedlen == 0) { ++ if (!TEST_ptr_null(out) || !TEST_uchar_eq(outlen, 0)) ++ goto err; ++ } else { ++ if (!TEST_mem_eq(out, outlen, np->selected, np->selectedlen)) ++ goto err; ++ } ++ ++ ret = 1; ++ err: ++ return ret; ++} ++ ++static const unsigned char fooprot[] = {3, 'f', 'o', 'o' }; ++static const unsigned char barprot[] = {3, 'b', 'a', 'r' }; ++ ++#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) ++static int npn_advert_cb(SSL *ssl, const unsigned char **out, ++ unsigned int *outlen, void *arg) ++{ ++ int *idx = (int *)arg; ++ ++ switch (*idx) { ++ default: ++ case 0: ++ *out = fooprot; ++ *outlen = sizeof(fooprot); ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 1: ++ *outlen = 0; ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 2: ++ return SSL_TLSEXT_ERR_NOACK; ++ } ++} ++ ++static int npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, ++ const unsigned char *in, unsigned int inlen, void *arg) ++{ ++ int *idx = (int *)arg; ++ ++ switch (*idx) { ++ case 0: ++ case 1: ++ *out = (unsigned char *)(fooprot + 1); ++ *outlen = *fooprot; ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 3: ++ *out = (unsigned char *)(barprot + 1); ++ *outlen = *barprot; ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 4: ++ *outlen = 0; ++ return SSL_TLSEXT_ERR_OK; ++ ++ default: ++ case 2: ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ } ++} ++ ++/* ++ * Test the NPN callbacks ++ * Test 0: advert = foo, select = foo ++ * Test 1: advert = , select = foo ++ * Test 2: no advert ++ * Test 3: advert = foo, select = bar ++ * Test 4: advert = foo, select = (should fail) ++ */ ++static int test_npn(int idx) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *serverssl = NULL, *clientssl = NULL; ++ int testresult = 0; ++ ++ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), ++ TLS_client_method(), 0, TLS1_2_VERSION, ++ &sctx, &cctx, cert, privkey))) ++ goto end; ++ ++ SSL_CTX_set_next_protos_advertised_cb(sctx, npn_advert_cb, &idx); ++ SSL_CTX_set_next_proto_select_cb(cctx, npn_select_cb, &idx); ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, ++ NULL))) ++ goto end; ++ ++ if (idx == 4) { ++ /* We don't allow empty selection of NPN, so this should fail */ ++ if (!TEST_false(create_ssl_connection(serverssl, clientssl, ++ SSL_ERROR_NONE))) ++ goto end; ++ } else { ++ const unsigned char *prot; ++ unsigned int protlen; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, ++ SSL_ERROR_NONE))) ++ goto end; ++ ++ SSL_get0_next_proto_negotiated(serverssl, &prot, &protlen); ++ switch (idx) { ++ case 0: ++ case 1: ++ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot)) ++ goto end; ++ break; ++ case 2: ++ if (!TEST_uint_eq(protlen, 0)) ++ goto end; ++ break; ++ case 3: ++ if (!TEST_mem_eq(prot, protlen, barprot + 1, *barprot)) ++ goto end; ++ break; ++ default: ++ TEST_error("Should not get here"); ++ goto end; ++ } ++ } ++ ++ testresult = 1; ++ end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ ++ return testresult; ++} ++#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) */ ++ ++static int alpn_select_cb2(SSL *ssl, const unsigned char **out, ++ unsigned char *outlen, const unsigned char *in, ++ unsigned int inlen, void *arg) ++{ ++ int *idx = (int *)arg; ++ ++ switch (*idx) { ++ case 0: ++ *out = (unsigned char *)(fooprot + 1); ++ *outlen = *fooprot; ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 2: ++ *out = (unsigned char *)(barprot + 1); ++ *outlen = *barprot; ++ return SSL_TLSEXT_ERR_OK; ++ ++ case 3: ++ *outlen = 0; ++ return SSL_TLSEXT_ERR_OK; ++ ++ default: ++ case 1: ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ } ++ return 0; ++} ++ ++/* ++ * Test the ALPN callbacks ++ * Test 0: client = foo, select = foo ++ * Test 1: client = , select = none ++ * Test 2: client = foo, select = bar (should fail) ++ * Test 3: client = foo, select = (should fail) ++ */ ++static int test_alpn(int idx) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *serverssl = NULL, *clientssl = NULL; ++ int testresult = 0; ++ const unsigned char *prots = fooprot; ++ unsigned int protslen = sizeof(fooprot); ++ ++ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), ++ TLS_client_method(), 0, 0, ++ &sctx, &cctx, cert, privkey))) ++ goto end; ++ ++ SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb2, &idx); ++ ++ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, ++ NULL))) ++ goto end; ++ ++ if (idx == 1) { ++ prots = NULL; ++ protslen = 0; ++ } ++ ++ /* SSL_set_alpn_protos returns 0 for success! */ ++ if (!TEST_false(SSL_set_alpn_protos(clientssl, prots, protslen))) ++ goto end; ++ ++ if (idx == 2 || idx == 3) { ++ /* We don't allow empty selection of NPN, so this should fail */ ++ if (!TEST_false(create_ssl_connection(serverssl, clientssl, ++ SSL_ERROR_NONE))) ++ goto end; ++ } else { ++ const unsigned char *prot; ++ unsigned int protlen; ++ ++ if (!TEST_true(create_ssl_connection(serverssl, clientssl, ++ SSL_ERROR_NONE))) ++ goto end; ++ ++ SSL_get0_alpn_selected(clientssl, &prot, &protlen); ++ switch (idx) { ++ case 0: ++ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot)) ++ goto end; ++ break; ++ case 1: ++ if (!TEST_uint_eq(protlen, 0)) ++ goto end; ++ break; ++ default: ++ TEST_error("Should not get here"); ++ goto end; ++ } ++ } ++ ++ testresult = 1; ++ end: ++ SSL_free(serverssl); ++ SSL_free(clientssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ ++ return testresult; ++} ++ + int setup_tests(void) + { + if (!TEST_ptr(certsdir = test_get_argument(0)) +@@ -6890,6 +7251,11 @@ int setup_tests(void) + ADD_ALL_TESTS(test_ca_names, 3); + ADD_ALL_TESTS(test_servername, 10); + ADD_ALL_TESTS(test_multi_resume, 5); ++ ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests)); ++#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) ++ ADD_ALL_TESTS(test_npn, 5); ++#endif ++ ADD_ALL_TESTS(test_alpn, 4); + return 1; + } + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Message.pm b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Message.pm +index 10b6156..acdb834 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Message.pm ++++ b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Message.pm +@@ -379,6 +379,15 @@ sub create_message + [@message_frag_lens] + ); + $message->parse(); ++ } elsif ($mt == MT_NEXT_PROTO) { ++ $message = TLSProxy::NextProto->new( ++ $server, ++ $data, ++ [@message_rec_list], ++ $startoffset, ++ [@message_frag_lens] ++ ); ++ $message->parse(); + } else { + #Unknown message type + $message = TLSProxy::Message->new( +diff --git a/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/NextProto.pm b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/NextProto.pm +new file mode 100644 +index 0000000..0e18347 +--- /dev/null ++++ b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/NextProto.pm +@@ -0,0 +1,54 @@ ++# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. ++# ++# Licensed under the Apache License 2.0 (the "License"). You may not use ++# this file except in compliance with the License. You can obtain a copy ++# in the file LICENSE in the source distribution or at ++# https://www.openssl.org/source/license.html ++ ++use strict; ++ ++package TLSProxy::NextProto; ++ ++use vars '@ISA'; ++push @ISA, 'TLSProxy::Message'; ++ ++sub new ++{ ++ my $class = shift; ++ my ($server, ++ $data, ++ $records, ++ $startoffset, ++ $message_frag_lens) = @_; ++ ++ my $self = $class->SUPER::new( ++ $server, ++ TLSProxy::Message::MT_NEXT_PROTO, ++ $data, ++ $records, ++ $startoffset, ++ $message_frag_lens); ++ ++ return $self; ++} ++ ++sub parse ++{ ++ # We don't support parsing at the moment ++} ++ ++# This is supposed to reconstruct the on-the-wire message data following changes. ++# For now though since we don't support parsing we just create an empty NextProto ++# message - this capability is used in test_npn ++sub set_message_contents ++{ ++ my $self = shift; ++ my $data; ++ ++ $data = pack("C32", 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00); ++ $self->data($data); ++} ++1; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Proxy.pm b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Proxy.pm +index 6f983b3..0b2e657 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Proxy.pm ++++ b/CryptoPkg/Library/OpensslLib/openssl/util/perl/TLSProxy/Proxy.pm +@@ -23,6 +23,7 @@ use TLSProxy::CertificateRequest; + use TLSProxy::CertificateVerify; + use TLSProxy::ServerKeyExchange; + use TLSProxy::NewSessionTicket; ++use TLSProxy::NextProto; + + my $have_IPv6; + my $IP_factory; +-- +2.33.0 + diff --git a/0080-Fix-i2v_GENERAL_NAME-to-not-assume-NUL-terminated-st.patch b/0080-Fix-i2v_GENERAL_NAME-to-not-assume-NUL-terminated-st.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1577ba92c169635ef29e3f3f03374e98ac5c4ef --- /dev/null +++ b/0080-Fix-i2v_GENERAL_NAME-to-not-assume-NUL-terminated-st.patch @@ -0,0 +1,148 @@ +From 380b8db5b1310e2242a6d29d77682593d10ee266 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 12:24:22 +0100 +Subject: [PATCH 1/9] Fix i2v_GENERAL_NAME to not assume NUL terminated strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + .../OpensslLib/openssl/crypto/x509v3/v3_alt.c | 10 +++-- + .../OpensslLib/openssl/crypto/x509v3/v3_utl.c | 38 ++++++++++++++++--- + .../OpensslLib/openssl/include/crypto/x509.h | 5 +++ + 3 files changed, 44 insertions(+), 9 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c +index 7ac2911..79f0f14 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c +@@ -9,6 +9,7 @@ + + #include + #include "internal/cryptlib.h" ++#include "crypto/x509.h" + #include + #include + #include "ext_dat.h" +@@ -99,17 +100,20 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + break; + + case GEN_EMAIL: +- if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) ++ if (!x509v3_add_len_value_uchar("email", gen->d.ia5->data, ++ gen->d.ia5->length, &ret)) + return NULL; + break; + + case GEN_DNS: +- if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) ++ if (!x509v3_add_len_value_uchar("DNS", gen->d.ia5->data, ++ gen->d.ia5->length, &ret)) + return NULL; + break; + + case GEN_URI: +- if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) ++ if (!x509v3_add_len_value_uchar("URI", gen->d.ia5->data, ++ gen->d.ia5->length, &ret)) + return NULL; + break; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c +index 7281a7b..004ef55 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c +@@ -12,6 +12,7 @@ + #include "e_os.h" + #include "internal/cryptlib.h" + #include ++#include + #include "crypto/ctype.h" + #include + #include +@@ -34,17 +35,26 @@ static int ipv6_hex(unsigned char *out, const char *in, int inlen); + + /* Add a CONF_VALUE name value pair to stack */ + +-int X509V3_add_value(const char *name, const char *value, +- STACK_OF(CONF_VALUE) **extlist) ++static int x509v3_add_len_value(const char *name, const char *value, ++ size_t vallen, STACK_OF(CONF_VALUE) **extlist) + { + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + int sk_allocated = (*extlist == NULL); + +- if (name && (tname = OPENSSL_strdup(name)) == NULL) +- goto err; +- if (value && (tvalue = OPENSSL_strdup(value)) == NULL) ++ if (name != NULL && (tname = OPENSSL_strdup(name)) == NULL) + goto err; ++ if (value != NULL && vallen > 0) { ++ /* ++ * We tolerate a single trailing NUL character, but otherwise no ++ * embedded NULs ++ */ ++ if (memchr(value, 0, vallen - 1) != NULL) ++ goto err; ++ tvalue = OPENSSL_strndup(value, vallen); ++ if (tvalue == NULL) ++ goto err; ++ } + if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL) + goto err; + if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL) +@@ -67,10 +77,26 @@ int X509V3_add_value(const char *name, const char *value, + return 0; + } + ++int X509V3_add_value(const char *name, const char *value, ++ STACK_OF(CONF_VALUE) **extlist) ++{ ++ return x509v3_add_len_value(name, value, ++ value != NULL ? strlen((const char *)value) : 0, ++ extlist); ++} ++ + int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) + { +- return X509V3_add_value(name, (const char *)value, extlist); ++ return x509v3_add_len_value(name, (const char *)value, ++ value != NULL ? strlen((const char *)value) : 0, ++ extlist); ++} ++ ++int x509v3_add_len_value_uchar(const char *name, const unsigned char *value, ++ size_t vallen, STACK_OF(CONF_VALUE) **extlist) ++{ ++ return x509v3_add_len_value(name, (const char *)value, vallen, extlist); + } + + /* Free function for STACK_OF(CONF_VALUE) */ +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/x509.h b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/x509.h +index b53c2b0..7ffb8ab 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/x509.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/x509.h +@@ -8,6 +8,8 @@ + */ + + #include "internal/refcount.h" ++#include ++#include + + /* Internal X509 structures and functions: not for application use */ + +@@ -284,3 +286,6 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc); + int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm); + + void x509_init_sig_info(X509 *x); ++ ++int x509v3_add_len_value_uchar(const char *name, const unsigned char *value, ++ size_t vallen, STACK_OF(CONF_VALUE) **extlist); +-- +2.33.0 + diff --git a/0081-Fix-POLICYINFO-printing-to-not-assume-NUL-terminated.patch b/0081-Fix-POLICYINFO-printing-to-not-assume-NUL-terminated.patch new file mode 100644 index 0000000000000000000000000000000000000000..3579cc0fcd3bfe082b66785c3437afe1bbf76b2a --- /dev/null +++ b/0081-Fix-POLICYINFO-printing-to-not-assume-NUL-terminated.patch @@ -0,0 +1,53 @@ +From 87e959f14e82b34fcb29bd11274b7039678639f1 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 12:31:38 +0100 +Subject: [PATCH 2/9] Fix POLICYINFO printing to not assume NUL terminated + strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + .../Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c +index 1d12c89..861e845 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c +@@ -422,7 +422,8 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: +- BIO_printf(out, "%*sCPS: %s\n", indent, "", ++ BIO_printf(out, "%*sCPS: %.*s\n", indent, "", ++ qualinfo->d.cpsuri->length, + qualinfo->d.cpsuri->data); + break; + +@@ -447,7 +448,8 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; +- BIO_printf(out, "%*sOrganization: %s\n", indent, "", ++ BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", ++ ref->organization->length, + ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); +@@ -470,7 +472,8 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) + BIO_puts(out, "\n"); + } + if (notice->exptext) +- BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", ++ BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", ++ notice->exptext->length, + notice->exptext->data); + } + +-- +2.33.0 + diff --git a/0082-Fix-printing-of-PROXY_CERT_INFO_EXTENSION-to-not-ass.patch b/0082-Fix-printing-of-PROXY_CERT_INFO_EXTENSION-to-not-ass.patch new file mode 100644 index 0000000000000000000000000000000000000000..328861bd6d666f3e4739691348b65f710bcd869f --- /dev/null +++ b/0082-Fix-printing-of-PROXY_CERT_INFO_EXTENSION-to-not-ass.patch @@ -0,0 +1,33 @@ +From 68557991614b61629dce4a6ab4510087ff28022c Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 14:02:40 +0100 +Subject: [PATCH 3/9] Fix printing of PROXY_CERT_INFO_EXTENSION to not assume + NUL terminated strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c +index 3d124fa..98b6ef2 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c +@@ -77,7 +77,8 @@ static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) +- BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", ++ BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "", ++ pci->proxyPolicy->policy->length, + pci->proxyPolicy->policy->data); + return 1; + } +-- +2.33.0 + diff --git a/0083-Fix-the-name-constraints-code-to-not-assume-NUL-term.patch b/0083-Fix-the-name-constraints-code-to-not-assume-NUL-term.patch new file mode 100644 index 0000000000000000000000000000000000000000..76519aabab404fc7dbe34b3c297b8963b0a91abd --- /dev/null +++ b/0083-Fix-the-name-constraints-code-to-not-assume-NUL-term.patch @@ -0,0 +1,190 @@ +From 1339d0d1c2ff45d1a846c3df2cf66f2ca24f4c9b Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 17:08:58 +0100 +Subject: [PATCH 4/9] Fix the name constraints code to not assume NUL + terminated strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + .../openssl/crypto/x509v3/v3_ncons.c | 77 +++++++++++++------ + 1 file changed, 52 insertions(+), 25 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c +index 2a7b4f0..cb701c4 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c +@@ -63,8 +63,31 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { + IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + ++ ++#define IA5_OFFSET_LEN(ia5base, offset) \ ++ ((ia5base)->length - ((unsigned char *)(offset) - (ia5base)->data)) ++ ++/* Like memchr but for ASN1_IA5STRING. Additionally you can specify the ++ * starting point to search from ++ */ ++# define ia5memchr(str, start, c) memchr(start, c, IA5_OFFSET_LEN(str, start)) ++ ++/* Like memrrchr but for ASN1_IA5STRING */ ++static char *ia5memrchr(ASN1_IA5STRING *str, int c) ++{ ++ int i; ++ ++ for (i = str->length; i > 0 && str->data[i - 1] != c; i--); ++ ++ if (i == 0) ++ return NULL; ++ ++ return (char *)&str->data[i - 1]; ++} ++ + /* +- * We cannot use strncasecmp here because that applies locale specific rules. ++ * We cannot use strncasecmp here because that applies locale specific rules. It ++ * also doesn't work with ASN1_STRINGs that may have embedded NUL characters. + * For example in Turkish 'I' is not the uppercase character for 'i'. We need to + * do a simple ASCII case comparison ignoring the locale (that is why we use + * numeric constants below). +@@ -89,20 +112,12 @@ static int ia5ncasecmp(const char *s1, const char *s2, size_t n) + + /* c1 > c2 */ + return 1; +- } else if (*s1 == 0) { +- /* If we get here we know that *s2 == 0 too */ +- return 0; + } + } + + return 0; + } + +-static int ia5casecmp(const char *s1, const char *s2) +-{ +- return ia5ncasecmp(s1, s2, SIZE_MAX); +-} +- + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) + { +@@ -337,7 +352,7 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) + --utf8_length; + + /* Reject *embedded* NULs */ +- if ((size_t)utf8_length != strlen((char *)utf8_value)) { ++ if (memchr(utf8_value, 0, utf8_length) != NULL) { + OPENSSL_free(utf8_value); + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } +@@ -536,9 +551,14 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) + { + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; ++ + /* Empty matches everything */ +- if (!*baseptr) ++ if (base->length == 0) + return X509_V_OK; ++ ++ if (dns->length < base->length) ++ return X509_V_ERR_PERMITTED_VIOLATION; ++ + /* + * Otherwise can add zero or more components on the left so compare RHS + * and if dns is longer and expect '.' as preceding character. +@@ -549,7 +569,7 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) + return X509_V_ERR_PERMITTED_VIOLATION; + } + +- if (ia5casecmp(baseptr, dnsptr)) ++ if (ia5ncasecmp(baseptr, dnsptr, base->length)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +@@ -560,16 +580,17 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) + { + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; ++ const char *baseat = ia5memrchr(base, '@'); ++ const char *emlat = ia5memrchr(eml, '@'); ++ size_t basehostlen, emlhostlen; + +- const char *baseat = strchr(baseptr, '@'); +- const char *emlat = strchr(emlptr, '@'); + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: initial '.' is RHS match */ +- if (!baseat && (*baseptr == '.')) { ++ if (!baseat && base->length > 0 && (*baseptr == '.')) { + if (eml->length > base->length) { + emlptr += eml->length - base->length; +- if (ia5casecmp(baseptr, emlptr) == 0) ++ if (ia5ncasecmp(baseptr, emlptr, base->length) == 0) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; +@@ -589,8 +610,10 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) + baseptr = baseat + 1; + } + emlptr = emlat + 1; ++ basehostlen = IA5_OFFSET_LEN(base, baseptr); ++ emlhostlen = IA5_OFFSET_LEN(eml, emlptr); + /* Just have hostname left to match: case insensitive */ +- if (ia5casecmp(baseptr, emlptr)) ++ if (basehostlen != emlhostlen || ia5ncasecmp(baseptr, emlptr, emlhostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +@@ -601,10 +624,14 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) + { + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; +- const char *p = strchr(hostptr, ':'); ++ const char *p = ia5memchr(uri, (char *)uri->data, ':'); + int hostlen; ++ + /* Check for foo:// and skip past it */ +- if (!p || (p[1] != '/') || (p[2] != '/')) ++ if (p == NULL ++ || IA5_OFFSET_LEN(uri, p) < 3 ++ || p[1] != '/' ++ || p[2] != '/') + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + +@@ -612,13 +639,13 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) + + /* Look for a port indicator as end of hostname first */ + +- p = strchr(hostptr, ':'); ++ p = ia5memchr(uri, hostptr, ':'); + /* Otherwise look for trailing slash */ +- if (!p) +- p = strchr(hostptr, '/'); ++ if (p == NULL) ++ p = ia5memchr(uri, hostptr, '/'); + +- if (!p) +- hostlen = strlen(hostptr); ++ if (p == NULL) ++ hostlen = IA5_OFFSET_LEN(uri, hostptr); + else + hostlen = p - hostptr; + +@@ -626,7 +653,7 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: initial '.' is RHS match */ +- if (*baseptr == '.') { ++ if (base->length > 0 && *baseptr == '.') { + if (hostlen > base->length) { + p = hostptr + hostlen - base->length; + if (ia5ncasecmp(p, baseptr, base->length) == 0) +-- +2.33.0 + diff --git a/0084-Fix-test-code-to-not-assume-NUL-terminated-strings.patch b/0084-Fix-test-code-to-not-assume-NUL-terminated-strings.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd8b96ccc1e6c17299f7a4ce4787652056e7d9d9 --- /dev/null +++ b/0084-Fix-test-code-to-not-assume-NUL-terminated-strings.patch @@ -0,0 +1,39 @@ +From 13213d2f8a0003e51f89732e639a7783ce82c94f Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 17:37:41 +0100 +Subject: [PATCH 5/9] Fix test code to not assume NUL terminated strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + .../Library/OpensslLib/openssl/test/x509_time_test.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/x509_time_test.c b/CryptoPkg/Library/OpensslLib/openssl/test/x509_time_test.c +index b6fd38a..d0993d9 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/x509_time_test.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/x509_time_test.c +@@ -330,10 +330,12 @@ static int test_x509_time(int idx) + + /* if t is not NULL but expected_string is NULL, it is an 'OK' case too */ + if (t != NULL && x509_format_tests[idx].expected_string) { +- if (!TEST_str_eq((const char *)t->data, +- x509_format_tests[idx].expected_string)) { +- TEST_info("test_x509_time(%d) failed: expected_string %s, got %s\n", +- idx, x509_format_tests[idx].expected_string, t->data); ++ if (!TEST_mem_eq((const char *)t->data, t->length, ++ x509_format_tests[idx].expected_string, ++ strlen(x509_format_tests[idx].expected_string))) { ++ TEST_info("test_x509_time(%d) failed: expected_string %s, got %.*s\n", ++ idx, x509_format_tests[idx].expected_string, t->length, ++ t->data); + goto out; + } + } +-- +2.33.0 + diff --git a/0085-Fix-append_ia5-function-to-not-assume-NUL-terminated.patch b/0085-Fix-append_ia5-function-to-not-assume-NUL-terminated.patch new file mode 100644 index 0000000000000000000000000000000000000000..a083a8167be374b8e2f702a5b662dee59c1313f9 --- /dev/null +++ b/0085-Fix-append_ia5-function-to-not-assume-NUL-terminated.patch @@ -0,0 +1,55 @@ +From 2c44830ce3b1b2daa18c7b1c5a47877cf728c851 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 18 Aug 2021 17:58:23 +0100 +Subject: [PATCH 6/9] Fix append_ia5 function to not assume NUL terminated + strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + .../OpensslLib/openssl/crypto/x509v3/v3_utl.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c +index 004ef55..513dc68 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c +@@ -528,18 +528,26 @@ static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; +- if (!email->data || !email->length) ++ if (email->data == NULL || email->length == 0) ++ return 1; ++ if (memchr(email->data, 0, email->length) != NULL) + return 1; + if (*sk == NULL) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (*sk == NULL) + return 0; ++ ++ emtmp = OPENSSL_strndup((char *)email->data, email->length); ++ if (emtmp == NULL) ++ return 0; ++ + /* Don't add duplicates */ +- if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) ++ if (sk_OPENSSL_STRING_find(*sk, emtmp) != -1) { ++ OPENSSL_free(emtmp); + return 1; +- emtmp = OPENSSL_strdup((char *)email->data); +- if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) { +- OPENSSL_free(emtmp); /* free on push failure */ ++ } ++ if (!sk_OPENSSL_STRING_push(*sk, emtmp)) { ++ OPENSSL_free(emtmp); /* free on push failure */ + X509_email_free(*sk); + *sk = NULL; + return 0; +-- +2.33.0 + diff --git a/0086-Fix-NETSCAPE_SPKI_print-function-to-not-assume-NUL-t.patch b/0086-Fix-NETSCAPE_SPKI_print-function-to-not-assume-NUL-t.patch new file mode 100644 index 0000000000000000000000000000000000000000..b437fea20cf36ff10026fa8b6536f133dd755a0e --- /dev/null +++ b/0086-Fix-NETSCAPE_SPKI_print-function-to-not-assume-NUL-t.patch @@ -0,0 +1,32 @@ +From a3c789bd414c69c703c49a10b83acf81853f6df6 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 19 Aug 2021 12:23:38 +0100 +Subject: [PATCH 7/9] Fix NETSCAPE_SPKI_print function to not assume NUL + terminated strings + +ASN.1 strings may not be NUL terminated. Don't assume they are. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c +index 51b56d0..64ee77e 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c +@@ -38,7 +38,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) + } + chal = spki->spkac->challenge; + if (chal->length) +- BIO_printf(out, " Challenge String: %s\n", chal->data); ++ BIO_printf(out, " Challenge String: %.*s\n", chal->length, chal->data); + i = OBJ_obj2nid(spki->sig_algor.algorithm); + BIO_printf(out, " Signature Algorithm: %s", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); +-- +2.33.0 + diff --git a/0087-Fix-EC_GROUP_new_from_ecparameters-to-check-the-base.patch b/0087-Fix-EC_GROUP_new_from_ecparameters-to-check-the-base.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1b4de26b88662c8e1ae3f93791df6d3bf7815c0 --- /dev/null +++ b/0087-Fix-EC_GROUP_new_from_ecparameters-to-check-the-base.patch @@ -0,0 +1,36 @@ +From 0d71cee87b0bce7d3729ac4bbefbb42bda6cdb3c Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 19 Aug 2021 12:24:17 +0100 +Subject: [PATCH 8/9] Fix EC_GROUP_new_from_ecparameters to check the base + length + +Check that there's at least one byte in params->base before trying to +read it. + +CVE-2021-3712 + +Reviewed-by: Viktor Dukhovni +Reviewed-by: Paul Dale +--- + CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c +index 336afc9..98a742d 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c +@@ -747,7 +747,10 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) + ret->seed_len = params->curve->seed->length; + } + +- if (!params->order || !params->base || !params->base->data) { ++ if (params->order == NULL ++ || params->base == NULL ++ || params->base->data == NULL ++ || params->base->length == 0) { + ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR); + goto err; + } +-- +2.33.0 + diff --git a/0088-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch b/0088-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch new file mode 100644 index 0000000000000000000000000000000000000000..cfe0cae2aef425945db3bd9ea913ba2122b65638 --- /dev/null +++ b/0088-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch @@ -0,0 +1,69 @@ +From 8c40007cee48ac54f0644a1c8e01809ee47ecf1b Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Mon, 28 Feb 2022 18:26:21 +0100 +Subject: [PATCH 9/9] Fix possible infinite loop in BN_mod_sqrt() + +The calculation in some cases does not finish for non-prime p. + +This fixes CVE-2022-0778. + +Based on patch by David Benjamin . + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + .../OpensslLib/openssl/crypto/bn/bn_sqrt.c | 30 +++++++++++-------- + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c +index 1723d5d..53b0f55 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c +@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + /* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number +- * Theory", algorithm 1.5.1). 'p' must be prime! ++ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or ++ * an incorrect "result" will be returned. + */ + { + BIGNUM *ret = in; +@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + goto vrfy; + } + +- /* find smallest i such that b^(2^i) = 1 */ +- i = 1; +- if (!BN_mod_sqr(t, b, p, ctx)) +- goto end; +- while (!BN_is_one(t)) { +- i++; +- if (i == e) { +- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); +- goto end; ++ /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */ ++ for (i = 1; i < e; i++) { ++ if (i == 1) { ++ if (!BN_mod_sqr(t, b, p, ctx)) ++ goto end; ++ ++ } else { ++ if (!BN_mod_mul(t, t, t, p, ctx)) ++ goto end; + } +- if (!BN_mod_mul(t, t, t, p, ctx)) +- goto end; ++ if (BN_is_one(t)) ++ break; ++ } ++ /* If not found, a is not a square or p is not prime. */ ++ if (i >= e) { ++ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); ++ goto end; + } + + /* t := y^2^(e - i - 1) */ +-- +2.33.0 + diff --git a/0089-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch b/0089-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch new file mode 100644 index 0000000000000000000000000000000000000000..bd006f0fb1f03ed5a821bd56efd72ce7499d325b --- /dev/null +++ b/0089-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch @@ -0,0 +1,218 @@ +From fdbe00ab92845e2c878eea62be2becc2101dd9b6 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Sat, 7 Sep 2024 17:23:41 +0800 +Subject: [PATCH 1/3] VirtioDxe: add support of MMIO Bar for virtio devices + +As some virtio devices support MMIO BAR, add support for +it in Virtio10Dxe and VirtioPciDeviceDXE. + +Signed-off-by: jiangdongxu +--- + OvmfPkg/Include/Protocol/VirtioDevice.h | 12 +++ + .../VirtioMmioDeviceLib/VirtioMmioDevice.c | 1 + + OvmfPkg/Virtio10Dxe/Virtio10.c | 1 + + OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 89 +++++++++++++++---- + 4 files changed, 85 insertions(+), 18 deletions(-) + +diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h +index ea56071..70491ca 100644 +--- a/OvmfPkg/Include/Protocol/VirtioDevice.h ++++ b/OvmfPkg/Include/Protocol/VirtioDevice.h +@@ -466,6 +466,16 @@ EFI_STATUS + IN VOID *Mapping + ); + ++/** ++ * Note: Zero virtio devices has BAR0 of type MMIO but not PIO which do not ++ * flow the virtio 0.95 spec due to hw limiation. We extend edk2 to support ++ * such variant. ++ */ ++typedef enum { ++ VirtioCfgSpaceAcessIo = 0, ++ VirtioCfgSpaceAcessMem ++} VIRTIO_CFG_SPACE_ACCESS_MODE; ++ + /// + /// This protocol provides an abstraction over the VirtIo transport layer + /// +@@ -482,6 +492,8 @@ struct _VIRTIO_DEVICE_PROTOCOL { + // + INT32 SubSystemDeviceId; + ++ VIRTIO_CFG_SPACE_ACCESS_MODE CfgAccessMode; ++ + VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures; + VIRTIO_SET_GUEST_FEATURES SetGuestFeatures; + +diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c +index 6dbbba0..ac6facc 100644 +--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c ++++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c +@@ -17,6 +17,7 @@ + STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = { + 0, // Revision + 0, // SubSystemDeviceId ++ 0, // CfgAccessMode + VirtioMmioGetDeviceFeatures, // GetDeviceFeatures + VirtioMmioSetGuestFeatures, // SetGuestFeatures + VirtioMmioSetQueueAddress, // SetQueueAddress +diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c +index 4d8e5b5..795b81b 100644 +--- a/OvmfPkg/Virtio10Dxe/Virtio10.c ++++ b/OvmfPkg/Virtio10Dxe/Virtio10.c +@@ -848,6 +848,7 @@ Virtio10UnmapSharedBuffer ( + STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = { + VIRTIO_SPEC_REVISION (1, 0, 0), + 0, // SubSystemDeviceId, filled in dynamically ++ 0, // CfgAccessMode + Virtio10GetDeviceFeatures, + Virtio10SetGuestFeatures, + Virtio10SetQueueAddress, +diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c +index c5c8d5e..cfbe5e1 100644 +--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c ++++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c +@@ -23,6 +23,7 @@ + STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = { + 0, // Revision + 0, // SubSystemDeviceId ++ 0, // CfgAccessMode + VirtioPciGetDeviceFeatures, // GetDeviceFeatures + VirtioPciSetGuestFeatures, // SetGuestFeatures + VirtioPciSetQueueAddress, // SetQueueAddress +@@ -117,14 +118,25 @@ VirtioPciIoRead ( + return EFI_INVALID_PARAMETER; + } + +- return PciIo->Io.Read ( +- PciIo, +- Width, +- PCI_BAR_IDX0, +- FieldOffset, +- Count, +- Buffer +- ); ++ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) { ++ return PciIo->Io.Read ( ++ PciIo, ++ Width, ++ PCI_BAR_IDX0, ++ FieldOffset, ++ Count, ++ Buffer ++ ); ++ } else { ++ return PciIo->Mem.Read ( ++ PciIo, ++ Width, ++ PCI_BAR_IDX0, ++ FieldOffset, ++ Count, ++ Buffer ++ ); ++ } + } + + /** +@@ -197,14 +209,25 @@ VirtioPciIoWrite ( + return EFI_INVALID_PARAMETER; + } + +- return PciIo->Io.Write ( +- PciIo, +- Width, +- PCI_BAR_IDX0, +- FieldOffset, +- Count, +- &Value +- ); ++ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) { ++ return PciIo->Io.Write ( ++ PciIo, ++ Width, ++ PCI_BAR_IDX0, ++ FieldOffset, ++ Count, ++ &Value ++ ); ++ } else { ++ return PciIo->Mem.Write ( ++ PciIo, ++ Width, ++ PCI_BAR_IDX0, ++ FieldOffset, ++ Count, ++ &Value ++ ); ++ } + } + + /** +@@ -327,6 +350,7 @@ VirtioPciInit ( + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; ++ VOID *Resources; + + ASSERT (Device != NULL); + PciIo = Device->PciIo; +@@ -365,6 +389,27 @@ VirtioPciInit ( + Device->DeviceSpecificConfigurationOffset = + VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI; + ++ Status = PciIo->GetBarAttributes(PciIo, PCI_BAR_IDX0, NULL, &Resources); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) { ++ EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *Descriptor; ++ ++ Descriptor = Resources; ++ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { ++ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessMem; ++ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio MMIO BAR used.\n", __FUNCTION__)); ++ } else { ++ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo; ++ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio IO BAR used.\n", __FUNCTION__)); ++ } ++ } else { ++ DEBUG ((DEBUG_WARN, "%a: Cannot determine BAR0 type, assume IO.\n", __FUNCTION__)); ++ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo; ++ } ++ + return EFI_SUCCESS; + } + +@@ -427,6 +472,7 @@ VirtioPciDeviceBindingStart ( + { + VIRTIO_PCI_DEVICE *Device; + EFI_STATUS Status; ++ UINT64 Attributes; + + Device = (VIRTIO_PCI_DEVICE *) AllocateZeroPool (sizeof *Device); + if (Device == NULL) { +@@ -457,11 +503,18 @@ VirtioPciDeviceBindingStart ( + goto ClosePciIo; + } + ++ Status = Device->PciIo->Attributes (Device->PciIo, ++ EfiPciIoAttributeOperationSupported, ++ 0, &Attributes); ++ if (EFI_ERROR (Status)) { ++ goto ClosePciIo; ++ } ++ ++ Attributes &= (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO); + Status = Device->PciIo->Attributes ( + Device->PciIo, + EfiPciIoAttributeOperationEnable, +- (EFI_PCI_IO_ATTRIBUTE_IO | +- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER), ++ Attributes | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, + NULL + ); + if (EFI_ERROR (Status)) { +-- +2.46.0.windows.1 + diff --git a/0090-Virtio-wait-virtio-device-reset-done.patch b/0090-Virtio-wait-virtio-device-reset-done.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa097a0c7299c3c3d17aa6e18270cb9e03568745 --- /dev/null +++ b/0090-Virtio-wait-virtio-device-reset-done.patch @@ -0,0 +1,123 @@ +From 11085d9350aa63b67ed51a4d8d0010a274a190e6 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Sat, 7 Sep 2024 17:25:41 +0800 +Subject: [PATCH 2/3] Virtio: wait virtio device reset done. + +The Virtio 1.0 driver performs subsequent negotiation operations +only after the device reset operation is complete. + +Implement this in the VirtioScsiDxe and VirtioBlkDxe. + +Signed-off-by: jiangdongxu +--- + OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 21 +++++++++++++++++++++ + OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 21 +++++++++++++++++++++ + 2 files changed, 42 insertions(+) + +diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +index 06b9859..70fc8dd 100644 +--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c ++++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +@@ -28,6 +28,9 @@ + + #include "VirtioBlk.h" + ++#define MAX_RETRY_TIMES 1000 ++#define DEVICE_WAIT_INTVL 1000 ++ + /** + + Convenience macros to read and write region 0 IO space elements of the +@@ -723,6 +726,10 @@ VirtioBlkInit ( + UINT32 OptIoSize; + UINT16 QueueSize; + UINT64 RingBaseShift; ++ UINT8 DevStat; ++ UINT16 RetryTimes; ++ ++ RetryTimes = MAX_RETRY_TIMES; + + PhysicalBlockExp = 0; + AlignmentOffset = 0; +@@ -737,12 +744,26 @@ VirtioBlkInit ( + goto Failed; + } + ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ while (DevStat != NextDevStat && RetryTimes) { ++ gBS->Stall(DEVICE_WAIT_INTVL); ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ RetryTimes--; ++ } ++ + NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); + if (EFI_ERROR (Status)) { + goto Failed; + } + ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ while (DevStat != NextDevStat && RetryTimes) { ++ gBS->Stall(DEVICE_WAIT_INTVL); ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ RetryTimes--; ++ } ++ + NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); + if (EFI_ERROR (Status)) { +diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +index 935d154..0b9ad60 100644 +--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c ++++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +@@ -43,6 +43,9 @@ + + #include "VirtioScsi.h" + ++#define MAX_RETRY_TIMES 1000 ++#define DEVICE_WAIT_INTVL 1000 ++ + /** + + Convenience macros to read and write configuration elements of the +@@ -930,6 +933,10 @@ VirtioScsiInit ( + UINT16 MaxChannel; // for validation only + UINT32 NumQueues; // for validation only + UINT16 QueueSize; ++ UINT8 DevStat; ++ UINT16 RetryTimes; ++ ++ RetryTimes = MAX_RETRY_TIMES; + + // + // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence. +@@ -940,12 +947,26 @@ VirtioScsiInit ( + goto Failed; + } + ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ while (DevStat != NextDevStat && RetryTimes) { ++ gBS->Stall(DEVICE_WAIT_INTVL); ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ RetryTimes--; ++ } ++ + NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); + if (EFI_ERROR (Status)) { + goto Failed; + } + ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ while (DevStat != NextDevStat && RetryTimes) { ++ gBS->Stall(DEVICE_WAIT_INTVL); ++ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat); ++ RetryTimes--; ++ } ++ + NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); + if (EFI_ERROR (Status)) { +-- +2.46.0.windows.1 + diff --git a/0091-VirtioBlk-split-large-IO-according-to-segment_size_m.patch b/0091-VirtioBlk-split-large-IO-according-to-segment_size_m.patch new file mode 100644 index 0000000000000000000000000000000000000000..60d33833789161322dbe664deddea0f376dd1ccf --- /dev/null +++ b/0091-VirtioBlk-split-large-IO-according-to-segment_size_m.patch @@ -0,0 +1,249 @@ +From 58abc1e5f9c374f2b26634b7f41def82ae3233f6 Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Sat, 7 Sep 2024 17:30:28 +0800 +Subject: [PATCH 3/3] VirtioBlk: split large IO according to segment_size_max + +When the VirtioBlk device is initialized, the value of SegmentSizeMax +is obtained based on the feature capability. Then delivere the requests + based on the value of SegmentSizeMax. + +Signed-off-by: jiangdongxu +--- + MdePkg/Include/Protocol/BlockIo.h | 10 ++ + OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 147 +++++++++++++++++++++--------- + 2 files changed, 116 insertions(+), 41 deletions(-) + +diff --git a/MdePkg/Include/Protocol/BlockIo.h b/MdePkg/Include/Protocol/BlockIo.h +index 3bd7688..30b20d0 100644 +--- a/MdePkg/Include/Protocol/BlockIo.h ++++ b/MdePkg/Include/Protocol/BlockIo.h +@@ -197,6 +197,16 @@ typedef struct { + /// granularity as a number of logical blocks. + /// + UINT32 OptimalTransferLengthGranularity; ++ ++ /// ++ /// Maximum size of any single segment ++ /// ++ UINT32 MaxSegmentSize; ++ ++ /// ++ /// Maximum number of segments in a request ++ /// ++ UINT32 MaxSegments; + } EFI_BLOCK_IO_MEDIA; + + #define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000 +diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +index 70fc8dd..d13cb37 100644 +--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c ++++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +@@ -31,6 +31,8 @@ + #define MAX_RETRY_TIMES 1000 + #define DEVICE_WAIT_INTVL 1000 + ++#define DEFAULT_MAX_SEGMENTS 32 ++ + /** + + Convenience macros to read and write region 0 IO space elements of the +@@ -457,6 +459,67 @@ FreeHostStatusBuffer: + return Status; + } + ++STATIC ++EFI_STATUS ++EFIAPI ++VirtioBlkReadWriteBlocks ( ++ IN EFI_BLOCK_IO_PROTOCOL *This, ++ IN UINT32 MediaId, ++ IN EFI_LBA Lba, ++ IN UINTN BufferSize, ++ IN OUT VOID *Buffer, ++ IN BOOLEAN RequestIsWrite ++ ) ++{ ++ VBLK_DEV *Dev; ++ EFI_STATUS Status; ++ UINT32 SizeMax; ++ ++ if (BufferSize == 0) { ++ return EFI_SUCCESS; ++ } ++ ++ Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); ++ Status = VerifyReadWriteRequest ( ++ &Dev->BlockIoMedia, ++ Lba, ++ BufferSize, ++ RequestIsWrite ++ ); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ SizeMax = Dev->BlockIoMedia.MaxSegmentSize; ++ while (BufferSize >= SizeMax) { ++ Status = SynchronousRequest ( ++ Dev, ++ Lba, ++ SizeMax, ++ Buffer, ++ RequestIsWrite ++ ); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ Lba += SizeMax / Dev->BlockIoMedia.BlockSize; ++ BufferSize -= SizeMax; ++ Buffer = (CHAR8 *)Buffer + SizeMax; ++ } ++ ++ if (BufferSize == 0) { ++ return EFI_SUCCESS; ++ } ++ ++ return SynchronousRequest ( ++ Dev, ++ Lba, ++ BufferSize, ++ Buffer, ++ RequestIsWrite ++ ); ++} + + /** + +@@ -486,30 +549,13 @@ VirtioBlkReadBlocks ( + OUT VOID *Buffer + ) + { +- VBLK_DEV *Dev; +- EFI_STATUS Status; +- +- if (BufferSize == 0) { +- return EFI_SUCCESS; +- } +- +- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); +- Status = VerifyReadWriteRequest ( +- &Dev->BlockIoMedia, +- Lba, +- BufferSize, +- FALSE // RequestIsWrite +- ); +- if (EFI_ERROR (Status)) { +- return Status; +- } +- +- return SynchronousRequest ( +- Dev, ++ return VirtioBlkReadWriteBlocks( ++ This, ++ MediaId, + Lba, + BufferSize, + Buffer, +- FALSE // RequestIsWrite ++ FALSE // RequestIsRead + ); + } + +@@ -541,26 +587,9 @@ VirtioBlkWriteBlocks ( + IN VOID *Buffer + ) + { +- VBLK_DEV *Dev; +- EFI_STATUS Status; +- +- if (BufferSize == 0) { +- return EFI_SUCCESS; +- } +- +- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); +- Status = VerifyReadWriteRequest ( +- &Dev->BlockIoMedia, +- Lba, +- BufferSize, +- TRUE // RequestIsWrite +- ); +- if (EFI_ERROR (Status)) { +- return Status; +- } +- +- return SynchronousRequest ( +- Dev, ++ return VirtioBlkReadWriteBlocks( ++ This, ++ MediaId, + Lba, + BufferSize, + Buffer, +@@ -718,6 +747,8 @@ VirtioBlkInit ( + UINT8 NextDevStat; + EFI_STATUS Status; + ++ UINT32 MaxSegmentSize; ++ UINT32 MaxSegments; + UINT64 Features; + UINT64 NumSectors; + UINT32 BlockSize; +@@ -814,6 +845,36 @@ VirtioBlkInit ( + BlockSize = 512; + } + ++ if (Features & VIRTIO_BLK_F_SIZE_MAX) { ++ Status = VIRTIO_CFG_READ (Dev, SizeMax, &MaxSegmentSize); ++ if (EFI_ERROR (Status)) { ++ goto Failed; ++ } ++ if (MaxSegmentSize == 0) { ++ // ++ // We need at least one 4KB page. ++ // ++ MaxSegmentSize = SIZE_4KB; ++ } ++ } else { ++ MaxSegmentSize = SIZE_512KB; ++ } ++ ++ if (Features & VIRTIO_BLK_F_SEG_MAX) { ++ Status = VIRTIO_CFG_READ (Dev, SegMax, &MaxSegments); ++ if (EFI_ERROR (Status)) { ++ goto Failed; ++ } ++ if (MaxSegments == 0) { ++ // ++ // We need at least one SG element, whatever they say. ++ // ++ MaxSegments = 1; ++ } ++ } else { ++ MaxSegments = DEFAULT_MAX_SEGMENTS; ++ } ++ + if (Features & VIRTIO_BLK_F_TOPOLOGY) { + Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp, + &PhysicalBlockExp); +@@ -949,6 +1010,8 @@ VirtioBlkInit ( + Dev->BlockIoMedia.ReadOnly = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0); + Dev->BlockIoMedia.WriteCaching = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0); + Dev->BlockIoMedia.BlockSize = BlockSize; ++ Dev->BlockIoMedia.MaxSegments = MaxSegments; ++ Dev->BlockIoMedia.MaxSegmentSize = MaxSegmentSize; + Dev->BlockIoMedia.IoAlign = 0; + Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors, + BlockSize / 512) - 1; +@@ -956,6 +1019,8 @@ VirtioBlkInit ( + DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n", + __FUNCTION__, Dev->BlockIoMedia.BlockSize, + Dev->BlockIoMedia.LastBlock + 1)); ++ DEBUG ((DEBUG_INFO, "%a: MaxSegments=0x%x[B] MaxSegmentSize=0x%x[B]\n", ++ __FUNCTION__, Dev->BlockIoMedia.MaxSegments, Dev->BlockIoMedia.MaxSegmentSize)); + + if (Features & VIRTIO_BLK_F_TOPOLOGY) { + Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; +-- +2.46.0.windows.1 + diff --git a/0092-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch b/0092-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch new file mode 100644 index 0000000000000000000000000000000000000000..82620e66a208e4ad58eedbedcad8a2231645abe7 --- /dev/null +++ b/0092-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch @@ -0,0 +1,32 @@ +From c95233b8525ca6828921affd1496146cff262e65 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Fri, 27 Sep 2024 12:08:55 -0700 +Subject: [PATCH] MdePkg: Fix overflow issue in BasePeCoffLib + +The RelocDir->Size is a UINT32 value, and RelocDir->VirtualAddress is +also a UINT32 value. The current code does not check for overflow when +adding RelocDir->Size to RelocDir->VirtualAddress. This patch adds a +check to ensure that the addition does not overflow. + +Signed-off-by: Doug Flick +Authored-by: sriraamx gobichettipalayam +--- + MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +index 1102833..7fa4714 100644 +--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c ++++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +@@ -991,7 +991,7 @@ PeCoffLoaderRelocateImage ( + RelocDir = &Hdr.Te->DataDirectory[0]; + } + +- if ((RelocDir != NULL) && (RelocDir->Size > 0)) { ++ if ((RelocDir != NULL) && (RelocDir->Size > 0) && (RelocDir->Size - 1 < MAX_UINT32 - RelocDir->VirtualAddress)) { + RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset); + RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, + RelocDir->VirtualAddress + RelocDir->Size - 1, +-- +2.43.0 + diff --git a/0093-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236-Rela.patch b/0093-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236-Rela.patch new file mode 100644 index 0000000000000000000000000000000000000000..20c8b85fa0616603741139cd5365ceb6ea93e071 --- /dev/null +++ b/0093-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236-Rela.patch @@ -0,0 +1,87 @@ +From 780535ba9e0d2a81db5ae17374fdfa8cb5e80d91 Mon Sep 17 00:00:00 2001 +From: ShenYage +Date: Fri, 28 Feb 2025 16:04:22 +0800 +Subject: [PATCH 1/2] NetworkPkg: TcpDxe: SECURITY PATCH CVE-2023-45236 Relared + Patch + +BUG: Tianocore's EDK2 TCP implementation generates ISNs using fixed +increments from a fixed base value and thus is uceptible to TCP session injection +and session hijack attacks. + +This commit is a patch for CVE-2023-45236. Generates ISNs using RngLib to get a high-quality random number. + +Signed-off-by: ShenYage +--- + NetworkPkg/TcpDxe/TcpDxe.inf | 1 + + NetworkPkg/TcpDxe/TcpMain.h | 1 + + NetworkPkg/TcpDxe/TcpMisc.c | 9 ++++++++- + NetworkPkg/TcpDxe/TcpTimer.c | 7 ++++++- + 4 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf +index c0acbdc..9281f90 100644 +--- a/NetworkPkg/TcpDxe/TcpDxe.inf ++++ b/NetworkPkg/TcpDxe/TcpDxe.inf +@@ -67,6 +67,7 @@ + DpcLib + NetLib + IpIoLib ++ RngLib + + + [Protocols] +diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h +index 35f12a1..ef35fa7 100644 +--- a/NetworkPkg/TcpDxe/TcpMain.h ++++ b/NetworkPkg/TcpDxe/TcpMain.h +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + #include "Socket.h" + #include "TcpProto.h" +diff --git a/NetworkPkg/TcpDxe/TcpMisc.c b/NetworkPkg/TcpDxe/TcpMisc.c +index 73ed33d..1249ae6 100644 +--- a/NetworkPkg/TcpDxe/TcpMisc.c ++++ b/NetworkPkg/TcpDxe/TcpMisc.c +@@ -522,7 +522,14 @@ TcpGetIss ( + VOID + ) + { +- mTcpGlobalIss += TCP_ISS_INCREMENT_1; ++ UINT32 RandomVal; ++ ++ if (GetRandomNumber32(&RandomVal)) { ++ mTcpGlobalIss += RandomVal; ++ } else { ++ mTcpGlobalIss += TCP_ISS_INCREMENT_1; ++ } ++ + return mTcpGlobalIss; + } + +diff --git a/NetworkPkg/TcpDxe/TcpTimer.c b/NetworkPkg/TcpDxe/TcpTimer.c +index 106d947..6a9dab3 100644 +--- a/NetworkPkg/TcpDxe/TcpTimer.c ++++ b/NetworkPkg/TcpDxe/TcpTimer.c +@@ -495,9 +495,14 @@ TcpTickingDpc ( + LIST_ENTRY *Next; + TCP_CB *Tcb; + INT16 Index; ++ UINT32 RandomVal; + + mTcpTick++; +- mTcpGlobalIss += TCP_ISS_INCREMENT_2; ++ if (GetRandomNumber32(&RandomVal)) { ++ mTcpGlobalIss += RandomVal; ++ } else { ++ mTcpGlobalIss += TCP_ISS_INCREMENT_2; ++ } + + // + // Don't use LIST_FOR_EACH, which isn't delete safe. +-- +2.33.0 + diff --git a/0094-NetworkPkg-DxeNetLib-SECURITY-PATCH-CVE-2023-45237-R.patch b/0094-NetworkPkg-DxeNetLib-SECURITY-PATCH-CVE-2023-45237-R.patch new file mode 100644 index 0000000000000000000000000000000000000000..e025fbd5f63da567eeab6ce87f4cfe119bae1a3c --- /dev/null +++ b/0094-NetworkPkg-DxeNetLib-SECURITY-PATCH-CVE-2023-45237-R.patch @@ -0,0 +1,69 @@ +From cc8e518d327b7ee851e28060b95a06edfcfc4400 Mon Sep 17 00:00:00 2001 +From: ShenYage +Date: Fri, 28 Feb 2025 16:18:39 +0800 +Subject: [PATCH 2/2] NetworkPkg: DxeNetLib: SECURITY PATCH CVE-2023-45237 + Relared Patch + +This commit is a patch for CVE-2023-45237. Using RngLib to generate a stronger pseudoRandom number for NetRandomInitSeed(). + +Signed-off-by: ShenYage +--- + NetworkPkg/Library/DxeNetLib/DxeNetLib.c | 22 ++++++++++++++-------- + NetworkPkg/Library/DxeNetLib/DxeNetLib.inf | 1 + + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +index 2a555a7..f0b5ed8 100644 +--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c ++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +@@ -31,6 +31,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + #include ++#include + + #define NIC_ITEM_CONFIG_SIZE (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE) + #define DEFAULT_ZERO_START ((UINTN) ~0) +@@ -908,14 +909,19 @@ NetRandomInitSeed ( + EFI_TIME Time; + UINT32 Seed; + UINT64 MonotonicCount; +- +- gRT->GetTime (&Time, NULL); +- Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second); +- Seed ^= Time.Nanosecond; +- Seed ^= Time.Year << 7; +- +- gBS->GetNextMonotonicCount (&MonotonicCount); +- Seed += (UINT32) MonotonicCount; ++ UINT32 RandomVal; ++ ++ if (GetRandomNumber32(&RandomVal)) { ++ Seed = RandomVal; ++ } else { ++ gRT->GetTime (&Time, NULL); ++ Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second); ++ Seed ^= Time.Nanosecond; ++ Seed ^= Time.Year << 7; ++ ++ gBS->GetNextMonotonicCount (&MonotonicCount); ++ Seed += (UINT32) MonotonicCount; ++ } + + return Seed; + } +diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +index 8145d25..ce90aa5 100644 +--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf ++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +@@ -43,6 +43,7 @@ + MemoryAllocationLib + DevicePathLib + PrintLib ++ RngLib + + + [Guids] +-- +2.33.0 + diff --git a/0095-Fix-timing-side-channel-CVE-2024-13176.patch b/0095-Fix-timing-side-channel-CVE-2024-13176.patch new file mode 100644 index 0000000000000000000000000000000000000000..014bf18fc114ca1d3adebc38ad6f760092d38363 --- /dev/null +++ b/0095-Fix-timing-side-channel-CVE-2024-13176.patch @@ -0,0 +1,121 @@ +From 364614adb972bc64e4174031a026d14896b22463 Mon Sep 17 00:00:00 2001 +From: hy <12444214+dhjgty@user.noreply.gitee.com> +Date: Wed, 26 Feb 2025 01:13:34 +0800 +Subject: [PATCH] Fix timing side-channel in ECDSA signature computation There + is a timing signal of around 300 nanoseconds when the top word of the + inverted ECDSA nonce value is zero. This can happen with significant + probability only for some of the supported elliptic curves. In particular the + NIST P-521 curve is affected. To be able to measure this leak, the attacker + process must either be located in the same physical computer or must have a + very fast network connection with low latency. + +Attacks on ECDSA nonce are also known as Minerva attack. + +Fixes CVE-2024-13176 + +Reviewed-by: Tim Hudson +Reviewed-by: Neil Horman +Reviewed-by: Paul Dale +--- + .../OpensslLib/openssl/crypto/bn/bn_exp.c | 21 +++++++++++++------ + .../OpensslLib/openssl/crypto/ec/ec_lib.c | 8 +++---- + .../OpensslLib/openssl/include/crypto/bn.h | 3 +++ + 3 files changed, 22 insertions(+), 10 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c +index 9531acf..58b8058 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c +@@ -589,7 +589,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, + * out by Colin Percival, + * http://www.daemonology.net/hyperthreading-considered-harmful/) + */ +-int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ++int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) + { +@@ -606,10 +606,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + unsigned int t4 = 0; + #endif + +- bn_check_top(a); +- bn_check_top(p); +- bn_check_top(m); +- + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; +@@ -1112,7 +1108,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + goto err; + } else + #endif +- if (!BN_from_montgomery(rr, &tmp, mont, ctx)) ++ if (!bn_from_mont_fixed_top(rr, &tmp, mont, ctx)) + goto err; + ret = 1; + err: +@@ -1126,6 +1122,19 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + return ret; + } + ++int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ++ const BIGNUM *m, BN_CTX *ctx, ++ BN_MONT_CTX *in_mont) ++{ ++ bn_check_top(a); ++ bn_check_top(p); ++ bn_check_top(m); ++ if (!bn_mod_exp_mont_fixed_top(rr, a, p, m, ctx, in_mont)) ++ return 0; ++ bn_correct_top(rr); ++ return 1; ++} ++ + int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) + { +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c +index 3554ada..0e0b643 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c +@@ -12,7 +12,7 @@ + + #include + #include +- ++#include "crypto/bn.h" + #include "ec_local.h" + + /* functions for EC_GROUP objects */ +@@ -1154,10 +1154,10 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, + if (!BN_sub(e, group->order, e)) + goto err; + /*- +- * Exponent e is public. +- * No need for scatter-gather or BN_FLG_CONSTTIME. ++ * Although the exponent is public we want the result to be ++ * fixed top. + */ +- if (!BN_mod_exp_mont(r, x, e, group->order, ctx, group->mont_data)) ++ if (!bn_mod_exp_mont_fixed_top(r, x, e, group->order, ctx, group->mont_data)) + goto err; + + ret = 1; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h +index b5f36fb..12cb709 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/crypto/bn.h +@@ -72,6 +72,9 @@ int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words); + */ + int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); ++int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ++ const BIGNUM *m, BN_CTX *ctx, ++ BN_MONT_CTX *in_mont); + int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); + int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, +-- +2.33.0 + diff --git a/0096-Free-the-read-buffers-CVE-2024-4741.patch b/0096-Free-the-read-buffers-CVE-2024-4741.patch new file mode 100644 index 0000000000000000000000000000000000000000..43730faf6d5a0873bff07c8b9c63f045fbd2544f --- /dev/null +++ b/0096-Free-the-read-buffers-CVE-2024-4741.patch @@ -0,0 +1,70 @@ +From f40c84cc031796e0469c6294abbf945455084627 Mon Sep 17 00:00:00 2001 +From: hy <12444214+dhjgty@user.noreply.gitee.com> +Date: Mon, 24 Feb 2025 22:50:29 +0800 +Subject: [PATCH] fix CVE-2024-4741 +Only free the read buffers if we're not using them +If we're part way through processing a record, or the application has +not released all the records then we should not free our buffer because +they are still needed. + +CVE-2024-4741 + +Reviewed-by: Tomas Mraz +Reviewed-by: Neil Horman +Reviewed-by: Matt Caswell + +--- + .../Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c | 9 +++++++++ + CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h | 1 + + CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c | 3 +++ + 3 files changed, 13 insertions(+) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c +index 3baf8207..99602b6b 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c +@@ -81,6 +81,15 @@ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl) + return SSL3_BUFFER_get_left(&rl->rbuf) != 0; + } + ++int RECORD_LAYER_data_present(const RECORD_LAYER *rl) ++{ ++ if (rl->rstate == SSL_ST_READ_BODY) ++ return 1; ++ if (RECORD_LAYER_processed_read_pending(rl)) ++ return 1; ++ return 0; ++} ++ + /* Checks if we have decrypted unread record data pending */ + int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl) + { +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h b/CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h +index 234656bf..b60f71c8 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h +@@ -205,6 +205,7 @@ void RECORD_LAYER_release(RECORD_LAYER *rl); + int RECORD_LAYER_read_pending(const RECORD_LAYER *rl); + int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl); + int RECORD_LAYER_write_pending(const RECORD_LAYER *rl); ++int RECORD_LAYER_data_present(const RECORD_LAYER *rl); + void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl); + void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl); + int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl); +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +index 5d57f5d2..ac4ae41e 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +@@ -5489,6 +5489,9 @@ int SSL_free_buffers(SSL *ssl) + if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl)) + return 0; + ++ if (RECORD_LAYER_data_present(rl)) ++ return 0; ++ + RECORD_LAYER_release(rl); + return 1; + } +-- +2.33.0 + diff --git a/0097-Harden-BN_GF2m_poly2arr-against-misuse.patch b/0097-Harden-BN_GF2m_poly2arr-against-misuse.patch new file mode 100644 index 0000000000000000000000000000000000000000..037d69273c5a49441ee823059abf9fe37dee6a1a --- /dev/null +++ b/0097-Harden-BN_GF2m_poly2arr-against-misuse.patch @@ -0,0 +1,187 @@ +From 2a0fa58af18f2ab5435ee2cefa6a02cacfb18818 Mon Sep 17 00:00:00 2001 +From: hy <941973499@qq.com> +Date: Fri, 28 Mar 2025 22:48:57 +0800 +Subject: [PATCH] Harden BN_GF2m_poly2arr against misuse. The + BN_GF2m_poly2arr() function converts characteristic-2 field (GF_{2^m}) Galois + polynomials from a representation as a BIGNUM bitmask, to a compact array + with just the exponents of the non-zero terms. + +These polynomials are then used in BN_GF2m_mod_arr() to perform modular +reduction. A precondition of calling BN_GF2m_mod_arr() is that the +polynomial must have a non-zero constant term (i.e. the array has `0` as +its final element). + +Internally, callers of BN_GF2m_poly2arr() did not verify that +precondition, and binary EC curve parameters with an invalid polynomial +could lead to out of bounds memory reads and writes in BN_GF2m_mod_arr(). + +The precondition is always true for polynomials that arise from the +standard form of EC parameters for characteristic-two fields (X9.62). +See the "Finite Field Identification" section of: + + https://www.itu.int/ITU-T/formal-language/itu-t/x/x894/2018-cor1/ANSI-X9-62.html + +The OpenSSL GF(2^m) code supports only the trinomial and pentanomial +basis X9.62 forms. + +This commit updates BN_GF2m_poly2arr() to return `0` (failure) when +the constant term is zero (i.e. the input bitmask BIGNUM is not odd). + +Additionally, the return value is made unambiguous when there is not +enough space to also pad the array with a final `-1` sentinel value. +The return value is now always the number of elements (including the +final `-1`) that would be filled when the output array is sufficiently +large. Previously the same count was returned both when the array has +just enough room for the final `-1` and when it had only enough space +for non-sentinel values. + +Finally, BN_GF2m_poly2arr() is updated to reject polynomials whose +degree exceeds `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against +CPU exhausition attacks via excessively large inputs. + +The above issues do not arise in processing X.509 certificates. These +generally have EC keys from "named curves", and RFC5840 (Section 2.1.1) +disallows explicit EC parameters. The TLS code in OpenSSL enforces this +constraint only after the certificate is decoded, but, even if explicit +parameters are specified, they are in X9.62 form, which cannot represent +problem values as noted above. + +Initially reported as oss-fuzz issue 71623. +--- + .../OpensslLib/openssl/crypto/bn/bn_gf2m.c | 28 +++++++--- + .../openssl/test/ec_internal_test.c | 51 +++++++++++++++++++ + 2 files changed, 71 insertions(+), 8 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c +index 304c2ea0..65e9958c 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c +@@ -15,6 +15,7 @@ + #include "bn_local.h" + + #ifndef OPENSSL_NO_EC2M ++# include + + /* + * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should +@@ -1134,16 +1135,26 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + /* + * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i * + * x^i) into an array of integers corresponding to the bits with non-zero +- * coefficient. Array is terminated with -1. Up to max elements of the array +- * will be filled. Return value is total number of array elements that would +- * be filled if array was large enough. ++ * coefficient. The array is intended to be suitable for use with ++ * `BN_GF2m_mod_arr()`, and so the constant term of the polynomial must not be ++ * zero. This translates to a requirement that the input BIGNUM `a` is odd. ++ * ++ * Given sufficient room, the array is terminated with -1. Up to max elements ++ * of the array will be filled. ++ * ++ * The return value is total number of array elements that would be filled if ++ * array was large enough, including the terminating `-1`. It is `0` when `a` ++ * is not odd or the constant term is zero contrary to requirement. ++ * ++ * The return value is also `0` when the leading exponent exceeds ++ * `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against CPU exhaustion attacks, + */ + int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) + { + int i, j, k = 0; + BN_ULONG mask; + +- if (BN_is_zero(a)) ++ if (!BN_is_odd(a)) + return 0; + + for (i = a->top - 1; i >= 0; i--) { +@@ -1161,12 +1172,13 @@ int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) + } + } + +- if (k < max) { ++ if (k > 0 && p[0] > OPENSSL_ECC_MAX_FIELD_BITS) ++ return 0; ++ ++ if (k < max) + p[k] = -1; +- k++; +- } + +- return k; ++ return k + 1; + } + + /* +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ec_internal_test.c b/CryptoPkg/Library/OpensslLib/openssl/test/ec_internal_test.c +index 8c2cd056..484cbb2a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ec_internal_test.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ec_internal_test.c +@@ -155,6 +155,56 @@ static int field_tests_ecp_mont(void) + } + + #ifndef OPENSSL_NO_EC2M ++/* Test that decoding of invalid GF2m field parameters fails. */ ++ static int ec2m_field_sanity(void) ++ { ++ int ret = 0; ++ BN_CTX *ctx = BN_CTX_new(); ++ BIGNUM *p, *a, *b; ++ EC_GROUP *group1 = NULL, *group2 = NULL, *group3 = NULL; ++ ++ TEST_info("Testing GF2m hardening\n"); ++ ++ BN_CTX_start(ctx); ++ p = BN_CTX_get(ctx); ++ a = BN_CTX_get(ctx); ++ if (!TEST_ptr(b = BN_CTX_get(ctx)) ++ || !TEST_true(BN_one(a)) ++ || !TEST_true(BN_one(b))) ++ goto out; ++ ++ /* Even pentanomial value should be rejected */ ++ if (!TEST_true(BN_set_word(p, 0xf2))) ++ goto out; ++ if (!TEST_ptr_null(group1 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) ++ TEST_error("Zero constant term accepted in GF2m polynomial"); ++ ++ /* Odd hexanomial should also be rejected */ ++ if (!TEST_true(BN_set_word(p, 0xf3))) ++ goto out; ++ if (!TEST_ptr_null(group2 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) ++ TEST_error("Hexanomial accepted as GF2m polynomial"); ++ ++ /* Excessive polynomial degree should also be rejected */ ++ if (!TEST_true(BN_set_word(p, 0x71)) ++ || !TEST_true(BN_set_bit(p, OPENSSL_ECC_MAX_FIELD_BITS + 1))) ++ goto out; ++ if (!TEST_ptr_null(group3 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) ++ TEST_error("GF2m polynomial degree > %d accepted", ++ OPENSSL_ECC_MAX_FIELD_BITS); ++ ++ ret = group1 == NULL && group2 == NULL && group3 == NULL; ++ ++ out: ++ EC_GROUP_free(group1); ++ EC_GROUP_free(group2); ++ EC_GROUP_free(group3); ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ ++ return ret; ++ } ++ + /* test EC_GF2m_simple_method directly */ + static int field_tests_ec2_simple(void) + { +@@ -443,6 +493,7 @@ int setup_tests(void) + ADD_TEST(field_tests_ecp_simple); + ADD_TEST(field_tests_ecp_mont); + #ifndef OPENSSL_NO_EC2M ++ ADD_TEST(ec2m_field_sanity); + ADD_TEST(field_tests_ec2_simple); + #endif + ADD_ALL_TESTS(field_tests_default, crv_len); +-- +2.33.0 + diff --git a/0098-SecurityPkg-Out-of-bound-read-in-HashPeImageByType.patch b/0098-SecurityPkg-Out-of-bound-read-in-HashPeImageByType.patch new file mode 100644 index 0000000000000000000000000000000000000000..23a5dd13bb08022e36671e105b549449e1b43185 --- /dev/null +++ b/0098-SecurityPkg-Out-of-bound-read-in-HashPeImageByType.patch @@ -0,0 +1,185 @@ +From ce37675db65a37c5a746d6ba6e3755f0feefc64c Mon Sep 17 00:00:00 2001 +From: hy <941973499@qq.com> +Date: Sun, 27 Apr 2025 20:54:06 +0800 +Subject: [PATCH] SecurityPkg: Out of bound read in HashPeImageByType() In + HashPeImageByType(), the hash of PE/COFF image is calculated. This function + may get untrusted input. + +Inside this function, the following code verifies the loaded image has +the correct format, by reading the second byte of the buffer. + +```c + if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { + ... + } +``` + +The input image is not trusted and that may not have the second byte to +read. So this poses an out of bound read error. + +With below fix we are assuring that we don't do out of bound read. i.e, +we make sure that AuthDataSize is greater than 1. + +```c + if (AuthDataSize > 1 + && (*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE){ + ... + } +``` + +AuthDataSize size is verified before reading the second byte. +So if AuthDataSize is less than 2, the second byte will not be read, and +the out of bound read situation won't occur. + +Tested the patch on real platform with and without TPM connected and +verified image is booting fine. + +Authored-by: Raj AlwinX Selvaraj +Signed-off-by: Doug Flick +--- + .../DxeImageVerificationLib.c | 37 ++++++++++--------- + SecurityPkg/SecurityFixes.yaml | 15 ++++++++ + .../SecureBootConfigImpl.c | 37 +++++++++++-------- + 3 files changed, 55 insertions(+), 34 deletions(-) + +diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +index d8b7b15..6060f93 100644 +--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c ++++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +@@ -607,6 +607,7 @@ Done: + @param[in] AuthDataSize Size of the Authenticode Signature in bytes. + + @retval EFI_UNSUPPORTED Hash algorithm is not supported. ++ @retval EFI_BAD_BUFFER_SIZE AuthData provided is invalid size. + @retval EFI_SUCCESS Hash successfully. + + **/ +@@ -618,28 +619,28 @@ HashPeImageByType ( + { + UINT8 Index; + +- for (Index = 0; Index < HASHALG_MAX; Index++) { ++ // ++ // Check the Hash algorithm in PE/COFF Authenticode. ++ // According to PKCS#7 Definition: ++ // SignedData ::= SEQUENCE { ++ // version Version, ++ // digestAlgorithms DigestAlgorithmIdentifiers, ++ // contentInfo ContentInfo, ++ // .... } ++ // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing ++ // This field has the fixed offset (+32) in final Authenticode ASN.1 data. ++ // Fixed offset (+32) is calculated based on two bytes of length encoding. ++ // ++ if ((AuthDataSize > 1) && ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)) { + // +- // Check the Hash algorithm in PE/COFF Authenticode. +- // According to PKCS#7 Definition: +- // SignedData ::= SEQUENCE { +- // version Version, +- // digestAlgorithms DigestAlgorithmIdentifiers, +- // contentInfo ContentInfo, +- // .... } +- // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing +- // This field has the fixed offset (+32) in final Authenticode ASN.1 data. +- // Fixed offset (+32) is calculated based on two bytes of length encoding. ++ // Only support two bytes of Long Form of Length Encoding. + // +- if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { +- // +- // Only support two bytes of Long Form of Length Encoding. +- // +- continue; +- } ++ return EFI_BAD_BUFFER_SIZE; ++ } + ++ for (Index = 0; Index < HASHALG_MAX; Index++) { + if (AuthDataSize < 32 + mHash[Index].OidLength) { +- return EFI_UNSUPPORTED; ++ continue; + } + + if (CompareMem (AuthData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) { +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index ceaaa25..0b24844 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -34,3 +34,18 @@ CVE_2022_36764: + - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 ++CVE_2024_38797: ++ commit-titles: ++ - "SecurityPkg: Out of bound read in HashPeImageByType()" ++ - "SecurityPkg: Improving HashPeImageByType () logic" ++ - "SecurityPkg: Improving SecureBootConfigImpl:HashPeImageByType () logic" ++ cve: CVE-2024-38797 ++ date_reported: 2024-06-04 12:00 UTC ++ description: Out of bound read in HashPeImageByType() ++ note: ++ files_impacted: ++ - SecurityPkg\Library\DxeImageVerificationLib\DxeImageVerificationLib.c ++ - SecurityPkg\VariableAuthenticated\SecureBootConfigDxe\SecureBootConfigImpl.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=2214 ++ - https://github.com/tianocore/edk2/security/advisories/GHSA-4wjw-6xmf-44xf +diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +index 4f01a2e..a363ab2 100644 +--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c ++++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +@@ -2063,30 +2063,35 @@ HashPeImageByType ( + { + UINT8 Index; + WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; ++ UINT32 PkcsCertSize; + + PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *) (mImageBase + mSecDataDir->Offset); ++ PkcsCertSize = mSecDataDir->SizeOfCert; + +- for (Index = 0; Index < HASHALG_MAX; Index++) { ++ // ++ // Check the Hash algorithm in PE/COFF Authenticode. ++ // According to PKCS#7 Definition: ++ // SignedData ::= SEQUENCE { ++ // version Version, ++ // digestAlgorithms DigestAlgorithmIdentifiers, ++ // contentInfo ContentInfo, ++ // .... } ++ // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing ++ // This field has the fixed offset (+32) in final Authenticode ASN.1 data. ++ // Fixed offset (+32) is calculated based on two bytes of length encoding. ++ // ++ if ((PkcsCertSize > 1) && ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)) { + // +- // Check the Hash algorithm in PE/COFF Authenticode. +- // According to PKCS#7 Definition: +- // SignedData ::= SEQUENCE { +- // version Version, +- // digestAlgorithms DigestAlgorithmIdentifiers, +- // contentInfo ContentInfo, +- // .... } +- // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing +- // This field has the fixed offset (+32) in final Authenticode ASN.1 data. +- // Fixed offset (+32) is calculated based on two bytes of length encoding. ++ // Only support two bytes of Long Form of Length Encoding. + // +- if ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { +- // +- // Only support two bytes of Long Form of Length Encoding. +- // ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ for (Index = 0; Index < HASHALG_MAX; Index++) { ++ if (PkcsCertSize < 32 + mHash[Index].OidLength) { + continue; + } + +- // + if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) { + break; + } +-- +2.33.0 + diff --git a/0099-CryptoPkg-Make-DH_check_pub_key-and.patch b/0099-CryptoPkg-Make-DH_check_pub_key-and.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6ce82c39c3ebcf37de6495eab9cd91c9b22e613 --- /dev/null +++ b/0099-CryptoPkg-Make-DH_check_pub_key-and.patch @@ -0,0 +1,143 @@ +From 318938b1e4db5d7c5f633ba6b915595fcb34db49 Mon Sep 17 00:00:00 2001 +From: TL <1045523086@qq.com> +Date: Fri, 27 Jun 2025 09:53:49 +0800 +Subject: [PATCH] CryptoPkg: Make DH_check_pub_key() and DH_generate_key() + safer yet + +We already check for an excessively large P in DH_generate_key(), but not in +DH_check_pub_key(), and none of them check for an excessively large Q. + +This change adds all the missing excessive size checks of P and Q. + +It's to be noted that behaviours surrounding excessively sized P and Q +differ. DH_check() raises an error on the excessively sized P, but only +sets a flag for the excessively sized Q. This behaviour is mimicked in +DH_check_pub_key(). + +Reviewed-by: Tomas Mraz +Reviewed-by: Matt Caswell +Reviewed-by: Hugo Landau +--- + .../Library/OpensslLib/openssl/crypto/dh/dh_check.c | 13 +++++++++++++ + .../Library/OpensslLib/openssl/crypto/dh/dh_err.c | 1 + + .../Library/OpensslLib/openssl/crypto/dh/dh_key.c | 12 ++++++++++++ + .../OpensslLib/openssl/crypto/err/openssl.txt | 1 + + .../Library/OpensslLib/openssl/include/openssl/dh.h | 5 +++-- + .../OpensslLib/openssl/include/openssl/dherr.h | 1 + + 6 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +index 2854341..54c6ad7 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c +@@ -197,6 +197,19 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) + BN_CTX *ctx = NULL; + + *ret = 0; ++ ++ /* Don't do any checks at all with an excessively large modulus */ ++ if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { ++ DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_LARGE); ++ *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID; ++ return 0; ++ } ++ ++ if (dh->q != NULL && BN_ucmp(dh->p, dh->q) < 0) { ++ *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; ++ return 1; ++ } ++ + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c +index 92800d3..b3b1e7a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c +@@ -82,6 +82,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = { + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), + "parameter encoding error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, ++ {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR), + "unable to check generator"}, +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c +index daffdf7..56aeff3 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c +@@ -82,6 +82,12 @@ static int generate_key(DH *dh) + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + ++ if (dh->q != NULL ++ && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { ++ DHerr(DH_F_GENERATE_KEY, DH_R_Q_TOO_LARGE); ++ return 0; ++ } ++ + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); + return 0; +@@ -175,6 +181,12 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) + int ret = -1; + int check_result; + ++ if (dh->q != NULL ++ && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { ++ DHerr(DH_F_COMPUTE_KEY, DH_R_Q_TOO_LARGE); ++ goto err; ++ } ++ + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); + goto err; +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +index a07f1a1..a21846d 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.txt +@@ -2097,6 +2097,7 @@ DH_R_NO_PARAMETERS_SET:107:no parameters set + DH_R_NO_PRIVATE_VALUE:100:no private value + DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error + DH_R_PEER_KEY_ERROR:111:peer key error ++DH_R_Q_TOO_LARGE:130:q too large + DH_R_SHARED_INFO_ERROR:113:shared info error + DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator + DSA_R_BAD_Q_VALUE:102:bad q value +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h +index ff00397..f04b02e 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h +@@ -72,14 +72,15 @@ DECLARE_ASN1_ITEM(DHparams) + /* #define DH_GENERATOR_3 3 */ + # define DH_GENERATOR_5 5 + +-/* DH_check error codes */ ++/* DH_check error codes, some of them shared with DH_check_pub_key */ + # define DH_CHECK_P_NOT_PRIME 0x01 + # define DH_CHECK_P_NOT_SAFE_PRIME 0x02 + # define DH_UNABLE_TO_CHECK_GENERATOR 0x04 + # define DH_NOT_SUITABLE_GENERATOR 0x08 + # define DH_CHECK_Q_NOT_PRIME 0x10 +-# define DH_CHECK_INVALID_Q_VALUE 0x20 ++# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */ + # define DH_CHECK_INVALID_J_VALUE 0x40 ++# define DH_MODULUS_TOO_LARGE 0x100 + + /* DH_check_pub_key error codes */ + # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h +index 528c819..d66c35a 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h ++++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/dherr.h +@@ -82,6 +82,7 @@ int ERR_load_DH_strings(void); + # define DH_R_NO_PRIVATE_VALUE 100 + # define DH_R_PARAMETER_ENCODING_ERROR 105 + # define DH_R_PEER_KEY_ERROR 111 ++# define DH_R_Q_TOO_LARGE 130 + # define DH_R_SHARED_INFO_ERROR 113 + # define DH_R_UNABLE_TO_CHECK_GENERATOR 121 + +-- +2.43.0 + diff --git a/0100-UefiCpuPkg-Add-StandardSignatureIsHygonGenuine-in-Ba.patch b/0100-UefiCpuPkg-Add-StandardSignatureIsHygonGenuine-in-Ba.patch new file mode 100644 index 0000000000000000000000000000000000000000..b2f1da70afc4c256f47c42d23b6f2aae304a72ad --- /dev/null +++ b/0100-UefiCpuPkg-Add-StandardSignatureIsHygonGenuine-in-Ba.patch @@ -0,0 +1,132 @@ +From 20514bc88b14974839d94ad79c36e22bb10988c6 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Thu, 21 Apr 2022 16:03:08 +0800 +Subject: [PATCH 1/2] UefiCpuPkg: Add StandardSignatureIsHygonGenuine() in + BaseUefiCpuLib + +This function allows IA32/X64 code to determine if it is running on an +Hygon brand processor. +--- + UefiCpuPkg/Include/Library/UefiCpuLib.h | 13 +++++ + UefiCpuPkg/Include/Register/Hygon/Cpuid.h | 47 +++++++++++++++++++ + .../Library/BaseUefiCpuLib/BaseUefiCpuLib.c | 24 ++++++++++ + 3 files changed, 84 insertions(+) + create mode 100644 UefiCpuPkg/Include/Register/Hygon/Cpuid.h + +diff --git a/UefiCpuPkg/Include/Library/UefiCpuLib.h b/UefiCpuPkg/Include/Library/UefiCpuLib.h +index 5326e72..e307777 100644 +--- a/UefiCpuPkg/Include/Library/UefiCpuLib.h ++++ b/UefiCpuPkg/Include/Library/UefiCpuLib.h +@@ -43,4 +43,17 @@ StandardSignatureIsAuthenticAMD ( + VOID + ); + ++/** ++ Determine if the standard CPU signature is "HygonGenuine". ++ ++ @retval TRUE The CPU signature matches. ++ @retval FALSE The CPU signature does not match. ++ ++**/ ++BOOLEAN ++EFIAPI ++StandardSignatureIsHygonGenuine ( ++ VOID ++ ); ++ + #endif +diff --git a/UefiCpuPkg/Include/Register/Hygon/Cpuid.h b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h +new file mode 100644 +index 0000000..e8a2c76 +--- /dev/null ++++ b/UefiCpuPkg/Include/Register/Hygon/Cpuid.h +@@ -0,0 +1,47 @@ ++/** @file ++ CPUID leaf definitions. ++ ++ Provides defines for CPUID leaf indexes. Data structures are provided for ++ registers returned by a CPUID leaf that contain one or more bit fields. ++ If a register returned is a single 32-bit value, then a data structure is ++ not provided for that register. ++ ++ Copyright (c) 2022, HYGON. All rights reserved.
++ ++ This program and the accompanying materials are licensed and made available ++ under the terms and conditions of the BSD License which accompanies this ++ distribution. The full text of the license may be found at ++ http://opensource.org/licenses/bsd-license.php ++ ++ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++**/ ++ ++#ifndef __HYGON_CPUID_H__ ++#define __HYGON_CPUID_H__ ++ ++/** ++CPUID Signature Information ++ ++@param EAX CPUID_SIGNATURE (0x00) ++ ++@retval EAX Returns the highest value the CPUID instruction recognizes for ++ returning basic processor information. The value is returned is ++ processor specific. ++@retval EBX First 4 characters of a vendor identification string. ++@retval ECX Last 4 characters of a vendor identification string. ++@retval EDX Middle 4 characters of a vendor identification string. ++ ++**/ ++ ++/// ++/// @{ CPUID signature values returned by HYGON processors ++/// ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX SIGNATURE_32 ('H', 'y', 'g', 'o') ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX SIGNATURE_32 ('n', 'G', 'e', 'n') ++#define CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX SIGNATURE_32 ('u', 'i', 'n', 'e') ++/// ++/// @} ++/// ++ ++#endif +diff --git a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c +index c2cc3ff..e61c850 100644 +--- a/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c ++++ b/UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + + #include + #include +@@ -36,3 +37,26 @@ StandardSignatureIsAuthenticAMD ( + RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); + } ++ ++/** ++ Determine if the standard CPU signature is "HygonGenuine". ++ ++ @retval TRUE The CPU signature matches. ++ @retval FALSE The CPU signature does not match. ++ ++**/ ++BOOLEAN ++EFIAPI ++StandardSignatureIsHygonGenuine ( ++ VOID ++ ) ++{ ++ UINT32 RegEbx; ++ UINT32 RegEcx; ++ UINT32 RegEdx; ++ ++ AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); ++ return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EBX && ++ RegEcx == CPUID_SIGNATURE_AUTHENTIC_HYGON_ECX && ++ RegEdx == CPUID_SIGNATURE_AUTHENTIC_HYGON_EDX); ++} +-- +2.43.0 + diff --git a/0101-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch b/0101-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch new file mode 100644 index 0000000000000000000000000000000000000000..11259d9dac6d2c9801b4a5e046e9b84bf44091a8 --- /dev/null +++ b/0101-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch @@ -0,0 +1,80 @@ +From 227f72f62fbdb03cd298a18c638e29438222234e Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Sun, 10 Apr 2022 21:50:15 -0400 +Subject: [PATCH 2/2] UefiCpuPkg/LocalApicLib: Exclude second SendIpi sequence + on HYGON hardware + +On HYGON processors the second SendIpi in the SendInitSipiSipi and +SendInitSipiSipiAllExcludingSelf routines is not required, and may cause +undesired side-effects during MP initialization. + +This patch leverages the StandardSignatureIsHygonGenuine check to exclude +the second SendIpi and its associated MicroSecondDelay (200). +--- + UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 5 +++-- + UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 5 +++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +index 52bd90d..fac41bd 100644 +--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -527,7 +528,7 @@ SendInitSipiSipi ( + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } +@@ -563,7 +564,7 @@ SendInitSipiSipiAllExcludingSelf ( + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +index cdcbca0..a8fea8b 100644 +--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c ++++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + // + // Library internal functions +@@ -622,7 +623,7 @@ SendInitSipiSipi ( + IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP; + IcrLow.Bits.Level = 1; + SendIpi (IcrLow.Uint32, ApicId); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, ApicId); + } +@@ -658,7 +659,7 @@ SendInitSipiSipiAllExcludingSelf ( + IcrLow.Bits.Level = 1; + IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF; + SendIpi (IcrLow.Uint32, 0); +- if (!StandardSignatureIsAuthenticAMD ()) { ++ if (!StandardSignatureIsAuthenticAMD () && !StandardSignatureIsHygonGenuine ()) { + MicroSecondDelay (200); + SendIpi (IcrLow.Uint32, 0); + } +-- +2.43.0 + diff --git a/brotli.tar.gz b/brotli.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a70a886e5b4bfc3da7bc35160d8188df4867749d Binary files /dev/null and b/brotli.tar.gz differ diff --git a/edk2-stable202002.tar.gz b/edk2-stable202011.tar.gz similarity index 60% rename from edk2-stable202002.tar.gz rename to edk2-stable202011.tar.gz index fd9db10fc1b4a05e53edad1323cc3002dfb0b840..0c2cd385cf55d5e336be5ee55ec9fc4cff2ec8ec 100644 Binary files a/edk2-stable202002.tar.gz and b/edk2-stable202011.tar.gz differ diff --git a/edk2.spec b/edk2.spec index 30110864ddb6a6e06f86d094bebb6b11f564263d..a1cb12f273a18e78bf03b3efaf55bacbd1130f6c 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,47 +1,159 @@ -%global stable_date 202002 +%global stable_date 202011 %global release_tag edk2-stable%{stable_date} %global openssl_version 1.1.1f %global _python_bytecompile_extra 0 Name: edk2 Version: %{stable_date} -Release: 11 +Release: 29 Summary: EFI Development Kit II License: BSD-2-Clause-Patent URL: https://github.com/tianocore/edk2 Source0: https://github.com/tianocore/edk2/archive/%{release_tag}.tar.gz Source1: openssl-%{openssl_version}.tar.gz - -Patch0001: 0001-CryptoPkg-OpensslLib-Modify-process_files.pl-for-Ope.patch -Patch0002: 0002-CryptoPkg-Upgrade-OpenSSL-to-1.1.1f.patch -Patch0003: 0003-OvmfPkg-Tcg2ConfigPei-introduce-a-signalling-PPI-to-.patch -Patch0004: 0004-ArmVirtPkg-PlatformPeiLib-make-PcdLib-dependency-exp.patch -Patch0005: 0005-ArmVirtPkg-PlatformPeiLib-discover-the-TPM-base-addr.patch -Patch0006: 0006-ArmVirtPkg-implement-ArmVirtPsciResetSystemPeiLib.patch -Patch0007: 0007-ArmVirtPkg-ArmVirtQemu-add-ResetSystem-PEIM-for-upco.patch -Patch0008: 0008-ArmVirtPkg-ArmVirtQemu-enable-TPM2-support-in-the-PE.patch -Patch0009: 0009-ArmVirtPkg-avoid-DxeTpmMeasurementLib-in-shared-.DSC.patch -Patch0010: 0010-ArmVirtPkg-unshare-TpmMeasurementLib-resolution-betw.patch -Patch0011: 0011-ArmVirtPkg-ArmVirtQemu-enable-the-DXE-phase-TPM2-sup.patch -Patch0012: 0012-ArmVirtPkg-ArmVirtQemu-enable-the-TPM2-configuration.patch -Patch0013: 0013-ArmVirtPkg-ArmVirtQemu-enable-TPM2-based-measured-bo.patch -Patch0014: 0014-MdeModulePkg-Core-Dxe-assert-SectionInstance-invariant-in-FindChildNode.patch -Patch0015: 0015-MdeModulePkg-Core-Dxe-limit-FwVol-encapsulation-section-recursion.patch -Patch0016: 0016-ArmPkg-CompilerIntrinsicsLib-provide-atomics-intrins.patch -Patch0017: 0017-MdeModulePkg-LzmaCustomDecompressLib-catch-4GB-uncom.patch -Patch0018: 0018-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch -Patch0019: 0019-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch -Patch0020: 0020-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch -Patch0021: 0021-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch -Patch0022: 0022-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch -Patch0023: 0023-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch -Patch0024: 0024-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch -Patch0025: 0025-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch -Patch0026: 0026-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch -Patch0027: 0027-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch -Patch0028: 0028-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch -Patch0029: 0029-BaseTools-fix-ucs-2-lookup-on-python-3.9.patch -Patch0030: 0030-BaseTools-Work-around-array.array.tostring-removal-i.patch +Source2: brotli.tar.gz + +# for CVE-2021-38575 +Patch0001: 0001-NetworkPkg-IScsiDxe-wrap-IScsiCHAP-source-files-to-8.patch +Patch0002: 0002-NetworkPkg-IScsiDxe-simplify-ISCSI_CHAP_AUTH_DATA.In.patch +Patch0003: 0003-NetworkPkg-IScsiDxe-clean-up-ISCSI_CHAP_AUTH_DATA.Ou.patch +Patch0004: 0004-NetworkPkg-IScsiDxe-clean-up-library-class-dependenc.patch +Patch0005: 0005-NetworkPkg-IScsiDxe-fix-potential-integer-overflow-i.patch +Patch0006: 0006-NetworkPkg-IScsiDxe-assert-that-IScsiBinToHex-always.patch +Patch0007: 0007-NetworkPkg-IScsiDxe-reformat-IScsiHexToBin-leading-c.patch +Patch0008: 0008-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-hex-parsing.patch +Patch0009: 0009-NetworkPkg-IScsiDxe-fix-IScsiHexToBin-buffer-overflo.patch +Patch0010: 0010-NetworkPkg-IScsiDxe-check-IScsiHexToBin-return-value.patch + +# for CVE-2021-28216 +Patch0011: 0011-MdeModulePkg-FPDT-Lock-boot-performance-table-addres.patch + +# for CVE-2021-38576 +Patch0012: 0012-SecurityPkg-TPM-Import-PeiDxeTpmPlatformHierarchyLib.patch +Patch0013: 0013-SecurityPkg-TPM-Fix-bugs-in-imported-PeiDxeTpmPlatfo.patch +Patch0014: 0014-SecrutiyPkg-Tcg-Import-Tcg2PlatformDxe-from-edk2-pla.patch +Patch0015: 0015-SecurityPkg-Tcg-Make-Tcg2PlatformDxe-buildable-and-f.patch +Patch0016: 0016-SecurityPkg-Introduce-new-PCD-PcdRandomizePlatformHi.patch +Patch0017: 0017-SecurityPkg-Tcg-Import-Tcg2PlatformPei-from-edk2-pla.patch +Patch0018: 0018-SecurityPkg-Tcg-Make-Tcg2PlatformPei-buildable-and-f.patch +Patch0019: 0019-SecurityPkg-Add-references-to-header-and-inf-files-t.patch + +Patch0020: 0020-OvmfPkg-VirtioNetDxe-Extend-the-RxBufferSize-to-avoi.patch + +Patch0021: 0021-UefiCpuPkg-Move-MigrateGdt-from-DiscoverMemory-to-Te.patch + +Patch0022: 0022-MdeModulePkg-PiSmmCore-SmmEntryPoint-underflow-CVE-2.patch +Patch0023: 0023-PATCH-Avoid-dangling-ptrs-in-header-and-data-params-.patch +Patch0024: 0024-PATCH-pk7_doit.c-Check-return-of-BIO_set_md-calls.patch +Patch0025: 0025-Fix-a-UAF-resulting-from-a-bug-in-BIO_new_NDEF.patch +Patch0026: 0026-Check-CMS-failure-during-BIO-setup-with-stream-is-ha.patch +Patch0027: 0027-Correctly-compare-EdiPartyName-in-GENERAL_NAME_cmp.patch +Patch0028: 0028-CVE-2023-0286-Fix-GENERAL_NAME_cmp-for-x400Address-1.patch + +# for CVE-2022-4304 +Patch0029: 0029-Fix-Timing-Oracle-in-RSA-decryption.patch + +# solving the compilation failure problem of gcc 12.3.0 +Patch0030: 0030-brotli-Fix-VLA-parameter-warning-893.patch +Patch0031: 0031-MdeModulePkg-UsbBusDxe-fix-NOOPT-build-error.patch +Patch0032: 0032-BaseTools-GenEfs-GenSec-fix-gcc12-warning.patch +Patch0033: 0033-BaseTools-LzmaCompress-fix-gcc12-warning.patch +Patch0034: 0034-Basetools-turn-off-gcc12-warning.patch + +Patch0035: 0035-x509-excessive-resource-use-verifying-policy-constra.patch +Patch0036: 0036-test-add-test-cases-for-the-policy-resource-overuse.patch +Patch0037: 0037-Ensure-that-EXFLAG_INVALID_POLICY-is-checked-even-in.patch +Patch0038: 0038-Fix-documentation-of-X509_VERIFY_PARAM_add0_policy.patch +Patch0039: 0039-Restrict-the-size-of-OBJECT-IDENTIFIERs-that-OBJ_obj.patch +Patch0040: 0040-Add-a-test-for-CVE-2023-3446.patch +Patch0041: 0041-Fix-DH_check-excessive-time-with-over-sized-modulus.patch +Patch0042: 0042-Update-further-expiring-certificates-that-affect-tes.patch +Patch0043: 0043-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch +Patch0044: 0044-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch +Patch0045: 0045-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch + +# CVE-2022-36763、CVE-2022-36764、CVE-2022-36765 +Patch0046: 0046-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +Patch0047: 0047-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch +Patch0048: 0048-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch +Patch0049: 0049-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +Patch0050: 0050-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch +Patch0051: 0051-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch +Patch0052: 0052-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch +Patch0053: 0053-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch +Patch0054: 0054-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch +Patch0055: 0055-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch + +Patch0056: 0056-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH.patch +Patch0057: 0057-NetworkPkg-Add-Unit-tests-to-CI-and-create-Host-Test.patch +Patch0058: 0058-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch +Patch0059: 0059-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch +Patch0060: 0060-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Un.patch +Patch0061: 0061-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch +Patch0062: 0062-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch +Patch0063: 0063-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch +Patch0064: 0064-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch +Patch0065: 0065-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +Patch0066: 0066-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +Patch0067: 0067-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +Patch0068: 0068-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +Patch0069: 0069-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch +Patch0070: 0070-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch +Patch0071: 0071-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch + +# fix CVE-2024-2511 +Patch0072: 0072-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch +Patch0073: 0073-Add-a-test-for-session-cache-handling.patch +Patch0074: 0074-Extend-the-multi_resume-test-for-simultaneous-resump.patch +Patch0075: 0075-Hardening-around-not_resumable-sessions.patch +Patch0076: 0076-Add-a-test-for-session-cache-overflow.patch + +# fix CVE-2024-1298 +Patch0077: 0077-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch + +# fix CVE-2024-5535 +Patch0078: 0078-Fix-SSL_select_next_proto-and-add-ALPN-validation-in.patch +Patch0079: 0079-Add-a-test-for-ALPN-and-NPN.patch + +# fix CVE-2021-3712、CVE-2022-0778 +Patch0080: 0080-Fix-i2v_GENERAL_NAME-to-not-assume-NUL-terminated-st.patch +Patch0081: 0081-Fix-POLICYINFO-printing-to-not-assume-NUL-terminated.patch +Patch0082: 0082-Fix-printing-of-PROXY_CERT_INFO_EXTENSION-to-not-ass.patch +Patch0083: 0083-Fix-the-name-constraints-code-to-not-assume-NUL-term.patch +Patch0084: 0084-Fix-test-code-to-not-assume-NUL-terminated-strings.patch +Patch0085: 0085-Fix-append_ia5-function-to-not-assume-NUL-terminated.patch +Patch0086: 0086-Fix-NETSCAPE_SPKI_print-function-to-not-assume-NUL-t.patch +Patch0087: 0087-Fix-EC_GROUP_new_from_ecparameters-to-check-the-base.patch +Patch0088: 0088-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch + +# support vdpa blk/scsi device boot +Patch0089: 0089-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch +Patch0090: 0090-Virtio-wait-virtio-device-reset-done.patch +Patch0091: 0091-VirtioBlk-split-large-IO-according-to-segment_size_m.patch + +# Fix CVE-2024-38796 +patch0092: 0092-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch + +# Fix CVE-2023-45236、CVE-2023-45237 +patch0093: 0093-NetworkPkg-TcpDxe-SECURITY-PATCH-CVE-2023-45236-Rela.patch +patch0094: 0094-NetworkPkg-DxeNetLib-SECURITY-PATCH-CVE-2023-45237-R.patch + +# Fix CVE-2024-13176、CVE-2024-4741 +patch95: 0095-Fix-timing-side-channel-CVE-2024-13176.patch +patch96: 0096-Free-the-read-buffers-CVE-2024-4741.patch + +# Fix CVE-2024-9143 +patch97: 0097-Harden-BN_GF2m_poly2arr-against-misuse.patch + +# Fix CVE-2024-38797 +patch98: 0098-SecurityPkg-Out-of-bound-read-in-HashPeImageByType.patch + +# Fix CVE-2023-5678 +patch99: 0099-CryptoPkg-Make-DH_check_pub_key-and.patch + +# Correct AP bootup sequence for Hygon vCPU +Patch0100: 0100-UefiCpuPkg-Add-StandardSignatureIsHygonGenuine-in-Ba.patch +Patch0101: 0101-UefiCpuPkg-LocalApicLib-Exclude-second-SendIpi-seque.patch BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command @@ -93,6 +205,8 @@ EFI Development Kit II Open Virtual Machine Firmware (ia32) %prep %setup -n edk2-%{release_tag} tar -xf %{SOURCE1} -C CryptoPkg/Library/OpensslLib/openssl --strip-components=1 +tar -xf %{SOURCE2} -C MdeModulePkg/Library/BrotliCustomDecompressLib/brotli --strip-components=1 +tar -xf %{SOURCE2} -C BaseTools/Source/C/BrotliCompress/brotli --strip-components=1 %autopatch -p1 %build @@ -117,6 +231,8 @@ COMMON_FLAGS="-D NETWORK_IP6_ENABLE" BUILD_OPTION="$BUILD_OPTION -D SECURE_BOOT_ENABLE=TRUE" BUILD_OPTION="$BUILD_OPTION -D TPM2_ENABLE=TRUE" BUILD_OPTION="$BUILD_OPTION -D TPM2_CONFIG_ENABLE=TRUE" +BUILD_OPTION="$BUILD_OPTION -D TPM_ENABLE=TRUE" +BUILD_OPTION="$BUILD_OPTION -D TPM_CONFIG_ENABLE=TRUE" build $BUILD_OPTION %install @@ -175,7 +291,7 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys %files devel %license License.txt %license LICENSE.openssl -%{_bindir}/Brotli +%{_bindir}/BrotliCompress %{_bindir}/DevicePath %{_bindir}/EfiRom %{_bindir}/GenCrc32 @@ -239,11 +355,98 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys %endif %changelog -* Wed Jan 12 2022 Jinhua Cao - 202002-11 +* Thu Sep 04 2025 hanliyang -202011-29 +- Correct AP boot sequence for Hygon vCPU + +* Sat Jun 28 2025 taolinghongfei -202011-28 +- fix CVE-2023-5678 + +* Sun Apr 27 2025 huyu - 202011-27 +- fix CVE-2024-38797 + +* Fri Mar 28 2025 huyu - 202011-26 +- fix CVE-2024-9143 + +* Sun Mar 9 2025 shenyage - 202011-25 +- fix bugs for CVE-2023-45236、CVE-2023-45237 + +* Wed Feb 26 2025 huyu - 202011-24 +- fix CVE-2024-13176、CVE-2024-4741 + +* Mon Oct 14 2024 shenyage - 202011-23 +- fix CVE-2023-45236、CVE-2023-45237 + +* Wed Oct 09 2024 zhangxianting - 202011-22 +- fix CVE-2024-38796 + +* Wed Sep 18 2024 jiangdongxu - 202011-21 +- vdpa: support vdpa blk/scsi device boot + +* Tue Sep 3 2024 shenyage - 202011-20 +- fix CVE-2021-3712、CVE-2022-0778 + +* Thu Jul 11 2024 shenyage - 202011-19 +- fix CVE-2024-5535 + +* Wed Jun 12 2024 shenyage - 202011-18 +- fix CVE-2024-1298 + +* Mon Apr 15 2024 shenyage - 202011-17 +- fix CVE-2024-2511 + +* Thu Mar 7 2024 yexiao - 202011-16 +- fix CVE-2023-45229、CVE-2023-45230、CVE-2023-45231、CVE-2023-45232、CVE-2023-45233、CVE-2023-45234、CVE-2023-45235 + +* Tue Mar 5 2024 yexiao - 202011-15 +- fix CVE-2022-36763、CVE-2022-36764、CVE-2022-36765 + +* Tue Feb 20 2024 yexiao - 202011-14 +- fix CVE-2023-0464、CVE-2023-0465、CVE-2023-0466、CVE-2023-2650、CVE-2023-3446、CVE-2023-3817、CVE-2024-0727 + +* Thu Jul 13 2023 Jiabo Feng - 202011-13 +- solving the compilation failure problem of gcc 12.3.0 + +* Fri Mar 10 2023 yexiao - 202011-12 +- fix CVE-2022-4304 + +* Sun Feb 26 2023 chenhuiying - 202011-11 +- fix CVE-2023-0286 + +* Sun Feb 26 2023 chenhuiying - 202011-10 +- fix CVE-2023-0215 + +* Sat Feb 25 2023 shaodenghui - 202011-9 +- fix CVE-2023-0401 + +* Mon Feb 20 2023 shaodenghui - 202011-8 +- fix CVE-2022-4450 + +* Tue Nov 29 2022 chenhuiying - 202011-7 +- fix CVE-2021-38578 + +* Thu Sep 29 2022 chenhuiying - 202011-6 +* fix CVE-2019-11098 + +* Tue Jun 14 2022 miaoyubo - 202011-5 +- Enable TPM for pcr0-7 + +* Wed Apr 27 2022 yezengruan - 202011-4 +- update the format of changelog + +* Thu Feb 17 2022 Jinhua Cao - 202011-3 +- OvmfPkg: VirtioNetDxe: Extend the RxBufferSize to avoid data truncation + +* Tue Feb 15 2022 Jinhua Cao - 202011-2 +- fix CVE-2021-38576 + +* Mon Feb 7 2022 Jinhua Cao - 202011-1 +- update edk2 to stable 202011 + +* Wed Jan 12 2022 Jinhua Cao - 202002-11 - BaseTools: fix ucs-2 lookup on python3.9 - BaseTools: Work around array.array.tostring() removal in python3.9 -* Wed Dec 1 2021 Jinhua Cao -202002-10 +* Wed Dec 1 2021 Jinhua Cao - 202002-10 - fix CVE-2021-28216 * Wed Sep 22 2021 imxcc - 202002-9