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 -----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 (#94098): https://edk2.groups.io/g/devel/message/94098 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] -=-=-=-=-=-=-=-=-=-=-=-