Hi Mike, I did make some attempts with it, but it doesn't work, two troubles here:
Bob and Yuwei, please point out if I'm wrong: 1. Using member of structure PCD in INF isn’t supported by Basetools currently, At least it cannot be used as FeatureFlag Expression. 2. As far as I know, structure PCD actually is a const array in code, I afraid it will not work fine with precompile but we do have this need: #if !FixedPcdGetBool (PcdOpensslEcEnabled) # ifndef OPENSSL_NO_EC # define OPENSSL_NO_EC # endif #endif This is really caused by the bad structure of openssl, maybe we use more detailed comments to remind developers to sync the two PCDs? Thanks, Yi -----Original Message----- From: Kinney, Michael D <michael.d.kin...@intel.com> Sent: Friday, September 23, 2022 1:25 PM To: Li, Yi1 <yi1...@intel.com>; devel@edk2.groups.io; Chen, Christine <yuwei.c...@intel.com>; Feng, Bob C <bob.c.f...@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 Hi Yi, I agree there are some complex interactions in the opensll sources. Since you are defining a family for EC, can we use the EC Family != 0 instead of PcdOpensslEcEnabled and remove PcdOpensslEcEnabled. I want to make sure developers do not run into strange build failures if they do not keep the 2 different PCDs aligned. I prefer a single PCD setting to enable use of EC services. I also noticed that the use of a PCD expression in an INF to select source files does not work if the PCD value is specified with the --pcd flag on the build command line. This looks like a significant bug with the PCD expression in an INF file. This also needs to be fixed. Mike > -----Original Message----- > From: Li, Yi1 <yi1...@intel.com> > Sent: Thursday, September 22, 2022 8:02 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, > > 1. Yes, it matches. > By Intel side, 100+kb(20%+) FV size increase will be a big concern, please > refer to another internal email. > > 2. Additional size is coming from modules may consumed EC APIs, eg. TLS PEM > X509 ... > > If we added EC source to OpensslLib.inf and disabled macro OPENSSL_NO_EC, > those modules will link EC APIs and increase binary > size, > This an example from x509/x_pubkey.c , other modules is similar: > #ifndef OPENSSL_NO_EC > EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) > { > EVP_PKEY *pkey; > EC_KEY *key = NULL; > //.... call EC functions > } > #endif > > If we added EC source to OpensslLib.inf and enable macro OPENSSL_NO_EC, EC > module will throw build error, > Since some EC internal APIs or structs have been disabled by OPENSSL_NO_EC > but not another. > This an example from ec/ec_local.h , other error is similar: > > #ifndef OPENSSL_NO_EC > typedef struct ec_group_st EC_GROUP; > typedef struct ec_point_st EC_POINT; > #endif > > // but this function not been enclosed by OPENSSL_NO_EC, and will throw build > error > int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, > EC_POINT *, const BIGNUM *x, > const BIGNUM *y, > const BIGNUM *z, BN_CTX *); > > To avoid this annoying openssl error, we introduced conditional EC. > > Thanks, > Yi > > -----Original Message----- > From: Kinney, Michael D <michael.d.kin...@intel.com> > Sent: Friday, September 23, 2022 6:47 AM > To: Li, Yi1 <yi1...@intel.com>; devel@edk2.groups.io; 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 > > Hi Yi, > > I agree EC is an important feature. > > I did some analysis of the size impact to the CryptoPkg modules on current > trunk > with EC on and off. Uncompressed size is important for PEI Phase. For DXE and > SMM phase, the Crypto services can always be compressed. From the table > below, > building all the EC services in the OpensslLib has no size impact to the NONE > profile and the MIN_PEI profile. It has ~105 KB impact to compressed DXE/SMM > usages that may use the MIN_DXE_MIN_SMM or ALL profiles. > > Uncompressed LZMA Compressed > CPU CRYPTO_SERVICES Module EC=FALSE EC=TRUE EC=FALSE EC=TRUE > Increase > ==== =============== ======== ======== ======= ======== ======= > ======== > IA32 NONE CryptoPei 21536 21568 0 > KB > IA32 NONE CryptoDxe 21632 21696 0 > KB > IA32 NONE CryptoSmm 22976 23072 0 > KB > IA32 MIN_PEI CryptoPei 248992 249120 0 > KB > IA32 MIN_DXE_MIN_SMM CryptoDxe 636672 829568 288520 401034 113 > KB > IA32 MIN_DXE_MIN_SMM CryptoSmm 426048 601472 191517 296022 105 > KB > IA32 ALL CryptoPei 423840 598976 189047 293759 104 > KB > IA32 ALL CryptoDxe 645280 838144 292955 405277 113 > KB > IA32 ALL CryptoSmm 441888 617184 198779 303628 105 > KB > X64 NONE CryptoPei 29632 29664 0 > KB > X64 NONE CryptoDxe 29792 29792 0 > KB > X64 NONE CryptoSmm 31296 31296 0 > KB > X64 MIN_PEI CryptoPei 310784 310848 0 > KB > X64 MIN_DXE_MIN_SMM CryptoDxe 804288 1016256 311436 426596 115 > KB > X64 MIN_DXE_MIN_SMM CryptoSmm 543776 733920 204483 310775 106 > KB > X64 ALL CryptoPei 540384 730240 202494 308467 106 > KB > X64 ALL CryptoDxe 815392 1027296 316228 431321 115 > KB > X64 ALL CryptoSmm 563648 753696 213488 319644 106 > KB > > NOTE: Even if multiple modules in an FV use static linking of Crypto libs, if > the > entire FV is compressed, the total size impact is typically the size of > a > single instance of a compressed CryptoLib. The sizes of the Crypto* > modules > in the table above should be a close approximation of the size impact > to a > single FV. > > Does this match your previous size analysis? > > The critical issue to evaluate here is why adding the EC sources to > OpensllLib.inf > causes the modules that do not use any EC services to grow by ~105KB. Has any > detailed analysis of the final linked images been performed to see where this > additional size is coming from? > > Thanks, > > Mike > > > -----Original Message----- > > From: Li, Yi1 <yi1...@intel.com> > > Sent: Thursday, September 22, 2022 5:54 AM > > To: Kinney, Michael D <michael.d.kin...@intel.com>; devel@edk2.groups.io; > > Kishore, Shelly <shelly.kish...@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 > > > > Hi Mike, > > I have did some POC that seems existed structured PCD is hard to control > > binary size, > > Here is the previous discussion for reference. > > https://bugzilla.tianocore.org/show_bug.cgi?id=3679 > > https://edk2.groups.io/g/devel/topic/86257810#81814 > > https://bugzilla.tianocore.org/show_bug.cgi?id=1446 > > > > Anyway EC is an important feature which consumed by vary modern security > > features such WPA3 , SPDM, TLS1.3 etc. > > Hope it can be added to edk2, and I am glad to take the code and test work > > if there are other ways to control the size. > > > > Thanks, > > Yi > > > > -----Original Message----- > > From: Kinney, Michael D <michael.d.kin...@intel.com> > > Sent: Thursday, September 22, 2022 11:56 AM > > To: Li, Yi1 <yi1...@intel.com>; devel@edk2.groups.io; Kishore, Shelly > > <shelly.kish...@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 > > > > 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 (#94190): https://edk2.groups.io/g/devel/message/94190 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] -=-=-=-=-=-=-=-=-=-=-=-