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 > -----Original Message----- > From: Li, Yi1 <yi1...@intel.com> > Sent: Wednesday, September 21, 2022 7:16 PM > To: Kinney, Michael D <michael.d.kin...@intel.com>; devel@edk2.groups.io > Cc: Yao, Jiewen <jiewen....@intel.com>; Wang, Jian J <jian.j.w...@intel.com>; > Lu, Xiaoyu1 <xiaoyu1...@intel.com>; Jiang, > Guomin <guomin.ji...@intel.com> > 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.kin...@intel.com> > Sent: Thursday, September 22, 2022 12:22 AM > To: devel@edk2.groups.io; Li, Yi1 <yi1...@intel.com>; Kinney, Michael D > <michael.d.kin...@intel.com> > Cc: Yao, Jiewen <jiewen....@intel.com>; Wang, Jian J <jian.j.w...@intel.com>; > Lu, Xiaoyu1 <xiaoyu1...@intel.com>; Jiang, > Guomin <guomin.ji...@intel.com> > 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...@intel.com>; Yao, Jiewen <jiewen....@intel.com>; Wang, > > Jian J <jian.j.w...@intel.com>; Lu, Xiaoyu1 > > <xiaoyu1...@intel.com>; Jiang, Guomin <guomin.ji...@intel.com> > > 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....@intel.com> > > Cc: Jian J Wang <jian.j.w...@intel.com> > > Cc: Xiaoyu Lu <xiaoyu1...@intel.com> > > Cc: Guomin Jiang <guomin.ji...@intel.com> > > > > Signed-off-by: Yi Li <yi1...@intel.com> > > --- > > 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 > > > > > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94101): https://edk2.groups.io/g/devel/message/94101 Mute This Topic: https://groups.io/mt/93820542/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-