Re: [PATCH V2 1/3] CryptoPkg: Add EC support
That change to OpensslLib.inf should not have been done either.
Looks like this EC feature needs more evaluation to fit into the structured PCD control of the lib sizes.
Mike
toggle quoted message
Show quoted text
-----Original Message----- From: Li, Yi1 <yi1.li@...> Sent: Wednesday, September 21, 2022 7:16 PM To: Kinney, Michael D <michael.d.kinney@...>; devel@edk2.groups.io Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support
Hi Mike, Thanks for review.
Even PCD_CRYPTO_SERVICE_FAMILY_ENABLE is set to 0, CryptoEc.c will also be compiled and throw build error:
d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): error C2220: the following warning is treated as an error 1 file(s) copied. d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): warning C4013: 'EC_GROUP_new_by_curve_name' undefined; assuming extern returning int d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): warning C4047: 'return': 'void *' differs in levels of indirection from 'int' d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(105): warning C4013: 'EC_GROUP_get_curve' undefined; assuming extern returning int
I think the root cause is that we have enabled conditional ec in OpensslLib.inf before by PcdOpensslEcEnabled, https://github.com/tianocore/edk2/blob/2c17d676e402d75a3a674499342f7ddaccf387bd/CryptoPkg/Library/OpensslLib/OpensslLib.inf#L2 02-L238 if PcdOpensslEcEnabled not true, all ec files will not be compiled. This will save 200+kb memory on platforms which use dxe driver but do not need ec feature.
So I add this PCD to BaseCryptLib.inf also to avoid build error, Not sure if there is any other way, other better ideas are welcome.
Thanks, Yi
-----Original Message----- From: Kinney, Michael D <michael.d.kinney@...> Sent: Thursday, September 22, 2022 12:22 AM To: devel@edk2.groups.io; Li, Yi1 <yi1.li@...>; Kinney, Michael D <michael.d.kinney@...> Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support
Comments embedded below.
Mike
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of yi1 li Sent: Tuesday, September 20, 2022 9:55 PM To: devel@edk2.groups.io Cc: Li, Yi1 <yi1.li@...>; Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828
This patch is used to add CryptEc library, which is wrapped over OpenSSL.
Cc: Jiewen Yao <jiewen.yao@...> Cc: Jian J Wang <jian.j.wang@...> Cc: Xiaoyu Lu <xiaoyu1.lu@...> Cc: Guomin Jiang <guomin.jiang@...>
Signed-off-by: Yi Li <yi1.li@...> --- CryptoPkg/Include/Library/BaseCryptLib.h | 424 ++++++++++ .../Library/BaseCryptLib/BaseCryptLib.inf | 2 + .../Library/BaseCryptLib/PeiCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c | 765 ++++++++++++++++++ .../Library/BaseCryptLib/Pk/CryptEcNull.c | 496 ++++++++++++ .../Library/BaseCryptLib/SmmCryptLib.inf | 1 + .../BaseCryptLibNull/BaseCryptLibNull.inf | 1 + .../Library/BaseCryptLibNull/Pk/CryptEcNull.c | 496 ++++++++++++ 8 files changed, 2186 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c create mode 100644 CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index b253923dd8..d74fc21c1e 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -14,6 +14,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Uefi/UefiBaseType.h>
+#define CRYPTO_NID_NULL 0x0000 + +// Key Exchange +#define CRYPTO_NID_SECP256R1 0x0204 +#define CRYPTO_NID_SECP384R1 0x0205 +#define CRYPTO_NID_SECP521R1 0x0206 + /// /// MD5 digest size in bytes /// @@ -2850,4 +2857,421 @@ BigNumAddMod ( OUT VOID *BnRes );
+// ===================================================================================== +// Basic Elliptic Curve Primitives +// ===================================================================================== + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ); + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ); + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ); + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ); + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ); + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ); + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ); + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ); + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ); + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ); + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ); + +// ===================================================================================== +// Elliptic Curve Diffie Hellman Primitives +// ===================================================================================== + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ); + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ); + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ); + #endif // __BASE_CRYPT_LIB_H__ diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index 9e4be2fb0d..ade6ee3fdd 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -52,6 +52,8 @@ Pk/CryptTs.c Pk/CryptRsaPss.c Pk/CryptRsaPssSign.c + Pk/CryptEcNull.c |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled + Pk/CryptEc.c |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled The use of the PCD to select the file should not be needed here. The Ec Family and individual service enable/disable fields in the PCD_CRYPTO_SERVICE_FAMILY_ENABLE structured PCD are all that is needed to disable the Ec services.
The PCD gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled should be removed completely as part of this patch series.
Pem/CryptPem.c Bn/CryptBn.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf index 65ad23fb81..383df2b23c 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -58,6 +58,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Bn/CryptBnNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c new file mode 100644 index 0000000000..396c819834 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c @@ -0,0 +1,765 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include <openssl/objects.h> +#include <openssl/bn.h> +#include <openssl/ec.h> + +// ===================================================================================== +// Basic Elliptic Curve Primitives +// ===================================================================================== + +/** + Return the Nid of certain ECC curve. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval !=-1 On success. + @retval -1 ECC curve not supported. +**/ +STATIC +INT32 +CryptoNidToOpensslNid ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + switch (CryptoNid) { + case CRYPTO_NID_SECP256R1: + Nid = NID_X9_62_prime256v1; + break; + case CRYPTO_NID_SECP384R1: + Nid = NID_secp384r1; + break; + case CRYPTO_NID_SECP521R1: + Nid = NID_secp521r1; + break; + default: + return -1; + } + + return Nid; +} + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + Nid = CryptoNidToOpensslNid (CryptoNid); + + if (Nid < 0) { + return NULL; + } + + return EC_GROUP_new_by_curve_name (Nid); +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA, BnB, BnCtx); +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder, NULL); +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + EC_GROUP_free (EcGroup); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + return EC_POINT_new (EcGroup); +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + if (Clear) { + EC_POINT_clear_free (EcPoint); + } else { + EC_POINT_free (EcPoint); + } +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx); +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx); +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx); +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult, NULL, EcPoint, BnPScalar, BnCtx); +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx); +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) == 1; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + return EC_POINT_is_at_infinity (EcGroup, EcPoint) == 1; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) == 0; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_compressed_coordinates (EcGroup, EcPoint, BnX, YBit, BnCtx); +} + +// ===================================================================================== +// Elliptic Curve Diffie Hellman Primitives +// ===================================================================================== + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + INT32 OpenSslNid; + + OpenSslNid = CryptoNidToOpensslNid (Nid); + if (OpenSslNid < 0) { + return NULL; + } + + return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid); +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + EC_KEY_free ((EC_KEY *)EcContext); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + + if ((EcContext == NULL) || (PublicKeySize == NULL)) { + return FALSE; + } + + if ((PublicKey == NULL) && (*PublicKeySize != 0)) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + + // Assume RAND_seed was called + if (EC_KEY_generate_key (EcKey) != 1) { + return FALSE; + } + + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize = HalfSize * 2; + return FALSE; + } + + *PublicKeySize = HalfSize * 2; + + EcPoint = EC_KEY_get0_public_key (EcKey); + if (EcPoint == NULL) { + return FALSE; + } + + RetVal = FALSE; + BnX = BN_new (); + BnY = BN_new (); + if ((BnX == NULL) || (BnY == NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) { + goto fail; + } + + XSize = BN_num_bytes (BnX); + YSize = BN_num_bytes (BnY); + if ((XSize <= 0) || (YSize <= 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize); + + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + BOOLEAN RetVal; + + if ((EcContext == NULL) || (PublicKeySize == NULL)) { + return FALSE; + } + + if ((PublicKey == NULL) && (*PublicKeySize != 0)) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize = HalfSize * 2; + return FALSE; + } + + *PublicKeySize = HalfSize * 2; + + EcPoint = EC_KEY_get0_public_key (EcKey); + if (EcPoint == NULL) { + return FALSE; + } + + RetVal = FALSE; + BnX = BN_new (); + BnY = BN_new (); + if ((BnX == NULL) || (BnY == NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) { + goto fail; + } + + XSize = BN_num_bytes (BnX); + YSize = BN_num_bytes (BnY); + if ((XSize <= 0) || (YSize <= 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize); + + if (PublicKey != NULL) { + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + } + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If public key is compressed, the PeerPublic will only contain half key (X). + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + EC_KEY *EcKey; + EC_KEY *PeerEcKey; + CONST EC_GROUP *Group; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + EC_POINT *Point; + INT32 OpenSslNid; + UINTN HalfSize; + + if ((EcContext == NULL) || (PeerPublic == NULL) || (KeySize == NULL)) { + return FALSE; + } + + if ((Key == NULL) && (*KeySize != 0)) { + return FALSE; + } + + if (PeerPublicSize > INT_MAX) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + if ((CompressFlag == NULL) && (PeerPublicSize != HalfSize * 2)) { + return FALSE; + } + + if ((CompressFlag != NULL) && (PeerPublicSize != HalfSize)) { + return FALSE; + } + + if (*KeySize < HalfSize) { + *KeySize = HalfSize; + return FALSE; + } + + *KeySize = HalfSize; + + RetVal = FALSE; + Point = NULL; + BnX = BN_bin2bn (PeerPublic, (INT32)HalfSize, NULL); + BnY = NULL; + Point = EC_POINT_new (Group); + PeerEcKey = NULL; + if ((BnX == NULL) || (Point == NULL)) { + goto fail; + } + + if (CompressFlag == NULL) { + BnY = BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize, NULL); + if (BnY == NULL) { + goto fail; + } + + if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY, NULL) != 1) { + goto fail; + } + } else { + if (EC_POINT_set_compressed_coordinates (Group, Point, BnX, *CompressFlag, NULL) != 1) { + goto fail; + } + } + + // Validate NIST ECDH public key + OpenSslNid = EC_GROUP_get_curve_name (Group); + PeerEcKey = EC_KEY_new_by_curve_name (OpenSslNid); + if (PeerEcKey == NULL) { + goto fail; + } + + if (EC_KEY_set_public_key (PeerEcKey, Point) != 1) { + goto fail; + } + + if (EC_KEY_check_key (PeerEcKey) != 1) { + goto fail; + } + + if (ECDH_compute_key (Key, *KeySize, Point, EcKey, NULL) <= 0) { + goto fail; + } + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + EC_POINT_free (Point); + EC_KEY_free (PeerEcKey); + return RetVal; +} diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseCryptLib.h> +#include <Library/DebugLib.h> + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf index ce6a789dfd..4bc3063485 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -59,6 +59,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPem.c Bn/CryptBnNull.c
diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 354f3d80aa..e1a57ef09f 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf @@ -49,6 +49,7 @@ Pk/CryptX509Null.c Pk/CryptAuthenticodeNull.c Pk/CryptTsNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Pk/CryptRsaPssNull.c diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseCryptLib.h> +#include <Library/DebugLib.h> + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} -- 2.31.1.windows.1
|
|
Updated Event: EDKII Open Design Meeting - Friday, September 23, 2022
#cal-invite
Group Notification <noreply@...>
EDKII Open Design Meeting
When:
Friday, September 23, 2022
9:30am to 10:00am
(UTC+08:00) Asia/Shanghai
Where:
https://teams.microsoft.com/l/meetup-join/19%3ameeting_YWI4NDI4OGItOGM4OS00NDc0LWEzMDktOTExNjEzMDQ1ZGYy%40thread.v2/0?context=%7b%22Tid%22%3a%2246c98d88-e344-4ed4-8496-4ed7712e255d%22%2c%22Oid%22%3a%2255d36a50-78be-4ced-bc27-3d06c576cc19%22%7d
Organizer: Ray Ni
ray.ni@...
View Event
Description:
TOPIC:
How to add support for RISC-V in edk2? - Sunil V L
|
|
Re: How to guard CAR's stack overflow
Hi, Johnson:
Thanks for your reply!
I tried and found it seemed causing some other problems.
It hang in eary pei stage.
It seems below code could also cause an exception if using expand-down mode in CAR phase’s stack established.
mov eax, ss:[ebx]
mov eax, [ebp]
mov eax, [esp]
Thanks
Sent: Wednesday, September 14, 2022, 10:25 PM
Subject: [edk2-devel] How to guard CAR's stack overflow
It’s doable.
You need to enable paging and mark the very low 4K area of the stack as not-present.
You could use the UefiCpuPkg/Library/CpuPageTableLib to help you create the 1:1 page table with the specific
4K area as not-present (if you are using x86 processors).
Thanks,
Ray
Hi, Experts:
Usually, we use Cache As Ram to setup stack and heap for C language running environment before permanent memory has been initialized.
So, is there a method to guard this phase’s stack overflow?
Note:
I find udk has introduced a method to guard stack overflow after memory has been initialized and discovered.
Thanks
本邮件含有保密或专有信息,仅供指定收件人使用。严禁对本邮件或其内容做任何未经授权的查阅、使用、复制或转发。
This email contains confidential or legally privileged information and is for the sole use of its intended recipient. Any unauthorized
review, use, copying or forwarding of this email or the content of this email is strictly prohibited.
Groups.io Links:
You receive all messages sent to this group.
View/Reply Online (#93797) | |
Mute This Topic |
New Topic
Your Subscription |
Contact Group Owner | Unsubscribe [brian.johnson@...]
保密声明:
本邮件含有保密或专有信息,仅供指定收件人使用。严禁对本邮件或其内容做任何未经授权的查阅、使用、复制或转发。
CONFIDENTIAL NOTE:
This email contains confidential or legally privileged information and is for the sole use of its intended recipient. Any unauthorized review, use, copying or forwarding of this email or the content of this email is strictly prohibited.
|
|
Re: [PATCH V2 1/3] CryptoPkg: Add EC support
Hi Mike, Thanks for review. Even PCD_CRYPTO_SERVICE_FAMILY_ENABLE is set to 0, CryptoEc.c will also be compiled and throw build error: d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): error C2220: the following warning is treated as an error 1 file(s) copied. d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): warning C4013: 'EC_GROUP_new_by_curve_name' undefined; assuming extern returning int d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(77): warning C4047: 'return': 'void *' differs in levels of indirection from 'int' d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.c(105): warning C4013: 'EC_GROUP_get_curve' undefined; assuming extern returning int I think the root cause is that we have enabled conditional ec in OpensslLib.inf before by PcdOpensslEcEnabled, https://github.com/tianocore/edk2/blob/2c17d676e402d75a3a674499342f7ddaccf387bd/CryptoPkg/Library/OpensslLib/OpensslLib.inf#L202-L238 if PcdOpensslEcEnabled not true, all ec files will not be compiled. This will save 200+kb memory on platforms which use dxe driver but do not need ec feature. So I add this PCD to BaseCryptLib.inf also to avoid build error, Not sure if there is any other way, other better ideas are welcome. Thanks, Yi
toggle quoted message
Show quoted text
-----Original Message----- From: Kinney, Michael D <michael.d.kinney@...> Sent: Thursday, September 22, 2022 12:22 AM To: devel@edk2.groups.io; Li, Yi1 <yi1.li@...>; Kinney, Michael D <michael.d.kinney@...> Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support Comments embedded below. Mike -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of yi1 li Sent: Tuesday, September 20, 2022 9:55 PM To: devel@edk2.groups.io Cc: Li, Yi1 <yi1.li@...>; Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828
This patch is used to add CryptEc library, which is wrapped over OpenSSL.
Cc: Jiewen Yao <jiewen.yao@...> Cc: Jian J Wang <jian.j.wang@...> Cc: Xiaoyu Lu <xiaoyu1.lu@...> Cc: Guomin Jiang <guomin.jiang@...>
Signed-off-by: Yi Li <yi1.li@...> --- CryptoPkg/Include/Library/BaseCryptLib.h | 424 ++++++++++ .../Library/BaseCryptLib/BaseCryptLib.inf | 2 + .../Library/BaseCryptLib/PeiCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c | 765 ++++++++++++++++++ .../Library/BaseCryptLib/Pk/CryptEcNull.c | 496 ++++++++++++ .../Library/BaseCryptLib/SmmCryptLib.inf | 1 + .../BaseCryptLibNull/BaseCryptLibNull.inf | 1 + .../Library/BaseCryptLibNull/Pk/CryptEcNull.c | 496 ++++++++++++ 8 files changed, 2186 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c create mode 100644 CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h index b253923dd8..d74fc21c1e 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -14,6 +14,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Uefi/UefiBaseType.h>
+#define CRYPTO_NID_NULL 0x0000 + +// Key Exchange +#define CRYPTO_NID_SECP256R1 0x0204 +#define CRYPTO_NID_SECP384R1 0x0205 +#define CRYPTO_NID_SECP521R1 0x0206 + /// /// MD5 digest size in bytes /// @@ -2850,4 +2857,421 @@ BigNumAddMod ( OUT VOID *BnRes );
+// ===================================================================================== +// Basic Elliptic Curve Primitives +// ===================================================================================== + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ); + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ); + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ); + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ); + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ); + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ); + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ); + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ); + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ); + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ); + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ); + +// ===================================================================================== +// Elliptic Curve Diffie Hellman Primitives +// ===================================================================================== + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ); + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ); + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ); + #endif // __BASE_CRYPT_LIB_H__ diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index 9e4be2fb0d..ade6ee3fdd 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -52,6 +52,8 @@ Pk/CryptTs.c Pk/CryptRsaPss.c Pk/CryptRsaPssSign.c + Pk/CryptEcNull.c |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled + Pk/CryptEc.c |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled The use of the PCD to select the file should not be needed here. The Ec Family and individual service enable/disable fields in the PCD_CRYPTO_SERVICE_FAMILY_ENABLE structured PCD are all that is needed to disable the Ec services. The PCD gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled should be removed completely as part of this patch series. Pem/CryptPem.c Bn/CryptBn.c
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf index 65ad23fb81..383df2b23c 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -58,6 +58,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Bn/CryptBnNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c new file mode 100644 index 0000000000..396c819834 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c @@ -0,0 +1,765 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include <openssl/objects.h> +#include <openssl/bn.h> +#include <openssl/ec.h> + +// ===================================================================================== +// Basic Elliptic Curve Primitives +// ===================================================================================== + +/** + Return the Nid of certain ECC curve. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval !=-1 On success. + @retval -1 ECC curve not supported. +**/ +STATIC +INT32 +CryptoNidToOpensslNid ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + switch (CryptoNid) { + case CRYPTO_NID_SECP256R1: + Nid = NID_X9_62_prime256v1; + break; + case CRYPTO_NID_SECP384R1: + Nid = NID_secp384r1; + break; + case CRYPTO_NID_SECP521R1: + Nid = NID_secp521r1; + break; + default: + return -1; + } + + return Nid; +} + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + Nid = CryptoNidToOpensslNid (CryptoNid); + + if (Nid < 0) { + return NULL; + } + + return EC_GROUP_new_by_curve_name (Nid); +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA, BnB, BnCtx); +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder, NULL); +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + EC_GROUP_free (EcGroup); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + return EC_POINT_new (EcGroup); +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + if (Clear) { + EC_POINT_clear_free (EcPoint); + } else { + EC_POINT_free (EcPoint); + } +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx); +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx); +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx); +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult, NULL, EcPoint, BnPScalar, BnCtx); +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx); +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) == 1; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + return EC_POINT_is_at_infinity (EcGroup, EcPoint) == 1; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) == 0; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_compressed_coordinates (EcGroup, EcPoint, BnX, YBit, BnCtx); +} + +// ===================================================================================== +// Elliptic Curve Diffie Hellman Primitives +// ===================================================================================== + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + INT32 OpenSslNid; + + OpenSslNid = CryptoNidToOpensslNid (Nid); + if (OpenSslNid < 0) { + return NULL; + } + + return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid); +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + EC_KEY_free ((EC_KEY *)EcContext); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + + if ((EcContext == NULL) || (PublicKeySize == NULL)) { + return FALSE; + } + + if ((PublicKey == NULL) && (*PublicKeySize != 0)) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + + // Assume RAND_seed was called + if (EC_KEY_generate_key (EcKey) != 1) { + return FALSE; + } + + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize = HalfSize * 2; + return FALSE; + } + + *PublicKeySize = HalfSize * 2; + + EcPoint = EC_KEY_get0_public_key (EcKey); + if (EcPoint == NULL) { + return FALSE; + } + + RetVal = FALSE; + BnX = BN_new (); + BnY = BN_new (); + if ((BnX == NULL) || (BnY == NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) { + goto fail; + } + + XSize = BN_num_bytes (BnX); + YSize = BN_num_bytes (BnY); + if ((XSize <= 0) || (YSize <= 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize); + + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + BOOLEAN RetVal; + + if ((EcContext == NULL) || (PublicKeySize == NULL)) { + return FALSE; + } + + if ((PublicKey == NULL) && (*PublicKeySize != 0)) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize = HalfSize * 2; + return FALSE; + } + + *PublicKeySize = HalfSize * 2; + + EcPoint = EC_KEY_get0_public_key (EcKey); + if (EcPoint == NULL) { + return FALSE; + } + + RetVal = FALSE; + BnX = BN_new (); + BnY = BN_new (); + if ((BnX == NULL) || (BnY == NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) { + goto fail; + } + + XSize = BN_num_bytes (BnX); + YSize = BN_num_bytes (BnY); + if ((XSize <= 0) || (YSize <= 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize); + + if (PublicKey != NULL) { + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + } + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If public key is compressed, the PeerPublic will only contain half key (X). + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + EC_KEY *EcKey; + EC_KEY *PeerEcKey; + CONST EC_GROUP *Group; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + EC_POINT *Point; + INT32 OpenSslNid; + UINTN HalfSize; + + if ((EcContext == NULL) || (PeerPublic == NULL) || (KeySize == NULL)) { + return FALSE; + } + + if ((Key == NULL) && (*KeySize != 0)) { + return FALSE; + } + + if (PeerPublicSize > INT_MAX) { + return FALSE; + } + + EcKey = (EC_KEY *)EcContext; + Group = EC_KEY_get0_group (EcKey); + HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8; + if ((CompressFlag == NULL) && (PeerPublicSize != HalfSize * 2)) { + return FALSE; + } + + if ((CompressFlag != NULL) && (PeerPublicSize != HalfSize)) { + return FALSE; + } + + if (*KeySize < HalfSize) { + *KeySize = HalfSize; + return FALSE; + } + + *KeySize = HalfSize; + + RetVal = FALSE; + Point = NULL; + BnX = BN_bin2bn (PeerPublic, (INT32)HalfSize, NULL); + BnY = NULL; + Point = EC_POINT_new (Group); + PeerEcKey = NULL; + if ((BnX == NULL) || (Point == NULL)) { + goto fail; + } + + if (CompressFlag == NULL) { + BnY = BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize, NULL); + if (BnY == NULL) { + goto fail; + } + + if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY, NULL) != 1) { + goto fail; + } + } else { + if (EC_POINT_set_compressed_coordinates (Group, Point, BnX, *CompressFlag, NULL) != 1) { + goto fail; + } + } + + // Validate NIST ECDH public key + OpenSslNid = EC_GROUP_get_curve_name (Group); + PeerEcKey = EC_KEY_new_by_curve_name (OpenSslNid); + if (PeerEcKey == NULL) { + goto fail; + } + + if (EC_KEY_set_public_key (PeerEcKey, Point) != 1) { + goto fail; + } + + if (EC_KEY_check_key (PeerEcKey) != 1) { + goto fail; + } + + if (ECDH_compute_key (Key, *KeySize, Point, EcKey, NULL) <= 0) { + goto fail; + } + + RetVal = TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + EC_POINT_free (Point); + EC_KEY_free (PeerEcKey); + return RetVal; +} diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseCryptLib.h> +#include <Library/DebugLib.h> + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf index ce6a789dfd..4bc3063485 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -59,6 +59,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPem.c Bn/CryptBnNull.c
diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf index 354f3d80aa..e1a57ef09f 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf @@ -49,6 +49,7 @@ Pk/CryptX509Null.c Pk/CryptAuthenticodeNull.c Pk/CryptTsNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Pk/CryptRsaPssNull.c diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseCryptLib.h> +#include <Library/DebugLib.h> + +/** + Initialize new opaque EcGroup object. This object represents an EC curve and + and is used for calculation within this group. This object should be freed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the corresponding + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the corresponding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult = EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point should + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A == B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value for x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where BnX is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initialized. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this function uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is returned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and successfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in bytes. + On output, the size of data returned in Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged common key, + based on its own context including value of curve parameter and random secret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or not. + @param[out] Key Pointer to the buffer to receive generated key. + @param[in, out] KeySize On input, the size of Key buffer in bytes. + On output, the size of data returned in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} -- 2.31.1.windows.1
|
|
Re: [PATCH v1 0/3] CryptoPkg/OpensslLib: Add native instruction support for IA32

Christopher Zurcher
I have verified performance gains and functional integrity in SHA256, SHA384, and SHA512 hashing as well as AES encryption on Intel hardware as well as QEMU. The assembly implementations included with this patch are limited to SHA and AES to reduce size impact, and to match the currently-available accelerations in the X64 equivalent library. These flows have also been validated on in-market hardware. Previous benchmarking of this code demonstrated a 12x speed improvement for SHA256 compared to the base algorithm.
Thanks, Christopher Zurcher
toggle quoted message
Show quoted text
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao, Jiewen Sent: Wednesday, September 21, 2022 17:54 To: Christopher Zurcher <zurcher@...>; devel@edk2.groups.io Cc: Li, Yi1 <yi1.li@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: Re: [edk2-devel] [PATCH v1 0/3] CryptoPkg/OpensslLib: Add native instruction support for IA32 Thanks. Would you please add more detailed description on what test you have done? e.g. Real platform? Unit Test? Etc. -----Original Message----- From: Christopher Zurcher <zurcher@...> Sent: Thursday, September 22, 2022 4:26 AM To: devel@edk2.groups.io Cc: Li, Yi1 <yi1.li@...>; Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: [PATCH v1 0/3] CryptoPkg/OpensslLib: Add native instruction support for IA32
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3654 PR: https://github.com/tianocore/edk2/pull/3352
This patch adds support for building the native instruction algorithms for the IA32 architecture in OpensslLib. The base variant has been tested with VS2019 and CLANGPDB toolchains, and a GCC variant is also provided.
The implementation here follows the previous implementation of X64 native instructions as committed in 878a92a887.
Cc: Yi Li <yi1.li@...> Cc: Jiewen Yao <jiewen.yao@...> Cc: Jian J Wang <jian.j.wang@...> Cc: Xiaoyu Lu <xiaoyu1.lu@...> Cc: Guomin Jiang <guomin.jiang@...>
Christopher Zurcher (3): CryptoPkg/OpensslLib: Add native instruction support for IA32 CryptoPkg/OpensslLib: Commit the auto-generated assembly files for IA32 CryptoPkg/OpensslLib: Update generated files for native X64
CryptoPkg/CryptoPkg.ci.yaml | 4 + CryptoPkg/Library/OpensslLib/IA32/crypto/aes/aesni-x86.nasm | 3212 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/aes/vpaes-x86.nasm | 651 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/modes/ghash-x86.nasm | 700 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha1-586.nasm | 1394 ++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha256-586.nasm | 3364 ++++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha512-586.nasm | 579 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/x86cpuid.nasm | 433 +++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/aesni-x86.S | 3247 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/vpaes-x86.S | 670 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/modes/ghash-x86.S | 703 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha1-586.S | 1389 ++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha256-586.S | 3356 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha512-586.S | 574 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/x86cpuid.S | 449 +++ CryptoPkg/Library/OpensslLib/OpensslLibIa32.inf | 699 ++++ CryptoPkg/Library/OpensslLib/OpensslLibIa32Gcc.inf | 699 ++++ CryptoPkg/Library/OpensslLib/OpensslLibX64.inf | 53 + CryptoPkg/Library/OpensslLib/OpensslLibX64Gcc.inf | 53 + CryptoPkg/Library/OpensslLib/UefiAsm.conf | 18 + CryptoPkg/Library/OpensslLib/process_files.pl | 12 + 21 files changed, 22259 insertions(+) create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/aes/aesni-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/aes/vpaes-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/modes/ghash-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha1- 586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha256-586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha512-586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/x86cpuid.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/aesni-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/vpaes-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/modes/ghash-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha1-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha256-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha512-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/x86cpuid.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslLibIa32.inf create mode 100644 CryptoPkg/Library/OpensslLib/OpensslLibIa32Gcc.inf
-- 2.29.2.windows.2
|
|
Re: [PATCH v1 0/3] CryptoPkg/OpensslLib: Add native instruction support for IA32
Thanks. Would you please add more detailed description on what test you have done?
e.g. Real platform? Unit Test? Etc.
toggle quoted message
Show quoted text
-----Original Message----- From: Christopher Zurcher <zurcher@...> Sent: Thursday, September 22, 2022 4:26 AM To: devel@edk2.groups.io Cc: Li, Yi1 <yi1.li@...>; Yao, Jiewen <jiewen.yao@...>; Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...> Subject: [PATCH v1 0/3] CryptoPkg/OpensslLib: Add native instruction support for IA32
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3654 PR: https://github.com/tianocore/edk2/pull/3352
This patch adds support for building the native instruction algorithms for the IA32 architecture in OpensslLib. The base variant has been tested with VS2019 and CLANGPDB toolchains, and a GCC variant is also provided.
The implementation here follows the previous implementation of X64 native instructions as committed in 878a92a887.
Cc: Yi Li <yi1.li@...> Cc: Jiewen Yao <jiewen.yao@...> Cc: Jian J Wang <jian.j.wang@...> Cc: Xiaoyu Lu <xiaoyu1.lu@...> Cc: Guomin Jiang <guomin.jiang@...>
Christopher Zurcher (3): CryptoPkg/OpensslLib: Add native instruction support for IA32 CryptoPkg/OpensslLib: Commit the auto-generated assembly files for IA32 CryptoPkg/OpensslLib: Update generated files for native X64
CryptoPkg/CryptoPkg.ci.yaml | 4 + CryptoPkg/Library/OpensslLib/IA32/crypto/aes/aesni-x86.nasm | 3212 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/aes/vpaes-x86.nasm | 651 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/modes/ghash-x86.nasm | 700 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha1-586.nasm | 1394 ++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha256-586.nasm | 3364 ++++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha512-586.nasm | 579 ++++ CryptoPkg/Library/OpensslLib/IA32/crypto/x86cpuid.nasm | 433 +++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/aesni-x86.S | 3247 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/vpaes-x86.S | 670 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/modes/ghash-x86.S | 703 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha1-586.S | 1389 ++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha256-586.S | 3356 +++++++++++++++++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha512-586.S | 574 ++++ CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/x86cpuid.S | 449 +++ CryptoPkg/Library/OpensslLib/OpensslLibIa32.inf | 699 ++++ CryptoPkg/Library/OpensslLib/OpensslLibIa32Gcc.inf | 699 ++++ CryptoPkg/Library/OpensslLib/OpensslLibX64.inf | 53 + CryptoPkg/Library/OpensslLib/OpensslLibX64Gcc.inf | 53 + CryptoPkg/Library/OpensslLib/UefiAsm.conf | 18 + CryptoPkg/Library/OpensslLib/process_files.pl | 12 + 21 files changed, 22259 insertions(+) create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/aes/aesni-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/aes/vpaes-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/modes/ghash-x86.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha1- 586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha256-586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/sha/sha512-586.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32/crypto/x86cpuid.nasm create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/aesni-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/aes/vpaes-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/modes/ghash-x86.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha1-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha256-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/sha/sha512-586.S create mode 100644 CryptoPkg/Library/OpensslLib/IA32Gcc/crypto/x86cpuid.S create mode 100644 CryptoPkg/Library/OpensslLib/OpensslLibIa32.inf create mode 100644 CryptoPkg/Library/OpensslLib/OpensslLibIa32Gcc.inf
-- 2.29.2.windows.2
|
|
Re: [PATCH v5 3/4] CI: Use Fedora 35 container (Linux only)
There is probably value in having both if we want to support various flavors of containers in the future, but yes adding a container option to the template similar to vm_image.
Thanks, Chris
toggle quoted message
Show quoted text
On 9/21/2022 1:26 AM, Gerd Hoffmann wrote: On Tue, Sep 20, 2022 at 01:01:04PM -0700, Chris Fernald wrote:
Similar to my comment about the assumption in use of python, I believe the container should be determined and passed in as a parameter from the top level pipeline file rather then relying on tool chain tag. This lets the templates take action on being containerized rather then assuming the tool chain. Additionally, this would give consistency between the platform and PR templates which currently make opposite assumption about consumer vs template determining the container image. i.e. update .azurepipelines/Ubuntu-GCC5.yml and replace "vm_image: ..." with "container: ..."? take care, Gerd
|
|
toggle quoted message
Show quoted text
Thank you Sean and Mike!
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean
Sent: Wednesday, September 21, 2022 8:01 AM
To: devel@edk2.groups.io; Kinney, Michael D
<michael.d.kinney@...>; Yao, Jiewen <jiewen.yao@...>;
Kubacki, Michael <michael.kubacki@...>; Sean Brogan
<sean.brogan@...>
Subject: Re: [edk2-devel] EDKII CI Failure
Looking at it.
The vm image for VS2019 did change between working and failing build.
Will update once we figure something out.
Thanks
Sean
On 9/20/2022 4:36 PM, Michael D Kinney wrote:
Hi Jiewen,
Looks like it is not limited to that one PR.
I see this PR has similar failure. The artifacts show a more detailed log
with nmake.exe not found. That does not make sense for a
windows/VS2019
build after vswhere is used to find path to VS2019 tools. Perhaps Michael
or Sean can help evaluate. Maybe there was a change in the Windows
agent
profile or the VS2019 tools profile.
https://github.com/tianocore/edk2/pull/3354
https://dev.azure.com/tianocore/edk2-
ci/_build/results?buildId=62007&view=logs&jobId=4a97f94c-8e1f-5e76-
68ba-50872604dd63&j=898a5c7a-7a49-5be1-c417-92a6761a8039
INFO - Log Started: Tuesday, September 20, 2022 02:49PM
SECTION - Init SDE
DEBUG - --- self_describing_environment.__init__()
DEBUG - Skipped directories specified = ()
DEBUG - --- self_describing_environment.load_workspace()
DEBUG - Loading workspace: D:\a\1\s\BaseTools
DEBUG - Including scopes: global
DEBUG - --- self_describing_environment._gather_env_files()
DEBUG - Adding descriptor
D:\a\1\s\BaseTools\basetools_calling_path_env.yaml to the environment
with scope global
DEBUG - Adding descriptor D:\a\1\s\BaseTools\basetools_path_env.yaml
to the environment with scope global
DEBUG - Adding descriptor
D:\a\1\s\BaseTools\Source\Python\basetool_tiano_python_path_env.yam
l to the environment with scope global
DEBUG - Adding descriptor
D:\a\1\s\BaseTools\Plugin\BuildToolsReport\BuildToolsReportGenerator_p
lug_in.yaml to the environment with scope global
DEBUG - --- self_describing_environment.update_simple_paths()
DEBUG - --- self_describing_environment.update_extdep_paths()
DEBUG - --- self_describing_environment.report_extdep_version()
SECTION - Loading Plugins
DEBUG - Loading Plugin from
D:\a\1\s\BaseTools\Plugin\BuildToolsReport\BuildToolsReportGenerator.p
y
SECTION - Start Invocable Tool
INFO - Running Python version: sys.version_info(major=3, minor=10,
micro=7, releaselevel='final', serial=0)
INFO - Cmd to run is:
c:\hostedtoolcache\windows\python\3.10.7\x64\lib\site-
packages\edk2toollib\bin\vswhere.exe -latest -nologo -all -property
installationPath -products * -version 16.0,17.0
INFO - ------------------------------------------------
INFO - --------------Cmd Output Starting---------------
INFO - ------------------------------------------------
INFO - C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise
INFO - ------------------------------------------------
INFO - --------------Cmd Output Finished---------------
INFO - --------- Running Time (mm:ss): 00:00 ----------
INFO - ----------- Return Code: 0x00000000 ------------
INFO - ------------------------------------------------
DEBUG - Calling 'C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat x86'
DEBUG - Var - ExtensionSdkDir = C:\Program Files (x86)\Microsoft
SDKs\Windows Kits\10\ExtensionSDKs
DEBUG - Var - INCLUDE = C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\include;C:\
Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include;C:\Program
Files (x86)\Windows Kits\NETFXSDK\4.8\include\um;C:\Program Files
(x86)\Windows Kits\10\include\10.0.22621.0\ucrt;C:\Program Files
(x86)\Windows Kits\10\include\10.0.22621.0\shared;C:\Program Files
(x86)\Windows Kits\10\include\10.0.22621.0\um;C:\Program Files
(x86)\Windows Kits\10\include\10.0.22621.0\winrt;C:\Program Files
(x86)\Windows Kits\10\include\10.0.22621.0\cppwinrt
DEBUG - Var - LIB = C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x86;C:\
Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x86;C:\Program
Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x86;C:\Program Files
(x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x86;C:\Program Files
(x86)\Windows Kits\10\lib\10.0.22621.0\um\x86
DEBUG - Var - LIBPATH = C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x86;C:\
Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x86;C:\Program
Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x86\store\refere
nces;C:\Program Files (x86)\Windows
Kits\10\UnionMetadata\10.0.22621.0;C:\Program Files (x86)\Windows
Kits\10\References\10.0.22621.0;C:\Windows\Microsoft.NET\Framework\
v4.0.30319
DEBUG - Var - Path = C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\\Extensions\Microsoft\IntelliCode\
CLI;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86;C:
\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\Tes
tWindow;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\Tea
mFoundation\Team Explorer;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\MSBuild\Current\bin\Roslyn;C:\Program Files
(x86)\Microsoft Visual Studio\2019\Enterprise\Team Tools\Performance
Tools;C:\Program Files (x86)\Microsoft Visual
Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files
(x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\;C:\Program
Files (x86)\HTML Help Workshop;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\FSh
arp\Tools;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\Tools\devinit;C:\Program Files
(x86)\Windows Kits\10\bin\10.0.22621.0\x86;C:\Program Files
(x86)\Windows Kits\10\bin\x86;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\\MSBuild\Current\Bin;C:\Windows\Microsoft.NET
\Framework\v4.0.30319;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\;C:\Program Files (x86)\Microsoft
Visual
Studio\2019\Enterprise\Common7\Tools\;C:\hostedtoolcache\windows\n
ode\14.20.0\x64;C:\Users\VssAdministrator\AppData\Roaming\Python\Py
thon310\Scripts;C:\hostedtoolcache\windows\Python\3.10.7\x64\Scripts;
C:\hostedtoolcache\windows\Python\3.10.7\x64;C:\agents\2.210.1\extern
als\git\cmd;C:\agents\2.210.1\externals\git\mingw64\bin;C:\Program
Files\MongoDB\Server\5.0\bin;C:\aliyun-cli;C:\vcpkg;C:\cf-cli;C:\Program
Files (x86)\NSIS\;C:\tools\zstd;C:\Program
Files\Mercurial\;C:\hostedtoolcache\windows\stack\2.7.5\x64;C:\cabal\bi
n;C:\\ghcup\bin;C:\tools\ghc-9.4.2\bin;C:\Program
Files\dotnet;C:\mysql\bin;C:\Program Files\R\R-
4.2.1\bin\x64;C:\SeleniumWebDrivers\GeckoDriver;C:\Program Files
(x86)\sbt\bin;C:\Program Files (x86)\GitHub CLI;C:\Program
Files\Git\bin;C:\Program Files
(x86)\pipx_bin;C:\npm\prefix;C:\hostedtoolcache\windows\go\1.17.13\x6
4\bin;C:\hostedtoolcache\windows\Python\3.7.9\x64\Scripts;C:\hostedto
olcache\windows\Python\3.7.9\x64;C:\hostedtoolcache\windows\Ruby\2.
5.9\x64\bin;C:\tools\kotlinc\bin;C:\hostedtoolcache\windows\Java_Temur
in-Hotspot_jdk\8.0.345-1\x64\bin;C:\Program Files\ImageMagick-7.1.0-
Q16-HDRI;C:\Program Files (x86)\Microsoft
SDKs\Azure\CLI2\wbin;C:\ProgramData\kind;C:\Program Files\Eclipse
Foundation\jdk-8.0.302.8-
hotspot\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\
Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\Sys
tem32\OpenSSH\;C:\ProgramData\Chocolatey\bin;C:\Program
Files\PowerShell\7\;C:\Program Files\Microsoft\Web Platform
Installer\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL
Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client
SDK\ODBC\170\Tools\Binn\;C:\Program Files (x86)\Windows
Kits\10\Windows Performance Toolkit\;C:\Program Files (x86)\Microsoft
SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL
Server\120\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL
Server\130\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL
Server\140\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL
Server\150\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL
Server\160\DTS\Binn\;C:\Program
Files\OpenSSL\bin;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Stra
wberry\perl\bin;C:\ProgramData\chocolatey\lib\pulumi\tools\Pulumi\bin;
C:\Program Files\TortoiseSVN\bin;C:\Program
Files\CMake\bin;C:\ProgramData\chocolatey\lib\maven\apache-maven-
3.8.6\bin;C:\Program Files\Microsoft Service
Fabric\bin\Fabric\Fabric.Code;C:\Program Files\Microsoft SDKs\Service
Fabric\Tools\ServiceFabricLocalClusterManager;C:\Program
Files\nodejs\;C:\Program Files\Git\cmd;C:\Program
Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program
Files\GitHub CLI\;c:\tools\php;C:\Program Files
(x86)\sbt\bin;C:\SeleniumWebDrivers\ChromeDriver\;C:\SeleniumWebDriv
ers\EdgeDriver\;C:\Program Files\Amazon\AWSCLIV2\;C:\Program
Files\Amazon\SessionManagerPlugin\bin\;C:\Program
Files\Amazon\AWSSAMCLI\bin\;C:\Program Files (x86)\Google\Cloud
SDK\google-cloud-sdk\bin;C:\Program Files (x86)\Microsoft BizTalk
Server\;C:\Program
Files\LLVM\bin;C:\Users\VssAdministrator\.dotnet\tools;C:\Users\VssAdm
inistrator\.cargo\bin;C:\Users\VssAdministrator\AppData\Local\Microsoft\
WindowsApps;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\Llvm\bin;C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CM
ake\CMake\bin;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CM
ake\Ninja;C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\Common7\IDE\VC\Linux\bin\ConnectionManagerE
xe
DEBUG - Var - UCRTVersion = 10.0.22621.0
DEBUG - Var - UniversalCRTSdkDir = C:\Program Files (x86)\Windows
Kits\10\
DEBUG - Var - VCToolsInstallDir = C:\Program Files (x86)\Microsoft Visual
Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\
DEBUG - Var - WindowsLibPath = C:\Program Files (x86)\Windows
Kits\10\UnionMetadata\10.0.22621.0;C:\Program Files (x86)\Windows
Kits\10\References\10.0.22621.0
DEBUG - Var - WindowsSdkBinPath = C:\Program Files (x86)\Windows
Kits\10\bin\
DEBUG - Var - WindowsSdkDir = C:\Program Files (x86)\Windows Kits\10\
DEBUG - Var - WindowsSdkVerBinPath = C:\Program Files (x86)\Windows
Kits\10\bin\10.0.22621.0\
DEBUG - Var - WindowsSDKVersion = 10.0.22621.0\
INFO - Cmd to run is: nmake.exe
INFO - ------------------------------------------------
INFO - --------------Cmd Output Starting---------------
INFO - ------------------------------------------------
INFO - 'nmake.exe' is not recognized as an internal or external command,
INFO - operable program or batch file.
INFO - ------------------------------------------------
INFO - --------------Cmd Output Finished---------------
INFO - --------- Running Time (mm:ss): 00:00 ----------
INFO - ----------- Return Code: 0x00000001 ------------
INFO - ------------------------------------------------
Mike
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao,
Jiewen
Sent: Tuesday, September 20, 2022 4:06 PM
To: devel@edk2.groups.io
Subject: [edk2-devel] EDKII CI Failure
Hi
I notice that EDKII CI failed on step "Build Base Tools from source" for
https://github.com/DMTF/libspdm/pull/1218
https://dev.azure.com/tianocore/edk2-
ci/_build/results?buildId=62090&view=logs&j=c0929384-5a08-5c0f-b36d-
6f51b6b81732&t=dc6c8514-4845-5cff-3ead-20e6776e3d52
Anyone knows what is happening on the CI?
Thank you
Yao Jiewen
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao,
Jiewen
Sent: Wednesday, September 21, 2022 7:03 AM
To: Wenyi Xie <xiewenyi2@...>; devel@edk2.groups.io; Wang,
Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>;
Jiang,
Guomin <guomin.jiang@...>
Cc: songdongkuang@...
Subject: Re: [edk2-devel] [PATCH EDK2 v1 1/1]
CryptoPkg/BaseCryptLib:Remove redundant init
Reviewed-by: Jiewen Yao <Jiewen.yao@...>
-----Original Message-----
From: Wenyi Xie <xiewenyi2@...>
Sent: Thursday, September 15, 2022 5:26 PM
To: devel@edk2.groups.io; Yao, Jiewen <jiewen.yao@...>;
Wang,
Jian
J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,
Guomin <guomin.jiang@...>
Cc: songdongkuang@...; xiewenyi2@...
Subject: [PATCH EDK2 v1 1/1] CryptoPkg/BaseCryptLib:Remove
redundant
init
CertCtx is used to be defined as a struct and ZeroMem is called to
init this struct. But now CertCtx is defined as a point, so use
ZeroMem (&CertCtx, sizeof (CertCtx)) is not correct any more.
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyu1.lu@...>
Cc: Guomin Jiang <guomin.jiang@...>
Signed-off-by: Wenyi Xie <xiewenyi2@...>
---
CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c | 2
--
1 file changed, 2 deletions(-)
diff --git
a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
index 3336d2f60a6a..f8028181e47f 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
+++
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
@@ -502,8 +502,6 @@ Pkcs7GetCertificatesList (
OldBuf = NULL;
Signers = NULL;
- ZeroMem (&CertCtx, sizeof (CertCtx));
-
//
// Parameter Checking
//
--
2.20.1.windows.1
|
|
Re: [PATCH v1 1/1] BaseTools: Edk2ToolsBuild: Fixing pipeline build due to path too long
Reviewed-by: Sean Brogan <sean.brogan@...>
toggle quoted message
Show quoted text
On 9/21/2022 1:44 PM, Kun Qin wrote: From: Sean Brogan <sean.brogan@...>
Current implementation of looking up toolchain will _insert_ the findings from vsvarsall.bat to existing path and potentially stuff the variable to exceed the length of maximal path length accepted by Windows.
This change updated the logic to use the discovered shell varialbes to replace the existing path, which is desirable in the specific use case.
Cc: Bob Feng <bob.c.feng@...> Cc: Liming Gao <gaoliming@...> Cc: Yuwei Chen <yuwei.chen@...>
Co-authored-by: Sean Brogan <sean.brogan@...> Signed-off-by: Kun Qin <kuqin12@...> --- BaseTools/Edk2ToolsBuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/BaseTools/Edk2ToolsBuild.py b/BaseTools/Edk2ToolsBuild.py index 1ea8187de693..f862468ce275 100644 --- a/BaseTools/Edk2ToolsBuild.py +++ b/BaseTools/Edk2ToolsBuild.py @@ -122,7 +122,7 @@ class Edk2ToolsBuild(BaseAbstractInvocable): for key in vc_vars.keys():
logging.debug(f"Var - {key} = {vc_vars[key]}")
if key.lower() == 'path':
- shell_env.insert_path(vc_vars[key])
+ shell_env.set_path(vc_vars[key])
else:
shell_env.set_shell_var(key, vc_vars[key])
|
|
[[edk2-staging/HttpProxy] 3/3] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot
Add CONNECT HTTP command to create a tunnel from Proxy to EndPoint Server. Process the multi-URI device path in the input FilePath.
Cc: Maciej Rabeda <maciej.rabeda@...> Cc: Wu Jiaxin <jiaxin.wu@...> Cc: Siyuan Fu <siyuan.fu@...> Signed-off-by: Saloni Kasbekar <saloni.kasbekar@...> --- NetworkPkg/HttpBootDxe/HttpBootClient.c | 211 ++++++++++++++++- NetworkPkg/HttpBootDxe/HttpBootClient.h | 15 ++ NetworkPkg/HttpBootDxe/HttpBootDxe.h | 6 + NetworkPkg/HttpBootDxe/HttpBootImpl.c | 262 ++++++++++++++++----- NetworkPkg/HttpBootDxe/HttpBootImpl.h | 8 + NetworkPkg/HttpBootDxe/HttpBootSupport.c | 24 +- NetworkPkg/HttpBootDxe/HttpBootSupport.h | 8 +- NetworkPkg/HttpDxe/HttpDriver.h | 2 + NetworkPkg/HttpDxe/HttpDxe.inf | 1 + NetworkPkg/HttpDxe/HttpImpl.c | 139 +++++++++-- NetworkPkg/HttpDxe/HttpProto.c | 41 ++-- NetworkPkg/HttpDxe/HttpProto.h | 14 +- NetworkPkg/HttpDxe/HttpsSupport.c | 14 +- NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c | 5 + 14 files changed, 642 insertions(+), 108 deletions(-)
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 40f64fcb6b..bfad4809de 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -678,6 +678,10 @@ HttpBootFreeCache ( FreePool (Cache->RequestData->Url); } + if (Cache->RequestData->EndPointUrl != NULL) { + FreePool (Cache->RequestData->EndPointUrl); + } + FreePool (Cache->RequestData); } @@ -901,6 +905,189 @@ HttpBootGetBootFileCallback ( return EFI_SUCCESS; } +/** + This function establishes a connection through a proxy server + + @param[in] Private The pointer to the driver's private data. + + @retval EFI_SUCCESS Connection successful. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources + @retval Others Unexpected error happened. + +**/ +EFI_STATUS +HttpBootConnectProxy ( + IN HTTP_BOOT_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + EFI_HTTP_STATUS_CODE StatusCode; + CHAR8 *HostName; + EFI_HTTP_REQUEST_DATA *RequestData; + HTTP_IO_RESPONSE_DATA *ResponseData; + HTTP_IO *HttpIo; + HTTP_IO_HEADER *HttpIoHeader; + CHAR16 *Url; + CHAR16 *EndPointUrl; + UINTN UrlSize; + VOID *UrlParser; + + Url = NULL; + EndPointUrl = NULL; + RequestData = NULL; + ResponseData = NULL; + HttpIoHeader = NULL; + + UrlSize = AsciiStrSize (Private->BootFileUri); + Url = AllocatePool (UrlSize * sizeof (CHAR16)); + if (Url == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize); + + UrlSize = AsciiStrSize (Private->EndPointUri); + EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16))); + if (EndPointUrl == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + AsciiStrToUnicodeStrS (Private->EndPointUri, EndPointUrl, UrlSize); + + // + // Send HTTP request message. + // + + // + // Build HTTP header for the request, 2 headers are needed to send a CONNECT method: + // Host + // User + // + HttpIoHeader = HttpIoCreateHeader (2); + if (HttpIoHeader == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + // + // Add HTTP header field 1: Host (EndPoint URI) + // + Status = HttpParseUrl (Private->EndPointUri, (UINT32)AsciiStrLen (Private->EndPointUri), FALSE, &UrlParser); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + Status = HttpUrlGetHostName ( + Private->EndPointUri, + UrlParser, + &HostName + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + Status = HttpIoSetHeader ( + HttpIoHeader, + HTTP_HEADER_HOST, + HostName + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + // + // Add HTTP header field 2: User-Agent + // + Status = HttpIoSetHeader ( + HttpIoHeader, + HTTP_HEADER_USER_AGENT, + HTTP_USER_AGENT_EFI_HTTP_BOOT + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + // + // Build the rest of HTTP request info. + // + RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA)); + if (RequestData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + RequestData->Method = HttpMethodConnect; + RequestData->Url = Url; + RequestData->EndPointUrl = EndPointUrl; + + // + // Send out the request to HTTP server. + // + HttpIo = &Private->HttpIo; + Status = HttpIoSendRequest ( + HttpIo, + RequestData, + HttpIoHeader->HeaderCount, + HttpIoHeader->Headers, + 0, + NULL + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + // + // Receive HTTP response message. + // + + // + // Use zero BodyLength to only receive the response headers. + // + ResponseData = AllocateZeroPool (sizeof (HTTP_IO_RESPONSE_DATA)); + if (ResponseData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + Status = HttpIoRecvResponse ( + &Private->HttpIo, + TRUE, + ResponseData + ); + + if (EFI_ERROR (Status) || EFI_ERROR (ResponseData->Status)) { + if (EFI_ERROR (ResponseData->Status)) { + StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode; + HttpBootPrintErrorMessage (StatusCode); + Status = ResponseData->Status; + } + + goto ERROR; + } + +ERROR: + if (ResponseData != NULL) { + FreePool (ResponseData); + } + + if (RequestData != NULL) { + FreePool (RequestData); + } + + HttpIoFreeHeader (HttpIoHeader); + + if (EndPointUrl != NULL) { + FreePool (EndPointUrl); + } + + if (Url != NULL) { + FreePool (Url); + } + + return Status; +} + /** This function download the boot file by using UEFI HTTP protocol. @@ -950,6 +1137,7 @@ HttpBootGetBootFile ( UINT8 *Block; UINTN UrlSize; CHAR16 *Url; + CHAR16 *EndPointUrl; BOOLEAN IdentityMode; UINTN ReceivedSize; CHAR8 BaseAuthValue[80]; @@ -977,6 +1165,20 @@ HttpBootGetBootFile ( } AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize); + + if (Private->EndPointUri != NULL) { + UrlSize = AsciiStrSize (Private->EndPointUri); + EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16))); + if (EndPointUrl == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR_1; + } + + AsciiStrToUnicodeStrS (Private->EndPointUri, EndPointUrl, UrlSize); + } else { + EndPointUrl = NULL; + } + if (!HeaderOnly && (Buffer != NULL)) { Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType); if (Status != EFI_NOT_FOUND) { @@ -1106,8 +1308,9 @@ HttpBootGetBootFile ( goto ERROR_3; } - RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet; - RequestData->Url = Url; + RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet; + RequestData->Url = Url; + RequestData->EndPointUrl = EndPointUrl; // // 2.3 Record the request info in a temp cache item. @@ -1441,6 +1644,10 @@ ERROR_2: } ERROR_1: + if (EndPointUrl != NULL) { + FreePool (EndPointUrl); + } + if (Url != NULL) { FreePool (Url); } diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h index 2fba713679..fcd624f536 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.h +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h @@ -86,6 +86,21 @@ HttpBootCreateHttpIo ( IN HTTP_BOOT_PRIVATE_DATA *Private ); +/** + This function establishes a connection through a proxy server + + @param[in] Private The pointer to the driver's private data. + + @retval EFI_SUCCESS Connection successful. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources + @retval Others Unexpected error happened. + +**/ +EFI_STATUS +HttpBootConnectProxy ( + IN HTTP_BOOT_PRIVATE_DATA *Private + ); + /** This function download the boot file by using UEFI HTTP protocol. diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h index 5ff8ad4698..e2eb1ffc45 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -223,6 +223,12 @@ struct _HTTP_BOOT_PRIVATE_DATA { CHAR8 *FilePathUri; VOID *FilePathUriParser; + // + // URI string for the endpoint host if BootFileUri contains a proxy + // server in the path + // + CHAR8 *EndPointUri; + // // Cached HTTP data // diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index b4c61925b9..6fafd800bd 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -116,8 +116,14 @@ HttpBootStart ( UINTN Index; EFI_STATUS Status; CHAR8 *Uri; + CHAR8 *EndPointUri; + CHAR8 *BootFilePath; + UINTN FilePathUriLen; + UINTN EndPointUriLen; - Uri = NULL; + Uri = NULL; + EndPointUri = NULL; + BootFilePath = NULL; if ((Private == NULL) || (FilePath == NULL)) { return EFI_INVALID_PARAMETER; @@ -127,7 +133,7 @@ HttpBootStart ( // Check the URI in the input FilePath, in order to see whether it is // required to boot from a new specified boot file. // - Status = HttpBootParseFilePath (FilePath, &Uri); + Status = HttpBootParseFilePath (FilePath, &Uri, &EndPointUri); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } @@ -154,6 +160,10 @@ HttpBootStart ( FreePool (Uri); } + if (EndPointUri != NULL) { + FreePool (EndPointUri); + } + return Status; } } else { @@ -164,6 +174,10 @@ HttpBootStart ( FreePool (Uri); } + if (EndPointUri != NULL) { + FreePool (EndPointUri); + } + return EFI_ALREADY_STARTED; } } @@ -180,13 +194,63 @@ HttpBootStart ( FreePool (Uri); } + if (EndPointUri != NULL) { + FreePool (EndPointUri); + } + return EFI_UNSUPPORTED; } // // Record the specified URI and prepare the URI parser if needed. // - Private->FilePathUri = Uri; + Private->EndPointUri = EndPointUri; + if (Private->EndPointUri != NULL) { + // + // When a Proxy Server URI is included in the device path, the file path + // is a part of the EndPoint URI. + // Move the file path from EndPointUri to FilePathUri + // + Status = HttpParseUrl ( + Private->EndPointUri, + (UINT32)AsciiStrLen (Private->EndPointUri), + FALSE, + &Private->FilePathUriParser + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = HttpUrlGetPath ( + Private->EndPointUri, + Private->FilePathUriParser, + &BootFilePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Remove the file path from EndPointUri + // + EndPointUriLen = AsciiStrLen (EndPointUri) - AsciiStrLen (BootFilePath) + 1; + Private->EndPointUri = AllocateZeroPool (EndPointUriLen); + AsciiSPrint (Private->EndPointUri, EndPointUriLen, "%a", EndPointUri); + + // + // Add the file path to FilePathUri + // + FilePathUriLen = AsciiStrLen (Uri) + AsciiStrLen (BootFilePath) + 1; + Private->FilePathUri = AllocateZeroPool (FilePathUriLen); + AsciiSPrint (Private->FilePathUri, FilePathUriLen, "%a%a", Uri, BootFilePath); + + FreePool (BootFilePath); + FreePool (Private->FilePathUriParser); + FreePool (EndPointUri); + } else { + Private->FilePathUri = Uri; + } + if (Private->FilePathUri != NULL) { Status = HttpParseUrl ( Private->FilePathUri, @@ -274,6 +338,136 @@ HttpBootDhcp ( return Status; } +/** + Issue calls to HttpBootGetBootFile() based on current Boot File State + + @param[in] Private The pointer to the driver's private data. + @param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return + code of EFI_SUCCESS, the amount of data transferred to + Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, + the size of Buffer required to retrieve the requested file. + @param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL, + then the size of the requested file is returned in + BufferSize. + @param[out] ImageType The image type of the downloaded file. + + @retval EFI_SUCCESS The file was loaded. + @retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. + @retval EFI_ACCESS_DENIED Server authentication failed. + @retval Others Unexpected error happened. + +**/ +EFI_STATUS +HttpBootGetBootFileCaller ( + IN HTTP_BOOT_PRIVATE_DATA *Private, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL, + OUT HTTP_BOOT_IMAGE_TYPE *ImageType + ) +{ + HTTP_GET_BOOT_FILE_STATE State; + EFI_STATUS Status; + + if (Private->BootFileSize == 0) { + if (Private->EndPointUri != NULL) { + State = ConnectToProxy; + } else { + State = GetBootFileHead; + } + } else { + State = LoadBootFile; + } + + for ( ; ;) { + switch (State) { + case GetBootFileHead: + // + // Try to use HTTP HEAD method. + // + Status = HttpBootGetBootFile ( + Private, + TRUE, + &Private->BootFileSize, + NULL, + &Private->ImageType + ); + if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) { + if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) { + // + // Try to use HTTP HEAD method again since the Authentication information is provided. + // + State = GetBootFileHead; + } else { + State = GetBootFileGet; + } + } else { + State = LoadBootFile; + } + + break; + + case GetBootFileGet: + // + // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method. + // + ASSERT (Private->BootFileSize == 0); + Status = HttpBootGetBootFile ( + Private, + FALSE, + &Private->BootFileSize, + NULL, + &Private->ImageType + ); + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + State = GetBootFileError; + } else { + State = LoadBootFile; + } + + break; + + case ConnectToProxy: + Status = HttpBootConnectProxy (Private); + if (Status == EFI_SUCCESS) { + State = GetBootFileHead; + } else { + State = GetBootFileError; + } + + break; + + case LoadBootFile: + if (*BufferSize < Private->BootFileSize) { + *BufferSize = Private->BootFileSize; + *ImageType = Private->ImageType; + Status = EFI_BUFFER_TOO_SMALL; + return Status; + } + + // + // Load the boot file into Buffer + // + Status = HttpBootGetBootFile ( + Private, + FALSE, + BufferSize, + Buffer, + ImageType + ); + return Status; + + case GetBootFileError: + default: + AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); + return Status; + } + } +} + /** Attempt to download the boot file through HTTP message exchange. @@ -345,68 +539,10 @@ HttpBootLoadFile ( } } - if (Private->BootFileSize == 0) { - // - // Discover the information about the bootfile if we haven't. - // - - // - // Try to use HTTP HEAD method. - // - Status = HttpBootGetBootFile ( - Private, - TRUE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) { - // - // Try to use HTTP HEAD method again since the Authentication information is provided. - // - Status = HttpBootGetBootFile ( - Private, - TRUE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) { - // - // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method. - // - ASSERT (Private->BootFileSize == 0); - Status = HttpBootGetBootFile ( - Private, - FALSE, - &Private->BootFileSize, - NULL, - &Private->ImageType - ); - if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { - AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); - goto ON_EXIT; - } - } - } - - if (*BufferSize < Private->BootFileSize) { - *BufferSize = Private->BootFileSize; - *ImageType = Private->ImageType; - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - // - // Load the boot file into Buffer + // Load the Boot File // - Status = HttpBootGetBootFile ( - Private, - FALSE, - BufferSize, - Buffer, - ImageType - ); + Status = HttpBootGetBootFileCaller (Private, BufferSize, Buffer, ImageType); ON_EXIT: HttpBootUninstallCallback (Private); diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h index 55adc9cb50..e4ffc3ed48 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h @@ -11,6 +11,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define HTTP_BOOT_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) +typedef enum { + GetBootFileHead, + GetBootFileGet, + ConnectToProxy, + LoadBootFile, + GetBootFileError +} HTTP_GET_BOOT_FILE_STATE; + /** Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information. diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c index 236ef25931..c857488036 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -558,6 +558,7 @@ HttpBootCheckUriScheme ( @param[in] FilePath Pointer to the device path which contains a URI device path node. @param[out] UriAddress The URI address string extract from the device path. + @param[out] EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server @retval EFI_SUCCESS The URI string is returned. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @@ -566,19 +567,24 @@ HttpBootCheckUriScheme ( EFI_STATUS HttpBootParseFilePath ( IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - OUT CHAR8 **UriAddress + OUT CHAR8 **UriAddress, + OUT CHAR8 **EndPointUriAddress ) { EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; URI_DEVICE_PATH *UriDevicePath; CHAR8 *Uri; + CHAR8 *TempUri; UINTN UriStrLength; if (FilePath == NULL) { return EFI_INVALID_PARAMETER; } - *UriAddress = NULL; + Uri = NULL; + *UriAddress = NULL; + *EndPointUriAddress = NULL; + TempUri = NULL; // // Extract the URI address from the FilePath @@ -601,6 +607,15 @@ HttpBootParseFilePath ( break; } + if (Uri != NULL) { + // + // Device Path with Proxy Server will be described as + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(ProxyServer)/Uri(EndPointServer/FilePath) + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(ProxyServer)/Uri(EndPointServer/FilePath) + // + TempUri = Uri; + } + Uri = AllocatePool (UriStrLength + 1); if (Uri == NULL) { return EFI_OUT_OF_RESOURCES; @@ -615,6 +630,11 @@ HttpBootParseFilePath ( TempDevicePath = NextDevicePathNode (TempDevicePath); } + if (TempUri != NULL) { + *UriAddress = TempUri; + *EndPointUriAddress = Uri; + } + return EFI_SUCCESS; } diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h index 3698e55936..6228f37e36 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h @@ -138,8 +138,9 @@ HttpBootCheckUriScheme ( Caller need to free the buffer in the UriAddress pointer. - @param[in] FilePath Pointer to the device path which contains a URI device path node. - @param[out] UriAddress The URI address string extract from the device path. + @param[in] FilePath Pointer to the device path which contains a URI device path node. + @param[out] UriAddress The URI address string extract from the device path. + @param[out] EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server @retval EFI_SUCCESS The URI string is returned. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @@ -148,7 +149,8 @@ HttpBootCheckUriScheme ( EFI_STATUS HttpBootParseFilePath ( IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - OUT CHAR8 **UriAddress + OUT CHAR8 **UriAddress, + OUT CHAR8 **EndPointUriAddress ); /** diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h index 01a6bb7f4b..e0917f431e 100644 --- a/NetworkPkg/HttpDxe/HttpDriver.h +++ b/NetworkPkg/HttpDxe/HttpDriver.h @@ -26,6 +26,7 @@ #include <Library/NetLib.h> #include <Library/HttpLib.h> #include <Library/DpcLib.h> +#include <Library/PrintLib.h> // // UEFI Driver Model Protocols @@ -64,6 +65,7 @@ // Driver Version // #define HTTP_DRIVER_VERSION 0xa +#define URI_STR_MAX_SIZE 255 // // Protocol instances diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf index c9502d0bb6..30b7de1951 100644 --- a/NetworkPkg/HttpDxe/HttpDxe.inf +++ b/NetworkPkg/HttpDxe/HttpDxe.inf @@ -47,6 +47,7 @@ NetLib HttpLib DpcLib + PrintLib [Protocols] gEfiHttpServiceBindingProtocolGuid ## BY_START diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c index 7c5c925cf7..24ce87fd7d 100644 --- a/NetworkPkg/HttpDxe/HttpImpl.c +++ b/NetworkPkg/HttpDxe/HttpImpl.c @@ -233,35 +233,45 @@ EfiHttpRequest ( EFI_HTTP_MESSAGE *HttpMsg; EFI_HTTP_REQUEST_DATA *Request; VOID *UrlParser; + VOID *EndPointUrlParser; EFI_STATUS Status; CHAR8 *HostName; + CHAR8 *EndPointHostName; UINTN HostNameSize; UINT16 RemotePort; + UINT16 EndPointRemotePort; HTTP_PROTOCOL *HttpInstance; BOOLEAN Configure; BOOLEAN ReConfigure; BOOLEAN TlsConfigure; CHAR8 *RequestMsg; CHAR8 *Url; + CHAR8 *EndPointUrl; UINTN UrlLen; CHAR16 *HostNameStr; HTTP_TOKEN_WRAP *Wrap; CHAR8 *FileUrl; UINTN RequestMsgSize; EFI_HANDLE ImageHandle; + CHAR8 *EndPointUrlMsg; // // Initializations // - Url = NULL; - UrlParser = NULL; - RemotePort = 0; - HostName = NULL; - RequestMsg = NULL; - HostNameStr = NULL; - Wrap = NULL; - FileUrl = NULL; - TlsConfigure = FALSE; + Url = NULL; + UrlParser = NULL; + EndPointUrlParser = NULL; + RemotePort = 0; + EndPointRemotePort = 0; + HostName = NULL; + EndPointHostName = NULL; + RequestMsg = NULL; + HostNameStr = NULL; + Wrap = NULL; + FileUrl = NULL; + TlsConfigure = FALSE; + EndPointUrl = NULL; + EndPointUrlMsg = NULL; if ((This == NULL) || (Token == NULL)) { return EFI_INVALID_PARAMETER; @@ -275,16 +285,20 @@ EfiHttpRequest ( Request = HttpMsg->Data.Request; // - // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation. + // Only support GET, HEAD, DELETE, PATCH, PUT, CONNECT and POST method in current implementation. // if ((Request != NULL) && (Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) && - (Request->Method != HttpMethodPatch)) + (Request->Method != HttpMethodPatch) && (Request->Method != HttpMethodConnect)) { return EFI_UNSUPPORTED; } + if ((Request->Method == HttpMethodConnect) && (Request->EndPointUrl == NULL)) { + return EFI_INVALID_PARAMETER; + } + HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); // @@ -353,11 +367,25 @@ EfiHttpRequest ( UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen); + if (Request->EndPointUrl != NULL) { + UrlLen = StrLen (Request->EndPointUrl) + 1; + EndPointUrl = AllocateZeroPool (UrlLen); + if (EndPointUrl == NULL) { + goto Error1; + } + + UnicodeStrToAsciiStrS (Request->EndPointUrl, EndPointUrl, UrlLen); + } + // // From the information in Url, the HTTP instance will // be able to determine whether to use http or https. // - HttpInstance->UseHttps = IsHttpsUrl (Url); + if (HttpInstance->ProxyConnected) { + HttpInstance->UseHttps = IsHttpsUrl (EndPointUrl); + } else { + HttpInstance->UseHttps = IsHttpsUrl (Url); + } // // HTTP is disabled, return directly if the URI is not HTTPS. @@ -444,9 +472,10 @@ EfiHttpRequest ( if ((HttpInstance->ConnectionClose == FALSE) && (HttpInstance->RemotePort == RemotePort) && (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) && - (!HttpInstance->UseHttps || (HttpInstance->UseHttps && - !TlsConfigure && - (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring)))) + (!HttpInstance->UseHttps || + HttpInstance->ProxyConnected || (HttpInstance->UseHttps && + !TlsConfigure && + (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring)))) { // // Host Name and port number of the request URL are the same with previous call to Request(). @@ -599,7 +628,7 @@ EfiHttpRequest ( goto Error2; } - if (!Configure && !ReConfigure && !TlsConfigure) { + if ((!Configure && !ReConfigure) && ((HttpInstance->ProxyConnected && TlsConfigure) || (!TlsConfigure))) { // // For the new HTTP token, create TX TCP token events. // @@ -632,7 +661,48 @@ EfiHttpRequest ( } } - Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize); + if (HttpInstance->Method == HttpMethodConnect) { + Status = HttpParseUrl (EndPointUrl, (UINT32)AsciiStrLen (EndPointUrl), FALSE, &EndPointUrlParser); + if (EFI_ERROR (Status)) { + goto Error3; + } + + Status = HttpUrlGetHostName ( + EndPointUrl, + EndPointUrlParser, + &EndPointHostName + ); + if (EFI_ERROR (Status)) { + goto Error3; + } + + Status = HttpUrlGetPort (EndPointUrl, EndPointUrlParser, &EndPointRemotePort); + if (EFI_ERROR (Status)) { + if (IsHttpsUrl (EndPointUrl)) { + EndPointRemotePort = HTTPS_DEFAULT_PORT; + } else { + EndPointRemotePort = HTTP_DEFAULT_PORT; + } + } + + EndPointUrlMsg = AllocateZeroPool (URI_STR_MAX_SIZE); + if (EndPointUrlMsg == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error3; + } + + AsciiSPrint ( + EndPointUrlMsg, + URI_STR_MAX_SIZE, + "%a:%d", + EndPointHostName, + EndPointRemotePort + ); + + Status = HttpGenRequestMessage (HttpMsg, EndPointUrlMsg, &RequestMsg, &RequestMsgSize); + } else { + Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize); + } if (EFI_ERROR (Status) || (NULL == RequestMsg)) { goto Error3; @@ -668,6 +738,23 @@ EfiHttpRequest ( DispatchDpc (); + if (HttpInstance->Method == HttpMethodConnect) { + HttpInstance->ProxyConnected = TRUE; + HttpInstance->EndPointRemoteHost = EndPointHostName; + + if (EndPointUrlParser != NULL) { + HttpUrlFreeParser (EndPointUrlParser); + } + } + + if (EndPointUrlMsg != NULL) { + FreePool (EndPointUrlMsg); + } + + if (EndPointUrl != NULL) { + FreePool (EndPointUrl); + } + if (HostName != NULL) { FreePool (HostName); } @@ -698,6 +785,20 @@ Error3: TlsCloseTxRxEvent (HttpInstance); } + if (HttpInstance->Method == HttpMethodConnect) { + if (EndPointHostName != NULL) { + FreePool (EndPointHostName); + } + + if (EndPointUrlParser != NULL) { + HttpUrlFreeParser (EndPointUrlParser); + } + } + + if (EndPointUrlMsg != NULL) { + FreePool (EndPointUrlMsg); + } + Error2: HttpCloseConnection (HttpInstance); @@ -725,6 +826,10 @@ Error1: HttpUrlFreeParser (UrlParser); } + if (EndPointUrl != NULL) { + FreePool (EndPointUrl); + } + return Status; } diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c index 33ae622c3f..b87fbeeb54 100644 --- a/NetworkPkg/HttpDxe/HttpProto.c +++ b/NetworkPkg/HttpDxe/HttpProto.c @@ -849,6 +849,11 @@ HttpCleanProtocol ( HttpInstance->Url = NULL; } + if (HttpInstance->EndPointRemoteHost != NULL) { + FreePool (HttpInstance->EndPointRemoteHost); + HttpInstance->EndPointRemoteHost = NULL; + } + NetMapClean (&HttpInstance->TxTokens); NetMapClean (&HttpInstance->RxTokens); @@ -1206,6 +1211,7 @@ HttpConfigureTcp6 ( connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. + @param[in] TlsConfigure The Flag indicates whether it's the new Tls session. @retval EFI_SUCCESS The TCP connection is established. @retval EFI_NOT_READY TCP4 protocol child is not created or configured. @@ -1214,7 +1220,8 @@ HttpConfigureTcp6 ( **/ EFI_STATUS HttpConnectTcp4 ( - IN HTTP_PROTOCOL *HttpInstance + IN HTTP_PROTOCOL *HttpInstance, + IN BOOLEAN TlsConfigure ) { EFI_STATUS Status; @@ -1237,16 +1244,18 @@ HttpConnectTcp4 ( return Status; } - if (Tcp4State == Tcp4StateEstablished) { + if ((Tcp4State == Tcp4StateEstablished) && (!HttpInstance->ProxyConnected || !TlsConfigure)) { return EFI_SUCCESS; } else if (Tcp4State > Tcp4StateEstablished ) { HttpCloseConnection (HttpInstance); } - Status = HttpCreateConnection (HttpInstance); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status)); - return Status; + if (!HttpInstance->ProxyConnected) { + Status = HttpCreateConnection (HttpInstance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status)); + return Status; + } } // @@ -1298,6 +1307,7 @@ HttpConnectTcp4 ( connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. + @param[in] TlsConfigure The Flag indicates whether it's the new Tls session. @retval EFI_SUCCESS The TCP connection is established. @retval EFI_NOT_READY TCP6 protocol child is not created or configured. @@ -1306,7 +1316,8 @@ HttpConnectTcp4 ( **/ EFI_STATUS HttpConnectTcp6 ( - IN HTTP_PROTOCOL *HttpInstance + IN HTTP_PROTOCOL *HttpInstance, + IN BOOLEAN TlsConfigure ) { EFI_STATUS Status; @@ -1330,16 +1341,18 @@ HttpConnectTcp6 ( return Status; } - if (Tcp6State == Tcp6StateEstablished) { + if ((Tcp6State == Tcp6StateEstablished) && (!HttpInstance->ProxyConnected || !TlsConfigure)) { return EFI_SUCCESS; } else if (Tcp6State > Tcp6StateEstablished ) { HttpCloseConnection (HttpInstance); } - Status = HttpCreateConnection (HttpInstance); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status)); - return Status; + if (!HttpInstance->ProxyConnected) { + Status = HttpCreateConnection (HttpInstance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status)); + return Status; + } } // @@ -1434,7 +1447,7 @@ HttpInitSession ( // // Connect TCP. // - Status = HttpConnectTcp4 (HttpInstance); + Status = HttpConnectTcp4 (HttpInstance, TlsConfigure); if (EFI_ERROR (Status)) { return Status; } @@ -1452,7 +1465,7 @@ HttpInitSession ( // // Connect TCP. // - Status = HttpConnectTcp6 (HttpInstance); + Status = HttpConnectTcp6 (HttpInstance, TlsConfigure); if (EFI_ERROR (Status)) { return Status; } diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h index 620eb39158..2e8d516359 100644 --- a/NetworkPkg/HttpDxe/HttpProto.h +++ b/NetworkPkg/HttpDxe/HttpProto.h @@ -165,6 +165,12 @@ typedef struct _HTTP_PROTOCOL { CHAR8 *Url; + // + // Proxy Server Support + // + CHAR8 *EndPointRemoteHost; + BOOLEAN ProxyConnected; + // // Https Support // @@ -398,6 +404,7 @@ HttpConfigureTcp6 ( connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. + @param[in] TlsConfigure The Flag indicates whether it's the new Tls session. @retval EFI_SUCCESS The TCP connection is established. @retval EFI_NOT_READY TCP4 protocol child is not created or configured. @@ -406,7 +413,8 @@ HttpConfigureTcp6 ( **/ EFI_STATUS HttpConnectTcp4 ( - IN HTTP_PROTOCOL *HttpInstance + IN HTTP_PROTOCOL *HttpInstance, + IN BOOLEAN TlsConfigure ); /** @@ -414,6 +422,7 @@ HttpConnectTcp4 ( connect one TLS session if required. @param[in] HttpInstance The HTTP instance private data. + @param[in] TlsConfigure The Flag indicates whether it's the new Tls session. @retval EFI_SUCCESS The TCP connection is established. @retval EFI_NOT_READY TCP6 protocol child is not created or configured. @@ -422,7 +431,8 @@ HttpConnectTcp4 ( **/ EFI_STATUS HttpConnectTcp6 ( - IN HTTP_PROTOCOL *HttpInstance + IN HTTP_PROTOCOL *HttpInstance, + IN BOOLEAN TlsConfigure ); /** diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c index ad611e7c38..7dc2b752ec 100644 --- a/NetworkPkg/HttpDxe/HttpsSupport.c +++ b/NetworkPkg/HttpDxe/HttpsSupport.c @@ -644,11 +644,15 @@ TlsConfigureSession ( // // TlsConfigData initialization // - HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient; - HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER; - HttpInstance->TlsConfigData.VerifyHost.Flags = EFI_TLS_VERIFY_FLAG_NONE; - HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->RemoteHost; - HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted; + HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient; + HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted; + HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER; + HttpInstance->TlsConfigData.VerifyHost.Flags = EFI_TLS_VERIFY_FLAG_NONE; + if (HttpInstance->ProxyConnected) { + HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->EndPointRemoteHost; + } else { + HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->RemoteHost; + } // // EfiTlsConnectionEnd, diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c index 6a5d78629b..45087a1935 100644 --- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c +++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c @@ -1927,6 +1927,11 @@ HttpGenRequestMessage ( CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength); RequestPtr += StrLength; break; + case HttpMethodConnect: + StrLength = sizeof (HTTP_METHOD_CONNECT) - 1; + CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength); + RequestPtr += StrLength; + break; default: ASSERT (FALSE); Status = EFI_INVALID_PARAMETER; -- 2.36.1.windows.1
|
|
[[edk2-staging/HttpProxy] 2/3] MdeModulePkg/Library: Add support for multi-URI device path
Process device path with proxy server and endpoint server included. Update comment for sample HTTP device path.
Cc: Jian J Wang <jian.j.wang@...> Cc: Liming Gao <gaoliming@...> Signed-off-by: Saloni Kasbekar <saloni.kasbekar@...> --- .../Library/UefiBootManagerLib/BmBoot.c | 28 +++++++++++++++++++ .../UefiBootManagerLib/BmBootDescription.c | 4 +-- 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index 962892d38f..fdef1ba292 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -1513,6 +1513,9 @@ BmExpandLoadFiles ( UINTN HandleCount; UINTN Index; EFI_DEVICE_PATH_PROTOCOL *Node; + URI_DEVICE_PATH *NullUriPath; + + NullUriPath = NULL; // // Get file buffer from load file instance. @@ -1545,11 +1548,36 @@ BmExpandLoadFiles ( for (Index = 0; Index < HandleCount; Index++) { if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) { + // + // Matches HTTP Boot Device Path described as + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...) + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...) + // + Handle = Handles[Index]; + goto Done; + } + } + + NullUriPath = (URI_DEVICE_PATH *)CreateDeviceNode ( + MESSAGING_DEVICE_PATH, + MSG_URI_DP, + (UINT16)(sizeof (URI_DEVICE_PATH)) + ); + for (Index = 0; Index < HandleCount; Index++) { + if (BmMatchHttpBootDevicePath (AppendDevicePathNode (DevicePathFromHandle (Handles[Index]), (EFI_DEVICE_PATH_PROTOCOL *)NullUriPath), FilePath)) { + // + // Matches HTTP Boot Device Path described as + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)/Uri(...) + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)/Uri(...) + // Handle = Handles[Index]; break; } } + FreePool (NullUriPath); + +Done: if (Handles != NULL) { FreePool (Handles); } diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c index fac33b9ee9..19b7cd1457 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c @@ -412,8 +412,8 @@ BmGetNetworkDescription ( // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...) // // The HTTP device path is like: - // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...) - // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...) + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)[/Uri(...)] + // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)[/Uri(...)] // while (!IsDevicePathEnd (DevicePath) && ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) || -- 2.36.1.windows.1
|
|
[[edk2-staging/HttpProxy] 1/3] MdePkg/Include: Add the EndPoint Server's URL in HTTP Request Data
Add EndPoint Server URL to HTTP Request Data to be used when a Proxy Server URL is a part of the device path
Cc: Zhiguang Liu <zhiguang.liu@...> Cc: Michael D Kinney <michael.d.kinney@...> Cc: Liming Gao <gaoliming@...> Signed-off-by: Saloni Kasbekar <saloni.kasbekar@...> --- MdePkg/Include/Protocol/Http.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h index 28e6221593..4f77220587 100644 --- a/MdePkg/Include/Protocol/Http.h +++ b/MdePkg/Include/Protocol/Http.h @@ -191,6 +191,11 @@ typedef struct { /// is assumed. See RFC 3986 for more details on URI syntax. /// CHAR16 *Url; + /// + /// The URI of an endpoint host if the Url field contains the address of a proxy server. + /// This field will be NULL if there is no proxy server in the device path. + /// + CHAR16 *EndPointUrl; } EFI_HTTP_REQUEST_DATA; /// -- 2.36.1.windows.1
|
|
[[edk2-staging/HttpProxy] 0/3] Support HTTPS Proxy Server for HTTP Boot
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3951REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4052- Add CONNECT HTTP Method to create a tunnel through the Proxy Server - TLS adjustments to establish handshake with the Endpoint Server - Use multi-URI device path to support Proxy Server URI as a part of the FilePath Saloni Kasbekar (3): MdePkg/Include: Add the EndPoint Server's URL in HTTP Request Data MdeModulePkg/Library: Add support for multi-URI device path NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot .../Library/UefiBootManagerLib/BmBoot.c | 28 ++ .../UefiBootManagerLib/BmBootDescription.c | 4 +- MdePkg/Include/Protocol/Http.h | 5 + NetworkPkg/HttpBootDxe/HttpBootClient.c | 211 +++++++++++++- NetworkPkg/HttpBootDxe/HttpBootClient.h | 15 + NetworkPkg/HttpBootDxe/HttpBootDxe.h | 6 + NetworkPkg/HttpBootDxe/HttpBootImpl.c | 262 +++++++++++++----- NetworkPkg/HttpBootDxe/HttpBootImpl.h | 8 + NetworkPkg/HttpBootDxe/HttpBootSupport.c | 24 +- NetworkPkg/HttpBootDxe/HttpBootSupport.h | 8 +- NetworkPkg/HttpDxe/HttpDriver.h | 2 + NetworkPkg/HttpDxe/HttpDxe.inf | 1 + NetworkPkg/HttpDxe/HttpImpl.c | 139 ++++++++-- NetworkPkg/HttpDxe/HttpProto.c | 41 ++- NetworkPkg/HttpDxe/HttpProto.h | 14 +- NetworkPkg/HttpDxe/HttpsSupport.c | 14 +- NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c | 5 + 17 files changed, 677 insertions(+), 110 deletions(-) -- 2.36.1.windows.1
|
|
[PATCH v1 1/1] BaseTools: Edk2ToolsBuild: Fixing pipeline build due to path too long
From: Sean Brogan <sean.brogan@...>
Current implementation of looking up toolchain will _insert_ the findings from vsvarsall.bat to existing path and potentially stuff the variable to exceed the length of maximal path length accepted by Windows.
This change updated the logic to use the discovered shell varialbes to replace the existing path, which is desirable in the specific use case.
Cc: Bob Feng <bob.c.feng@...> Cc: Liming Gao <gaoliming@...> Cc: Yuwei Chen <yuwei.chen@...>
Co-authored-by: Sean Brogan <sean.brogan@...> Signed-off-by: Kun Qin <kuqin12@...> --- BaseTools/Edk2ToolsBuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/BaseTools/Edk2ToolsBuild.py b/BaseTools/Edk2ToolsBuild.py index 1ea8187de693..f862468ce275 100644 --- a/BaseTools/Edk2ToolsBuild.py +++ b/BaseTools/Edk2ToolsBuild.py @@ -122,7 +122,7 @@ class Edk2ToolsBuild(BaseAbstractInvocable): for key in vc_vars.keys():=0D logging.debug(f"Var - {key} =3D {vc_vars[key]}")=0D if key.lower() =3D=3D 'path':=0D - shell_env.insert_path(vc_vars[key])=0D + shell_env.set_path(vc_vars[key])=0D else:=0D shell_env.set_shell_var(key, vc_vars[key])=0D =0D --=20 2.37.1.windows.1
|
|
[PATCH v1 0/1] Fixing BaseTool build break
Currently the BaseTool build step is failing and caused the pipeline to malfunciton. The issue is due to the environment path too long during the build process and adding VC toolchain path to the environment variable will fail due to Windows varaible length limit. Patch v1 branch: https://github.com/kuqin12/edk2/tree/fix_edk2_buildCc: Bob Feng <bob.c.feng@...> Cc: Liming Gao <gaoliming@...> Cc: Yuwei Chen <yuwei.chen@...> Cc: Sean Brogan <sean.brogan@...> Sean Brogan (1): BaseTools: Edk2ToolsBuild: Fixing pipeline build due to path too long BaseTools/Edk2ToolsBuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.37.1.windows.1
|
|
[edk2-staging/RiscV64QemuVirt] Branch for enabling RISC-V qemu virt platform
|
|
Re: [PATCH v1 1/1] MdeModulePkg/Core: Fix the potential hang of calling SetTimer.
Hi,
If a module is has a dependency on the Timer Arch Protocol, that module should list the Timer Arch Protocol as only of its dependencies in the dependency expression.
I agree that we should avoid a hang condition, but it is not clear if new return statuses need to be added for this case where a module may not have a correct dependency expression.
An ASSERT() or DEBUG() message may be a better way to inform the developer that they may have an incorrect dependency expression.
Mike
toggle quoted message
Show quoted text
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ying-Tsun Huang via groups.io Sent: Tuesday, September 20, 2022 7:10 PM To: devel@edk2.groups.io Cc: Wang, Jian J <jian.j.wang@...>; Bi, Dandan <dandan.bi@...>; Gao, Liming <gaoliming@...> Subject: [edk2-devel] [PATCH v1 1/1] MdeModulePkg/Core: Fix the potential hang of calling SetTimer.
When calling SetTimer with Type is not TimerCancel and TriggerTime is 0, gTimer is used to get the timer period. However, gTimer is NULL before EFI_TIMER_ARCH_PROTOCOL is installed. Adding the check of gTimer and return EFI_NOT_READY to avoid the hang.
Cc: Jian J Wang <jian.j.wang@...> Cc: Dandan Bi <dandan.bi@...> Cc: Liming Gao <gaoliming@...> Signed-off-by: Ying-Tsun Huang <ying-tsun.huang@...> --- MdeModulePkg/Core/Dxe/DxeMain.h | 2 ++ MdeModulePkg/Core/Dxe/Event/Timer.c | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 815a6b4bd844..acf0b244aeda 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -1538,6 +1538,8 @@ CoreCreateEventInternal ( @retval EFI_SUCCESS The event has been set to be signaled at the requested time @retval EFI_INVALID_PARAMETER Event or Type is not valid + @retval EFI_NOT_READY Type is not TimerCancel, TriggerTime is 0, but + EFI_TIMER_ARCH_PROTOCOL is not installed yet
**/ EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/Event/Timer.c b/MdeModulePkg/Core/Dxe/Event/Timer.c index 29e507c67c50..1621814ef3c5 100644 --- a/MdeModulePkg/Core/Dxe/Event/Timer.c +++ b/MdeModulePkg/Core/Dxe/Event/Timer.c @@ -229,6 +229,8 @@ CoreTimerTick ( @retval EFI_SUCCESS The event has been set to be signaled at the requested time @retval EFI_INVALID_PARAMETER Event or Type is not valid + @retval EFI_NOT_READY Type is not TimerCancel, TriggerTime is 0, but + EFI_TIMER_ARCH_PROTOCOL is not installed yet
**/ EFI_STATUS @@ -255,6 +257,14 @@ CoreSetTimer ( return EFI_INVALID_PARAMETER; }
+ if ((Type != TimerCancel) && (TriggerTime == 0)) { + if (gTimer) { + gTimer->GetTimerPeriod (gTimer, &TriggerTime); + } else { + return EFI_NOT_READY; + } + } + CoreAcquireLock (&mEfiTimerLock);
// @@ -270,10 +280,6 @@ CoreSetTimer (
if (Type != TimerCancel) { if (Type == TimerPeriodic) { - if (TriggerTime == 0) { - gTimer->GetTimerPeriod (gTimer, &TriggerTime); - } - Event->Timer.Period = TriggerTime; }
-- 2.25.1
|
|
Re: [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial
FreeBuffer
On Wed, 21 Sept 2022 at 18:27, Jeff Brasen via groups.io <jbrasen@...> wrote: Anything else needed to get this merged?
That is up to the MdeModulePkg maintainers. -----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Thursday, September 8, 2022 9:55 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [edk2-devel] [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Thu, 8 Sept 2022 at 17:39, Jeff Brasen <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Monday, August 15, 2022 8:42 AM To: devel@edk2.groups.io; Jeff Brasen <jbrasen@...> Cc: hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [edk2-devel] [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Fri, 5 Aug 2022 at 18:56, Jeff Brasen via groups.io <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Tuesday, August 2, 2022 10:51 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Tue, 2 Aug 2022 at 17:32, Jeff Brasen <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Friday, July 29, 2022 9:48 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [PATCH v2]
MdeModulePkg/NonDiscoverablePciDeviceDxe:
Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Thu, 28 Jul 2022 at 13:25, Jeff Brasen <jbrasen@...>
wrote:
Adding Leif/Ard to CC incase they have any comments on this patch.
This generally looks ok to me. I just wonder if it wouldn't be simpler to reuse the existing allocation descriptor if it is not being freed entirely. Given the [presumably] the most common case is to allocate and then free some pages at the end, lowering the page count on the existing descriptor would cover most cases, and we'd only need to allocate new ones if pages are being freed at the start or in
the middle.
There is often freeing at the beginning as well as this is being used to create a 64K aligned section of memory in the case. So it over allocates and the free's some at the beginning and the end. I could probably make it detect and use that but figured this code would support all cases and required less case specific detection. Ah interesting. Would it help if the allocate routine aligned allocations to their size? The PciIo->AllocateBuffer function doesn't support passing the request in so we would need to know that info beforehand. The current calling in the XHCI driver does a free at the beginning and then the end of the buffer so we could the existing allocation tracker but figured it would be better to correct the function just in case someone called it to free
in the middle.
What I was wondering is whether such allocations are themselves multiples of 64k. This is perhaps orthogonal to the issue this patch addresses, as we'' still need to deal with partial free calls regardless. But I was curious whether XHCI in particular, and perhaps more generally, we could streamline this by aligning all allocations to a log2 upper bound of their sizes.
Xhci code (https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Bus/Pci/Xhci Dxe/UsbHcMem.c#L604) in allocation requested is greater the EFI_PAGE_SIZE allocates number of requested pages plus pages for the alignment and then frees pages at the beginning and end of the allocation. I am not sure we really could change this without adding an alignment field to the PciIo protocol.
Is there anything else you would like to change on this patch?
No. Thanks for the clarification.
Reviewed-by: Ard Biesheuvel <ardb@...>
|
|
Re: [PATCH] MdeModulePkg/TerminalDxe: add modes
The other way to get full screen text on graphical console is to disable the serial console in the Boot Maintenance Manager.
If the serial console is disabled then ConSplitterDxe will only see the text modes supported by GraphicsConsoleDxe which will include these higher text modes.
Is the issue that you are trying to solve supporting larger serial console modes or just wanting to use the largest possible text mode at a given graphics resolution?
Mike
toggle quoted message
Show quoted text
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Konstantin Aladyshev Sent: Wednesday, September 21, 2022 1:24 AM To: Kinney, Michael D <michael.d.kinney@...> Cc: devel@edk2.groups.io; Gao, Liming <gaoliming@...>; Wang, Jian J <jian.j.wang@...>; Ni, Ray <ray.ni@...> Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/TerminalDxe: add modes
I have tested it in the following way: - launch OVMF in Linux and connect with vnc - change resolution via the form browser (Device Manager -> OVMF Platform Configuration) from the default 640x480 to the 1920x1080 - "reset" - after the reset the system will boot to the 1920x1080 resolution and text mode 80x25 - check "mode" command output
Before the commit this command displays only these modes: ``` Shell> mode Available modes for console output device. Col 80 Row 25 * Col 80 Row 50 Col 100 Row 31 ``` But with this commit the high resolution modes are present in the output: ``` Shell> mode Available modes for console output device. Col 80 Row 25 * Col 80 Row 50 Col 100 Row 31 Col 128 Row 40 Col 160 Row 42 Col 240 Row 56 ``` And in my case setting the appropriate "mode 240 56" at runtime works just fine: ``` Shell> mode 240 56 ``` After that the text output starts using the full screen.
Best regards, Konstantin Aladyshev
On Wed, Sep 21, 2022 at 4:46 AM Kinney, Michael D <michael.d.kinney@...> wrote:
Tera Term works.
Mike
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of gaoliming via groups.io Sent: Tuesday, September 20, 2022 6:26 PM To: Kinney, Michael D <michael.d.kinney@...>; devel@edk2.groups.io; aladyshev22@... Cc: Wang, Jian J <jian.j.wang@...>; Ni, Ray <ray.ni@...> Subject: 回复: [edk2-devel] [PATCH] MdeModulePkg/TerminalDxe: add modes
Konstantin: Do you try the terminal software (such as Putty) to display the text mode 160, 42 or 240, 56? I try Putty in my desktop. It can't display 240 * 56 in one screen.
Thanks Liming
-----邮件原件----- 发件人: Kinney, Michael D <michael.d.kinney@...> 发送时间: 2022年9月20日 5:02 收件人: devel@edk2.groups.io; aladyshev22@...; Kinney, Michael D <michael.d.kinney@...> 抄送: Wang, Jian J <jian.j.wang@...>; Gao, Liming <gaoliming@...>; Ni, Ray <ray.ni@...> 主题: RE: [edk2-devel] [PATCH] MdeModulePkg/TerminalDxe: add modes
This looks like a reasonable update to support platforms that have both graphical consoles and serial consoles.
Reviewed-by: Michael D Kinney <michael.d.kinney@...>
-----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Konstantin Aladyshev
Sent: Monday, September 19, 2022 1:57 AM To: devel@edk2.groups.io Cc: Wang, Jian J <jian.j.wang@...>; Gao, Liming <gaoliming@...>; Ni, Ray <ray.ni@...>; Konstantin
Aladyshev <aladyshev22@...> Subject: [edk2-devel] [PATCH] MdeModulePkg/TerminalDxe: add modes
The commit b807174fecacf4c9f8400cab4d6fb3f580284021 ("MdeModulePkg/GraphicsConsoleDxe: add modes") has added modes for the
high display resolutions. Support these modes in the TerminalDxe as well, so it would be possible to select the text mode that would take all the available screen space.
Signed-off-by: Konstantin Aladyshev <aladyshev22@...> --- MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
index e2d779c783..6b7b970516 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c @@ -115,6 +115,9 @@ TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = {
{ 80, 25 },
{ 80, 50 },
{ 100, 31 },
+ { 128, 40 },
+ { 160, 42 },
+ { 240, 56 },
//
// New modes can be added here.
//
-- 2.25.1
-=-=-=-=-=-= Groups.io Links: You receive all messages sent to this group. View/Reply Online (#93935): https://edk2.groups.io/g/devel/message/93935
Mute This Topic: https://groups.io/mt/93777396/1643496 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [michael.d.kinney@...]
-=-=-=-=-=-=
|
|
Re: [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial
FreeBuffer
Anything else needed to get this merged?
toggle quoted message
Show quoted text
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Thursday, September 8, 2022 9:55 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [edk2-devel] [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Thu, 8 Sept 2022 at 17:39, Jeff Brasen <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Monday, August 15, 2022 8:42 AM To: devel@edk2.groups.io; Jeff Brasen <jbrasen@...> Cc: hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [edk2-devel] [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Fri, 5 Aug 2022 at 18:56, Jeff Brasen via groups.io <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Tuesday, August 2, 2022 10:51 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [PATCH v2] MdeModulePkg/NonDiscoverablePciDeviceDxe: Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Tue, 2 Aug 2022 at 17:32, Jeff Brasen <jbrasen@...> wrote:
-----Original Message----- From: Ard Biesheuvel <ardb@...> Sent: Friday, July 29, 2022 9:48 AM To: Jeff Brasen <jbrasen@...> Cc: devel@edk2.groups.io; hao.a.wu@...; ray.ni@...; quic_llindhol@...; ardb+tianocore@... Subject: Re: [PATCH v2]
MdeModulePkg/NonDiscoverablePciDeviceDxe:
Allow partial FreeBuffer
External email: Use caution opening links or attachments
On Thu, 28 Jul 2022 at 13:25, Jeff Brasen <jbrasen@...>
wrote:
Adding Leif/Ard to CC incase they have any comments on this patch.
This generally looks ok to me. I just wonder if it wouldn't be simpler to reuse the existing allocation descriptor if it is not being freed entirely. Given the [presumably] the most common case is to allocate and then free some pages at the end, lowering the page count on the existing descriptor would cover most cases, and we'd only need to allocate new ones if pages are being freed at the start or in
the middle.
There is often freeing at the beginning as well as this is being used to create a 64K aligned section of memory in the case. So it over allocates and the free's some at the beginning and the end. I could probably make it detect and use that but figured this code would support all cases and required less case specific detection. Ah interesting. Would it help if the allocate routine aligned allocations to their size? The PciIo->AllocateBuffer function doesn't support passing the request in so we would need to know that info beforehand. The current calling in the XHCI driver does a free at the beginning and then the end of the buffer so we could the existing allocation tracker but figured it would be better to correct the function just in case someone called it to free
in the middle.
What I was wondering is whether such allocations are themselves multiples of 64k. This is perhaps orthogonal to the issue this patch addresses, as we'' still need to deal with partial free calls regardless. But I was curious whether XHCI in particular, and perhaps more generally, we could streamline this by aligning all allocations to a log2 upper bound of their sizes.
Xhci code (https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Bus/Pci/Xhci Dxe/UsbHcMem.c#L604) in allocation requested is greater the EFI_PAGE_SIZE allocates number of requested pages plus pages for the alignment and then frees pages at the beginning and end of the allocation. I am not sure we really could change this without adding an alignment field to the PciIo protocol.
Is there anything else you would like to change on this patch?
No. Thanks for the clarification.
Reviewed-by: Ard Biesheuvel <ardb@...>
|
|