Re: [PATCH V2 1/3] CryptoPkg: Add EC support


Yao, Jiewen
 

Hi Mike

To clarify current situation: We support 3 different use cases:

 

1) PcdOpensslEcEnabled = FALSE, PcdCryptoServiceFamilyEnable.Ec = FALSE

That means legacy platform. No ECC support at all.

 

2) PcdOpensslEcEnabled = TRUE, PcdCryptoServiceFamilyEnable.Ec = FALSE

This means the platform need ECC in TLS. But no ECC is required in EDKII crypto service.

This is the first configuration to support ECC in surface use case.

 

3)  PcdOpensslEcEnabled = TRUE, PcdCryptoServiceFamilyEnable.Ec = TRUE

This means the platform need ECC in TLS. Also ECC is available in EDKII crypto service.

This is the first configuration to support ECC in BIOS to support WPA3, and SPDM in the future.

 

I think a platform developer should know its configuration and make right choice.

 

For other crypto algorithm, we only have PcdCryptoServiceFamilyEnable.

 

For PcdOpensslEcEnabled, it is newly added for size optimization, as we discussed before.

Base tool team was already involved in the design the solution, with the known limitation of structure PCD.

And that was tool team’s recommendation at that moment.

 

 

Thank you

Yao, Jiewen

 

 

From: Li, Yi1 <yi1.li@...>
Sent: Saturday, September 24, 2022 11:44 AM
To: Kinney, Michael D <michael.d.kinney@...>; Yao, Jiewen <jiewen.yao@...>; devel@edk2.groups.io; Chen, Christine <yuwei.chen@...>; Feng, Bob C <bob.c.feng@...>
Cc: Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...>; Luo, Heng <heng.luo@...>
Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

 

Hi Mike,

My bad missed this feedback , this important issue should be discussed as early as possible.

 

The configuration of PcdCryptoServiceFamilyEnable seems obvious, and the developer may needs

additional information about the source files config PCD to ensure that the service is enabled properly.

We can add the following table to the DSC file for reference.

 

################################################################################

#

# Openssl Source Config Table

#

################################################################################

# Note: To ensure crypto services are properly enabled, platform requires:

#       1. Set gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.XX.Family

#          to PCD_CRYPTO_SERVICE_ENABLE_FAMILY,

#          OR set gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.XX.Services.X

#          to TRUE if only function X of Services XX needed.

#       2. To optimize Crypto Driver binary size, source files of some crypto

#          services have been set to conditional. Additional PCD in below table should

#          be set to TRUE.

#===============================================================================

#|  Crypto Service  |                     Additional PCD                       |

#===============================================================================

#|TlsSet            | gEfiCryptoPkgTokenSpaceGuid.PcdOpensslSslEnabled [TBD]   |

#|TlsGet            | gEfiCryptoPkgTokenSpaceGuid.PcdOpensslSslEnabled [TBD]   |

#|Ec                | gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled          |

#===============================================================================

 

Welcome basetools to provide better ways to optimize the use of PCD,

but from the previous discussion it seems to take quite a long time,

do you think we can merge the current patch first and then optimize it?

 

Thanks,

Yi

 

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Saturday, September 24, 2022 10:19 AM
To: Yao, Jiewen <jiewen.yao@...>; Li, Yi1 <yi1.li@...>; devel@edk2.groups.io; Chen, Christine <yuwei.chen@...>; Feng, Bob C <bob.c.feng@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...>; Luo, Heng <heng.luo@...>
Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

 

Hi Jiewen,

 

My feedback on this topic back on 4/18/22 was never addressed and this PCD was added anyways.

 

    https://edk2.groups.io/g/devel/message/89019

 

My main concern at this point is how a platform developer knows how to configure these PCDs.

 

When should PcdOpensslEcEnabled be set to TRUE?  The name of the PCD implies that EC services

are available, but that is not actually true.  It only compiles the EC source files into

the openssl lib.

 

I think a developer has to enable other features in order to actually make use of the

content provided by those source files.  Correct?

 

The other INF that adds the SSL files has the same issue.  How does a developer know when

to use the INF with the SSL files or not.  And what features need to be enabled in order to use

the content added by those SSL files. 

 

We have a number of services in the BaseCryptLib that can be enabled and disabled using

the structured PCD gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.

 

Can someone provide a table that shows each service from gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable

and if the service is impacted by the inclusion of the ssl sources and/or the ec sources.  If there is an impact,

then describe the difference in the behavior for each of the 4 combinations of ssl and ec sources

 

Example:

 

gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable   SSL    EC    Description

========================================================  =====  =====  ===========

Sha256.Services.Init                                      FALSE  FALSE

Sha256.Services.Init                                      FALSE   TRUE

Sha256.Services.Init                                       TRUE  FALSE

Sha256.Services.Init                                       TRUE   TRUE

 

If there is a shorter way to describe the impact at the family level or groups of families, then

that would be acceptable as well.

 

I would prefer the ssl and ec sources from openssl be added/removed based on settings

in the gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.  However, the feature

flag expressions supported in INF files today do not support use of fields from

structured PCDs.  This needs to be discuss with the BaseTools owners to see if this

would be difficult to support or not.

 

Thanks,

 

Mike

 

 

> -----Original Message-----

> From: Yao, Jiewen <jiewen.yao@...>

> Sent: Friday, September 23, 2022 3:40 PM

> To: Li, Yi1 <yi1.li@...>; Kinney, Michael D <michael.d.kinney@...>; devel@edk2.groups.io; Chen, Christine

> <yuwei.chen@...>; Feng, Bob C <bob.c.feng@...>

> Cc: Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...>; Luo,

> Heng <heng.luo@...>

> Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

>

> Hi Mike

> This has been investigated before, but we don’t have better solution than PcdOpensslEcEnabled.

>

> Given the fact that this PCD is introduced before (not in this patch set), do you think we can merge this first, then do

> enhancement for PCD related stuff later?

>

> Or if you have any other idea, please let us know.

>

> Thank you

> Yao Jiewen

>

> > -----Original Message-----

> > From: Li, Yi1 <yi1.li@...>

> > Sent: Friday, September 23, 2022 3:09 PM

> > To: Kinney, Michael D <michael.d.kinney@...>;

> > devel@edk2.groups.io; Chen, Christine <yuwei.chen@...>; Feng, Bob

> > C <bob.c.feng@...>

> > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > Guomin <guomin.jiang@...>; Luo, Heng <heng.luo@...>

> > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> >

> > 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.kinney@...>

> > Sent: Friday, September 23, 2022 1:25 PM

> > To: Li, Yi1 <yi1.li@...>; devel@edk2.groups.io; Chen, Christine

> > <yuwei.chen@...>; Feng, Bob C <bob.c.feng@...>; Kinney,

> > Michael D <michael.d.kinney@...>

> > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > Guomin <guomin.jiang@...>

> > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> >

> > 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.li@...>

> > > Sent: Thursday, September 22, 2022 8:02 PM

> > > To: Kinney, Michael D <michael.d.kinney@...>;

> > devel@edk2.groups.io

> > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > Guomin <guomin.jiang@...>

> > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > >

> > > Hi Mike,

> > >

> > > 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.kinney@...>

> > > Sent: Friday, September 23, 2022 6:47 AM

> > > To: Li, Yi1 <yi1.li@...>; devel@edk2.groups.io; Kinney, Michael D

> > <michael.d.kinney@...>

> > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > Guomin <guomin.jiang@...>

> > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > >

> > > 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.li@...>

> > > > Sent: Thursday, September 22, 2022 5:54 AM

> > > > To: Kinney, Michael D <michael.d.kinney@...>;

> > devel@edk2.groups.io; Kishore, Shelly <shelly.kishore@...>

> > > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > > Guomin <guomin.jiang@...>

> > > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > > >

> > > > Hi Mike,

> > > > 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.kinney@...>

> > > > Sent: Thursday, September 22, 2022 11:56 AM

> > > > To: Li, Yi1 <yi1.li@...>; devel@edk2.groups.io; Kishore, Shelly

> > <shelly.kishore@...>

> > > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > > Guomin <guomin.jiang@...>

> > > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > > >

> > > > 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.li@...>

> > > > > Sent: Wednesday, September 21, 2022 7:16 PM

> > > > > To: Kinney, Michael D <michael.d.kinney@...>;

> > devel@edk2.groups.io

> > > > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > > > Guomin <guomin.jiang@...>

> > > > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > > > >

> > > > > Hi Mike,

> > > > > Thanks for review.

> > > > >

> > > > > Even PCD_CRYPTO_SERVICE_FAMILY_ENABLE is set to 0, CryptoEc.c

> > will also be compiled and throw build error:

> > > > >

> > > > >

> > d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.

> > c(77): error C2220: the following warning is treated

> > > > as

> > > > > an error

> > > > >         1 file(s) copied.

> > > > >

> > d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.

> > c(77): warning C4013: 'EC_GROUP_new_by_curve_name'

> > > > > undefined; assuming extern returning int

> > > > >

> > d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.

> > c(77): warning C4047: 'return': 'void *' differs in

> > > > > levels of indirection from 'int'

> > > > >

> > d:\workspace\tianocore\edk2\CryptoPkg\Library\BaseCryptLib\Pk\CryptEc.

> > c(105): warning C4013: 'EC_GROUP_get_curve'

> > > undefined;

> > > > > assuming extern returning int

> > > > >

> > > > > I think the root cause is that we have enabled conditional ec in

> > OpensslLib.inf before by PcdOpensslEcEnabled,

> > > > >

> > > >

> > >

> > https://github.com/tianocore/edk2/blob/2c17d676e402d75a3a67449934

> > 2f7ddaccf387bd/CryptoPkg/Library/OpensslLib/OpensslLib.inf#L2

> > > > > 02-L238

> > > > >  if PcdOpensslEcEnabled not true, all ec files will not be compiled.

> > > > > This will save 200+kb memory on platforms which use dxe driver but

> > do not need ec feature.

> > > > >

> > > > > So I add this PCD to BaseCryptLib.inf also to avoid build error, Not

> > sure if there is any other way, other better ideas

> > > are

> > > > > welcome.

> > > > >

> > > > > Thanks,

> > > > > Yi

> > > > >

> > > > > -----Original Message-----

> > > > > From: Kinney, Michael D <michael.d.kinney@...>

> > > > > Sent: Thursday, September 22, 2022 12:22 AM

> > > > > To: devel@edk2.groups.io; Li, Yi1 <yi1.li@...>; Kinney, Michael

> > D <michael.d.kinney@...>

> > > > > Cc: Yao, Jiewen <jiewen.yao@...>; Wang, Jian J

> > <jian.j.wang@...>; Lu, Xiaoyu1 <xiaoyu1.lu@...>; Jiang,

> > > > > Guomin <guomin.jiang@...>

> > > > > Subject: RE: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > > > >

> > > > > Comments embedded below.

> > > > >

> > > > > Mike

> > > > >

> > > > > > -----Original Message-----

> > > > > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of

> > yi1 li

> > > > > > Sent: Tuesday, September 20, 2022 9:55 PM

> > > > > > To: devel@edk2.groups.io

> > > > > > Cc: Li, Yi1 <yi1.li@...>; Yao, Jiewen <jiewen.yao@...>;

> > Wang, Jian J <jian.j.wang@...>; Lu, Xiaoyu1

> > > > > > <xiaoyu1.lu@...>; Jiang, Guomin <guomin.jiang@...>

> > > > > > Subject: [edk2-devel] [PATCH V2 1/3] CryptoPkg: Add EC support

> > > > > >

> > > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828

> > > > > >

> > > > > > This patch is used to add CryptEc library, which is wrapped

> > > > > > over OpenSSL.

> > > > > >

> > > > > > Cc: Jiewen Yao <jiewen.yao@...>

> > > > > > Cc: Jian J Wang <jian.j.wang@...>

> > > > > > Cc: Xiaoyu Lu <xiaoyu1.lu@...>

> > > > > > Cc: Guomin Jiang <guomin.jiang@...>

> > > > > >

> > > > > > Signed-off-by: Yi Li <yi1.li@...>

> > > > > > ---

> > > > > >  CryptoPkg/Include/Library/BaseCryptLib.h      | 424 ++++++++++

> > > > > >  .../Library/BaseCryptLib/BaseCryptLib.inf     |   2 +

> > > > > >  .../Library/BaseCryptLib/PeiCryptLib.inf      |   1 +

> > > > > >  CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c   | 765

> > ++++++++++++++++++

> > > > > >  .../Library/BaseCryptLib/Pk/CryptEcNull.c     | 496 ++++++++++++

> > > > > >  .../Library/BaseCryptLib/SmmCryptLib.inf      |   1 +

> > > > > >  .../BaseCryptLibNull/BaseCryptLibNull.inf     |   1 +

> > > > > >  .../Library/BaseCryptLibNull/Pk/CryptEcNull.c | 496 ++++++++++++

> > > > > >  8 files changed, 2186 insertions(+)

> > > > > >  create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c

> > > > > >  create mode 100644

> > CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c

> > > > > >  create mode 100644

> > CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c

> > > > > >

> > > > > > diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h

> > b/CryptoPkg/Include/Library/BaseCryptLib.h

> > > > > > index b253923dd8..d74fc21c1e 100644

> > > > > > --- a/CryptoPkg/Include/Library/BaseCryptLib.h

> > > > > > +++ b/CryptoPkg/Include/Library/BaseCryptLib.h

> > > > > > @@ -14,6 +14,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

> > > > > >

> > > > > >  #include <Uefi/UefiBaseType.h>

> > > > > >

> > > > > > +#define CRYPTO_NID_NULL  0x0000

> > > > > > +

> > > > > > +// Key Exchange

> > > > > > +#define CRYPTO_NID_SECP256R1  0x0204

> > > > > > +#define CRYPTO_NID_SECP384R1  0x0205

> > > > > > +#define CRYPTO_NID_SECP521R1  0x0206

> > > > > > +

> > > > > >  ///

> > > > > >  /// MD5 digest size in bytes

> > > > > >  ///

> > > > > > @@ -2850,4 +2857,421 @@ BigNumAddMod (

> > > > > >    OUT VOID       *BnRes

> > > > > >    );

> > > > > >

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +//    Basic Elliptic Curve Primitives

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EcGroup object. This object represents an EC

> > curve and

> > > > > > +  and is used for calculation within this group. This object should be

> > freed

> > > > > > +  using EcGroupFree() function.

> > > > > > +

> > > > > > +  @param[in]  CryptoNid   Identifying number for the ECC curve

> > (Defined in

> > > > > > +                          BaseCryptLib.h).

> > > > > > +

> > > > > > +  @retval EcGroup object  On success.

> > > > > > +  @retval NULL            On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcGroupInit (

> > > > > > +  IN UINTN  CryptoNid

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC curve parameters. While elliptic curve equation is Y^2 mod

> > P = (X^3 + AX + B) Mod P.

> > > > > > +  This function will set the provided Big Number objects  to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[out] BnPrime    Group prime number.

> > > > > > +  @param[out] BnA        A coefficient.

> > > > > > +  @param[out] BnB        B coefficient.

> > > > > > +  @param[in]  BnCtx      BN context.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *BnPrime,

> > > > > > +  OUT VOID       *BnA,

> > > > > > +  OUT VOID       *BnB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC group order.

> > > > > > +  This function will set the provided Big Number object to the

> > corresponding

> > > > > > +  value. The caller needs to make sure that the "out" BigNumber

> > parameter

> > > > > > +  is properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[out] BnOrder   Group prime number.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetOrder (

> > > > > > +  IN VOID   *EcGroup,

> > > > > > +  OUT VOID  *BnOrder

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC group object using EcGroupInit().

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object to free.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcGroupFree (

> > > > > > +  IN VOID  *EcGroup

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EC Point object. This object represents an EC

> > point

> > > > > > +  within the given EC group (curve).

> > > > > > +

> > > > > > +  @param[in]  EC Group, properly initialized using EcGroupInit().

> > > > > > +

> > > > > > +  @retval EC Point object  On success.

> > > > > > +  @retval NULL             On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcPointInit (

> > > > > > +  IN CONST VOID  *EcGroup

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC Point object using EcPointInit().

> > > > > > +

> > > > > > +  @param[in]  EcPoint   EC Point to free.

> > > > > > +  @param[in]  Clear     TRUE iff the memory should be cleared.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcPointDeInit (

> > > > > > +  IN VOID     *EcPoint,

> > > > > > +  IN BOOLEAN  Clear

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC point affine (x,y) coordinates.

> > > > > > +  This function will set the provided Big Number objects to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[out] BnX        X coordinate.

> > > > > > +  @param[out] BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointGetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  OUT VOID       *BnX,

> > > > > > +  OUT VOID       *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point affine (x,y) coordinates.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN CONST VOID  *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  EC Point addition. EcPointResult = EcPointA + EcPointB.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPointA         EC Point.

> > > > > > +  @param[in]  EcPointB         EC Point.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointAdd (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Variable EC point multiplication. EcPointResult = EcPoint *

> > BnPScalar.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPoint          EC Point.

> > > > > > +  @param[in]  BnPScalar        P Scalar.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointMul (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN CONST VOID  *BnPScalar,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Calculate the inverse of the supplied EC point.

> > > > > > +

> > > > > > +  @param[in]     EcGroup   EC group object.

> > > > > > +  @param[in,out] EcPoint   EC point to invert.

> > > > > > +  @param[in]     BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointInvert (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN OUT VOID    *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is on EC curve.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On curve.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsOnCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is at infinity.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +

> > > > > > +  @retval TRUE          At infinity.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsAtInfinity (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if EC points are equal.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPointA  EC point A.

> > > > > > +  @param[in]  EcPointB  EC point B.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          A == B.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointEqual (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point compressed coordinates. Points can be described in

> > terms of

> > > > > > +  their compressed coordinates. For a point (x, y), for any given

> > value for x

> > > > > > +  such that the point is on the curve there will only ever be two

> > possible

> > > > > > +  values for y. Therefore, a point can be set using this function

> > where BnX is

> > > > > > +  the x coordinate and YBit is a value 0 or 1 to identify which of the

> > two

> > > > > > +  possible values for y should be used.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC Point.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  YBit       0 or 1 to identify which Y value is used.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetCompressedCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN UINT8       YBit,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  );

> > > > > > +

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +//    Elliptic Curve Diffie Hellman Primitives

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +

> > > > > > +/**

> > > > > > +  Allocates and Initializes one Elliptic Curve Context for subsequent

> > use

> > > > > > +  with the NID.

> > > > > > +

> > > > > > +  @param[in]  Nid cipher NID

> > > > > > +  @return     Pointer to the Elliptic Curve Context that has been

> > initialized.

> > > > > > +              If the allocations fails, EcNewByNid() returns NULL.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcNewByNid (

> > > > > > +  IN UINTN  Nid

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Release the specified EC context.

> > > > > > +

> > > > > > +  @param[in]  EcContext  Pointer to the EC context to be released.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcFree (

> > > > > > +  IN  VOID  *EcContext

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Generates EC key and returns EC public key (X, Y), Please note,

> > this function uses

> > > > > > +  pseudo random number generator. The caller must make sure

> > RandomSeed()

> > > > > > +  function was properly called before.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid.

> > > > > > +  This function generates random secret, and computes the public

> > key (X, Y), which is

> > > > > > +  returned via parameter Public, PublicSize.

> > > > > > +  X is the first half of Public with size being PublicSize / 2,

> > > > > > +  Y is the second half of Public with size being PublicSize / 2.

> > > > > > +  EC context is updated accordingly.

> > > > > > +  If the Public buffer is too small to hold the public X, Y, FALSE is

> > returned and

> > > > > > +  PublicSize is set to the required buffer size to obtain the public X,

> > Y.

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PublicSize is NULL, then return FALSE.

> > > > > > +  If PublicSize is large enough but Public is NULL, then return FALSE.

> > > > > > +  @param[in, out]  EcContext      Pointer to the EC context.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC public X,Y generation succeeded.

> > > > > > +  @retval FALSE  EC public X,Y generation failed.

> > > > > > +  @retval FALSE  PublicKeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGenerateKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Gets the public key component from the established EC context.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid, and

> > successfully

> > > > > > +  generate key pair from EcGenerateKey().

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  @param[in, out]  EcContext      Pointer to EC context being set.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval  TRUE   EC key component was retrieved successfully.

> > > > > > +  @retval  FALSE  Invalid EC key component.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGetPubKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  );

> > > > > > +

> > > > > > +/**

> > > > > > +  Computes exchanged common key.

> > > > > > +  Given peer's public key (X, Y), this function computes the

> > exchanged common key,

> > > > > > +  based on its own context including value of curve parameter and

> > random secret.

> > > > > > +  X is the first half of PeerPublic with size being PeerPublicSize / 2,

> > > > > > +  Y is the second half of PeerPublic with size being PeerPublicSize /

> > 2.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PeerPublic is NULL, then return FALSE.

> > > > > > +  If PeerPublicSize is 0, then return FALSE.

> > > > > > +  If Key is NULL, then return FALSE.

> > > > > > +  If KeySize is not large enough, then return FALSE.

> > > > > > +  For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-

> > byte is Y.

> > > > > > +  For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-

> > byte is Y.

> > > > > > +  For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-

> > byte is Y.

> > > > > > +  @param[in, out]  EcContext          Pointer to the EC context.

> > > > > > +  @param[in]       PeerPublic         Pointer to the peer's public X,Y.

> > > > > > +  @param[in]       PeerPublicSize     Size of peer's public X,Y in bytes.

> > > > > > +  @param[in]       CompressFlag       Flag of PeerPublic is

> > compressed or not.

> > > > > > +  @param[out]      Key                Pointer to the buffer to receive

> > generated key.

> > > > > > +  @param[in, out]  KeySize            On input, the size of Key buffer in

> > bytes.

> > > > > > +                                      On output, the size of data returned in Key

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC exchanged key generation succeeded.

> > > > > > +  @retval FALSE  EC exchanged key generation failed.

> > > > > > +  @retval FALSE  KeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcDhComputeKey (

> > > > > > +  IN OUT  VOID         *EcContext,

> > > > > > +  IN      CONST UINT8  *PeerPublic,

> > > > > > +  IN      UINTN        PeerPublicSize,

> > > > > > +  IN      CONST INT32  *CompressFlag,

> > > > > > +  OUT     UINT8        *Key,

> > > > > > +  IN OUT  UINTN        *KeySize

> > > > > > +  );

> > > > > > +

> > > > > >  #endif // __BASE_CRYPT_LIB_H__

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf

> > b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf

> > > > > > index 9e4be2fb0d..ade6ee3fdd 100644

> > > > > > --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf

> > > > > > @@ -52,6 +52,8 @@

> > > > > >    Pk/CryptTs.c

> > > > > >    Pk/CryptRsaPss.c

> > > > > >    Pk/CryptRsaPssSign.c

> > > > > > +  Pk/CryptEcNull.c

> > |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled

> > > > > > +  Pk/CryptEc.c

> > |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled

> > > > >

> > > > > The use of the PCD to select the file should not be needed here.  The

> > > > > Ec Family and individual service enable/disable fields in the

> > > > > PCD_CRYPTO_SERVICE_FAMILY_ENABLE structured PCD are all that is

> > needed to

> > > > > disable the Ec services.

> > > > >

> > > > > The PCD gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled should

> > be removed

> > > > > completely as part of this patch series.

> > > > >

> > > > > >    Pem/CryptPem.c

> > > > > >    Bn/CryptBn.c

> > > > > >

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf

> > b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf

> > > > > > index 65ad23fb81..383df2b23c 100644

> > > > > > --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf

> > > > > > @@ -58,6 +58,7 @@

> > > > > >    Pk/CryptTsNull.c

> > > > > >    Pk/CryptRsaPss.c

> > > > > >    Pk/CryptRsaPssSignNull.c

> > > > > > +  Pk/CryptEcNull.c

> > > > > >    Pem/CryptPemNull.c

> > > > > >    Rand/CryptRandNull.c

> > > > > >    Bn/CryptBnNull.c

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c

> > b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c

> > > > > > new file mode 100644

> > > > > > index 0000000000..396c819834

> > > > > > --- /dev/null

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c

> > > > > > @@ -0,0 +1,765 @@

> > > > > > +/** @file

> > > > > > +  Elliptic Curve and ECDH API implementation based on OpenSSL

> > > > > > +

> > > > > > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

> > > > > > +  SPDX-License-Identifier: BSD-2-Clause-Patent

> > > > > > +

> > > > > > +**/

> > > > > > +

> > > > > > +#include "InternalCryptLib.h"

> > > > > > +#include <openssl/objects.h>

> > > > > > +#include <openssl/bn.h>

> > > > > > +#include <openssl/ec.h>

> > > > > > +

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +//    Basic Elliptic Curve Primitives

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +

> > > > > > +/**

> > > > > > +  Return the Nid of certain ECC curve.

> > > > > > +

> > > > > > +  @param[in]  CryptoNid   Identifying number for the ECC curve

> > (Defined in

> > > > > > +                          BaseCryptLib.h).

> > > > > > +

> > > > > > +  @retval !=-1    On success.

> > > > > > +  @retval -1      ECC curve not supported.

> > > > > > +**/

> > > > > > +STATIC

> > > > > > +INT32

> > > > > > +CryptoNidToOpensslNid (

> > > > > > +  IN UINTN  CryptoNid

> > > > > > +  )

> > > > > > +{

> > > > > > +  INT32  Nid;

> > > > > > +

> > > > > > +  switch (CryptoNid) {

> > > > > > +    case CRYPTO_NID_SECP256R1:

> > > > > > +      Nid = NID_X9_62_prime256v1;

> > > > > > +      break;

> > > > > > +    case CRYPTO_NID_SECP384R1:

> > > > > > +      Nid = NID_secp384r1;

> > > > > > +      break;

> > > > > > +    case CRYPTO_NID_SECP521R1:

> > > > > > +      Nid = NID_secp521r1;

> > > > > > +      break;

> > > > > > +    default:

> > > > > > +      return -1;

> > > > > > +  }

> > > > > > +

> > > > > > +  return Nid;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EcGroup object. This object represents an EC

> > curve and

> > > > > > +  and is used for calculation within this group. This object should be

> > freed

> > > > > > +  using EcGroupFree() function.

> > > > > > +

> > > > > > +  @param[in]  CryptoNid   Identifying number for the ECC curve

> > (Defined in

> > > > > > +                          BaseCryptLib.h).

> > > > > > +

> > > > > > +  @retval EcGroup object  On success.

> > > > > > +  @retval NULL            On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcGroupInit (

> > > > > > +  IN UINTN  CryptoNid

> > > > > > +  )

> > > > > > +{

> > > > > > +  INT32  Nid;

> > > > > > +

> > > > > > +  Nid = CryptoNidToOpensslNid (CryptoNid);

> > > > > > +

> > > > > > +  if (Nid < 0) {

> > > > > > +    return NULL;

> > > > > > +  }

> > > > > > +

> > > > > > +  return EC_GROUP_new_by_curve_name (Nid);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC curve parameters. While elliptic curve equation is Y^2 mod

> > P = (X^3 + AX + B) Mod P.

> > > > > > +  This function will set the provided Big Number objects  to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[out] BnPrime    Group prime number.

> > > > > > +  @param[out] BnA        A coefficient.

> > > > > > +  @param[out] BnB        B coefficient..

> > > > > > +  @param[in]  BnCtx      BN context.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *BnPrime,

> > > > > > +  OUT VOID       *BnA,

> > > > > > +  OUT VOID       *BnB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA,

> > BnB, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC group order.

> > > > > > +  This function will set the provided Big Number object to the

> > corresponding

> > > > > > +  value. The caller needs to make sure that the "out" BigNumber

> > parameter

> > > > > > +  is properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[out] BnOrder   Group prime number.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetOrder (

> > > > > > +  IN VOID   *EcGroup,

> > > > > > +  OUT VOID  *BnOrder

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder,

> > NULL);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC group object using EcGroupInit().

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object to free.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcGroupFree (

> > > > > > +  IN VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  EC_GROUP_free (EcGroup);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EC Point object. This object represents an EC

> > point

> > > > > > +  within the given EC group (curve).

> > > > > > +

> > > > > > +  @param[in]  EC Group, properly initialized using EcGroupInit().

> > > > > > +

> > > > > > +  @retval EC Point object  On success.

> > > > > > +  @retval NULL             On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcPointInit (

> > > > > > +  IN CONST VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  return EC_POINT_new (EcGroup);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC Point object using EcPointInit().

> > > > > > +

> > > > > > +  @param[in]  EcPoint   EC Point to free.

> > > > > > +  @param[in]  Clear     TRUE iff the memory should be cleared.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcPointDeInit (

> > > > > > +  IN VOID     *EcPoint,

> > > > > > +  IN BOOLEAN  Clear

> > > > > > +  )

> > > > > > +{

> > > > > > +  if (Clear) {

> > > > > > +    EC_POINT_clear_free (EcPoint);

> > > > > > +  } else {

> > > > > > +    EC_POINT_free (EcPoint);

> > > > > > +  }

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC point affine (x,y) coordinates.

> > > > > > +  This function will set the provided Big Number objects to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[out] BnX        X coordinate.

> > > > > > +  @param[out] BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointGetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  OUT VOID       *BnX,

> > > > > > +  OUT VOID       *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup,

> > EcPoint, BnX, BnY, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point affine (x,y) coordinates.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN CONST VOID  *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup,

> > EcPoint, BnX, BnY, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  EC Point addition. EcPointResult = EcPointA + EcPointB.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPointA         EC Point.

> > > > > > +  @param[in]  EcPointB         EC Point.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointAdd (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult,

> > EcPointA, EcPointB, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Variable EC point multiplication. EcPointResult = EcPoint *

> > BnPScalar.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPoint          EC Point.

> > > > > > +  @param[in]  BnPScalar        P Scalar.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointMul (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN CONST VOID  *BnPScalar,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult, NULL,

> > EcPoint, BnPScalar, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Calculate the inverse of the supplied EC point.

> > > > > > +

> > > > > > +  @param[in]     EcGroup   EC group object.

> > > > > > +  @param[in,out] EcPoint   EC point to invert.

> > > > > > +  @param[in]     BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointInvert (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN OUT VOID    *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is on EC curve.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On curve.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsOnCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) == 1;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is at infinity.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +

> > > > > > +  @retval TRUE          At infinity.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsAtInfinity (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint

> > > > > > +  )

> > > > > > +{

> > > > > > +  return EC_POINT_is_at_infinity (EcGroup, EcPoint) == 1;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if EC points are equal.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPointA  EC point A.

> > > > > > +  @param[in]  EcPointB  EC point B.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          A == B.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointEqual (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) == 0;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point compressed coordinates. Points can be described in

> > terms of

> > > > > > +  their compressed coordinates. For a point (x, y), for any given

> > value for x

> > > > > > +  such that the point is on the curve there will only ever be two

> > possible

> > > > > > +  values for y. Therefore, a point can be set using this function

> > where BnX is

> > > > > > +  the x coordinate and YBit is a value 0 or 1 to identify which of the

> > two

> > > > > > +  possible values for y should be used.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC Point.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  YBit       0 or 1 to identify which Y value is used.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetCompressedCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN UINT8       YBit,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  return (BOOLEAN)EC_POINT_set_compressed_coordinates

> > (EcGroup, EcPoint, BnX, YBit, BnCtx);

> > > > > > +}

> > > > > > +

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +//    Elliptic Curve Diffie Hellman Primitives

> > > > > > +//

> > ==========================================================

> > ===========================

> > > > > > +

> > > > > > +/**

> > > > > > +  Allocates and Initializes one Elliptic Curve Context for subsequent

> > use

> > > > > > +  with the NID.

> > > > > > +

> > > > > > +  @param[in]  Nid   Identifying number for the ECC curve (Defined

> > in

> > > > > > +                    BaseCryptLib.h).

> > > > > > +  @return     Pointer to the Elliptic Curve Context that has been

> > initialized.

> > > > > > +              If the allocations fails, EcNewByNid() returns NULL.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcNewByNid (

> > > > > > +  IN UINTN  Nid

> > > > > > +  )

> > > > > > +{

> > > > > > +  INT32  OpenSslNid;

> > > > > > +

> > > > > > +  OpenSslNid = CryptoNidToOpensslNid (Nid);

> > > > > > +  if (OpenSslNid < 0) {

> > > > > > +    return NULL;

> > > > > > +  }

> > > > > > +

> > > > > > +  return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Release the specified EC context.

> > > > > > +

> > > > > > +  @param[in]  EcContext  Pointer to the EC context to be released.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcFree (

> > > > > > +  IN  VOID  *EcContext

> > > > > > +  )

> > > > > > +{

> > > > > > +  EC_KEY_free ((EC_KEY *)EcContext);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Generates EC key and returns EC public key (X, Y), Please note,

> > this function uses

> > > > > > +  pseudo random number generator. The caller must make sure

> > RandomSeed()

> > > > > > +  function was properly called before.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid.

> > > > > > +  This function generates random secret, and computes the public

> > key (X, Y), which is

> > > > > > +  returned via parameter Public, PublicSize.

> > > > > > +  X is the first half of Public with size being PublicSize / 2,

> > > > > > +  Y is the second half of Public with size being PublicSize / 2.

> > > > > > +  EC context is updated accordingly.

> > > > > > +  If the Public buffer is too small to hold the public X, Y, FALSE is

> > returned and

> > > > > > +  PublicSize is set to the required buffer size to obtain the public X,

> > Y.

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PublicSize is NULL, then return FALSE.

> > > > > > +  If PublicSize is large enough but Public is NULL, then return FALSE.

> > > > > > +  @param[in, out]  EcContext      Pointer to the EC context.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC public X,Y generation succeeded.

> > > > > > +  @retval FALSE  EC public X,Y generation failed.

> > > > > > +  @retval FALSE  PublicKeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGenerateKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  EC_KEY          *EcKey;

> > > > > > +  CONST EC_GROUP  *Group;

> > > > > > +  CONST EC_POINT  *EcPoint;

> > > > > > +  BOOLEAN         RetVal;

> > > > > > +  BIGNUM          *BnX;

> > > > > > +  BIGNUM          *BnY;

> > > > > > +  UINTN           HalfSize;

> > > > > > +  INTN            XSize;

> > > > > > +  INTN            YSize;

> > > > > > +

> > > > > > +  if ((EcContext == NULL) || (PublicKeySize == NULL)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if ((PublicKey == NULL) && (*PublicKeySize != 0)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  EcKey    = (EC_KEY *)EcContext;

> > > > > > +  Group    = EC_KEY_get0_group (EcKey);

> > > > > > +  HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;

> > > > > > +

> > > > > > +  // Assume RAND_seed was called

> > > > > > +  if (EC_KEY_generate_key (EcKey) != 1) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (*PublicKeySize < HalfSize * 2) {

> > > > > > +    *PublicKeySize = HalfSize * 2;

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  *PublicKeySize = HalfSize * 2;

> > > > > > +

> > > > > > +  EcPoint = EC_KEY_get0_public_key (EcKey);

> > > > > > +  if (EcPoint == NULL) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  RetVal = FALSE;

> > > > > > +  BnX    = BN_new ();

> > > > > > +  BnY    = BN_new ();

> > > > > > +  if ((BnX == NULL) || (BnY == NULL)) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY,

> > NULL) != 1) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  XSize = BN_num_bytes (BnX);

> > > > > > +  YSize = BN_num_bytes (BnY);

> > > > > > +  if ((XSize <= 0) || (YSize <= 0)) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize);

> > > > > > +

> > > > > > +  ZeroMem (PublicKey, *PublicKeySize);

> > > > > > +  BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);

> > > > > > +  BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);

> > > > > > +

> > > > > > +  RetVal = TRUE;

> > > > > > +

> > > > > > +fail:

> > > > > > +  BN_free (BnX);

> > > > > > +  BN_free (BnY);

> > > > > > +  return RetVal;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Gets the public key component from the established EC context.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid, and

> > successfully

> > > > > > +  generate key pair from EcGenerateKey().

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  @param[in, out]  EcContext      Pointer to EC context being set.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval  TRUE   EC key component was retrieved successfully.

> > > > > > +  @retval  FALSE  Invalid EC key component.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGetPubKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  EC_KEY          *EcKey;

> > > > > > +  CONST EC_GROUP  *Group;

> > > > > > +  CONST EC_POINT  *EcPoint;

> > > > > > +  BIGNUM          *BnX;

> > > > > > +  BIGNUM          *BnY;

> > > > > > +  UINTN           HalfSize;

> > > > > > +  INTN            XSize;

> > > > > > +  INTN            YSize;

> > > > > > +  BOOLEAN         RetVal;

> > > > > > +

> > > > > > +  if ((EcContext == NULL) || (PublicKeySize == NULL)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if ((PublicKey == NULL) && (*PublicKeySize != 0)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  EcKey    = (EC_KEY *)EcContext;

> > > > > > +  Group    = EC_KEY_get0_group (EcKey);

> > > > > > +  HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;

> > > > > > +  if (*PublicKeySize < HalfSize * 2) {

> > > > > > +    *PublicKeySize = HalfSize * 2;

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  *PublicKeySize = HalfSize * 2;

> > > > > > +

> > > > > > +  EcPoint = EC_KEY_get0_public_key (EcKey);

> > > > > > +  if (EcPoint == NULL) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  RetVal = FALSE;

> > > > > > +  BnX    = BN_new ();

> > > > > > +  BnY    = BN_new ();

> > > > > > +  if ((BnX == NULL) || (BnY == NULL)) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY,

> > NULL) != 1) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  XSize = BN_num_bytes (BnX);

> > > > > > +  YSize = BN_num_bytes (BnY);

> > > > > > +  if ((XSize <= 0) || (YSize <= 0)) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize);

> > > > > > +

> > > > > > +  if (PublicKey != NULL) {

> > > > > > +    ZeroMem (PublicKey, *PublicKeySize);

> > > > > > +    BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);

> > > > > > +    BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);

> > > > > > +  }

> > > > > > +

> > > > > > +  RetVal = TRUE;

> > > > > > +

> > > > > > +fail:

> > > > > > +  BN_free (BnX);

> > > > > > +  BN_free (BnY);

> > > > > > +  return RetVal;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Computes exchanged common key.

> > > > > > +  Given peer's public key (X, Y), this function computes the

> > exchanged common key,

> > > > > > +  based on its own context including value of curve parameter and

> > random secret.

> > > > > > +  X is the first half of PeerPublic with size being PeerPublicSize / 2,

> > > > > > +  Y is the second half of PeerPublic with size being PeerPublicSize /

> > 2.

> > > > > > +  If public key is compressed, the PeerPublic will only contain half

> > key (X).

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PeerPublic is NULL, then return FALSE.

> > > > > > +  If PeerPublicSize is 0, then return FALSE.

> > > > > > +  If Key is NULL, then return FALSE.

> > > > > > +  If KeySize is not large enough, then return FALSE.

> > > > > > +  For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-

> > byte is Y.

> > > > > > +  For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-

> > byte is Y.

> > > > > > +  For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-

> > byte is Y.

> > > > > > +  @param[in, out]  EcContext          Pointer to the EC context.

> > > > > > +  @param[in]       PeerPublic         Pointer to the peer's public X,Y.

> > > > > > +  @param[in]       PeerPublicSize     Size of peer's public X,Y in bytes.

> > > > > > +  @param[in]       CompressFlag       Flag of PeerPublic is

> > compressed or not.

> > > > > > +  @param[out]      Key                Pointer to the buffer to receive

> > generated key.

> > > > > > +  @param[in, out]  KeySize            On input, the size of Key buffer in

> > bytes.

> > > > > > +                                      On output, the size of data returned in Key

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC exchanged key generation succeeded.

> > > > > > +  @retval FALSE  EC exchanged key generation failed.

> > > > > > +  @retval FALSE  KeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcDhComputeKey (

> > > > > > +  IN OUT  VOID         *EcContext,

> > > > > > +  IN      CONST UINT8  *PeerPublic,

> > > > > > +  IN      UINTN        PeerPublicSize,

> > > > > > +  IN      CONST INT32  *CompressFlag,

> > > > > > +  OUT     UINT8        *Key,

> > > > > > +  IN OUT  UINTN        *KeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  EC_KEY          *EcKey;

> > > > > > +  EC_KEY          *PeerEcKey;

> > > > > > +  CONST EC_GROUP  *Group;

> > > > > > +  BOOLEAN         RetVal;

> > > > > > +  BIGNUM          *BnX;

> > > > > > +  BIGNUM          *BnY;

> > > > > > +  EC_POINT        *Point;

> > > > > > +  INT32           OpenSslNid;

> > > > > > +  UINTN           HalfSize;

> > > > > > +

> > > > > > +  if ((EcContext == NULL) || (PeerPublic == NULL) || (KeySize ==

> > NULL)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if ((Key == NULL) && (*KeySize != 0)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (PeerPublicSize > INT_MAX) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  EcKey    = (EC_KEY *)EcContext;

> > > > > > +  Group    = EC_KEY_get0_group (EcKey);

> > > > > > +  HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;

> > > > > > +  if ((CompressFlag == NULL) && (PeerPublicSize != HalfSize * 2)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if ((CompressFlag != NULL) && (PeerPublicSize != HalfSize)) {

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (*KeySize < HalfSize) {

> > > > > > +    *KeySize = HalfSize;

> > > > > > +    return FALSE;

> > > > > > +  }

> > > > > > +

> > > > > > +  *KeySize = HalfSize;

> > > > > > +

> > > > > > +  RetVal    = FALSE;

> > > > > > +  Point     = NULL;

> > > > > > +  BnX       = BN_bin2bn (PeerPublic, (INT32)HalfSize, NULL);

> > > > > > +  BnY       = NULL;

> > > > > > +  Point     = EC_POINT_new (Group);

> > > > > > +  PeerEcKey = NULL;

> > > > > > +  if ((BnX == NULL) || (Point == NULL)) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (CompressFlag == NULL) {

> > > > > > +    BnY = BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize, NULL);

> > > > > > +    if (BnY == NULL) {

> > > > > > +      goto fail;

> > > > > > +    }

> > > > > > +

> > > > > > +    if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY,

> > NULL) != 1) {

> > > > > > +      goto fail;

> > > > > > +    }

> > > > > > +  } else {

> > > > > > +    if (EC_POINT_set_compressed_coordinates (Group, Point, BnX,

> > *CompressFlag, NULL) != 1) {

> > > > > > +      goto fail;

> > > > > > +    }

> > > > > > +  }

> > > > > > +

> > > > > > +  // Validate NIST ECDH public key

> > > > > > +  OpenSslNid = EC_GROUP_get_curve_name (Group);

> > > > > > +  PeerEcKey  = EC_KEY_new_by_curve_name (OpenSslNid);

> > > > > > +  if (PeerEcKey == NULL) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (EC_KEY_set_public_key (PeerEcKey, Point) != 1) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (EC_KEY_check_key (PeerEcKey) != 1) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  if (ECDH_compute_key (Key, *KeySize, Point, EcKey, NULL) <= 0) {

> > > > > > +    goto fail;

> > > > > > +  }

> > > > > > +

> > > > > > +  RetVal = TRUE;

> > > > > > +

> > > > > > +fail:

> > > > > > +  BN_free (BnX);

> > > > > > +  BN_free (BnY);

> > > > > > +  EC_POINT_free (Point);

> > > > > > +  EC_KEY_free (PeerEcKey);

> > > > > > +  return RetVal;

> > > > > > +}

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c

> > b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c

> > > > > > new file mode 100644

> > > > > > index 0000000000..d9f1004f6c

> > > > > > --- /dev/null

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c

> > > > > > @@ -0,0 +1,496 @@

> > > > > > +/** @file

> > > > > > +  Elliptic Curve and ECDH API implementation based on OpenSSL

> > > > > > +

> > > > > > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

> > > > > > +  SPDX-License-Identifier: BSD-2-Clause-Patent

> > > > > > +

> > > > > > +**/

> > > > > > +

> > > > > > +#include <Library/BaseCryptLib.h>

> > > > > > +#include <Library/DebugLib.h>

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EcGroup object. This object represents an EC

> > curve and

> > > > > > +  and is used for calculation within this group. This object should be

> > freed

> > > > > > +  using EcGroupFree() function.

> > > > > > +

> > > > > > +  @param[in]  CryptoNid   Identifying number for the ECC curve

> > (Defined in

> > > > > > +                          BaseCryptLib.h).

> > > > > > +

> > > > > > +  @retval EcGroup object  On success.

> > > > > > +  @retval NULL            On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcGroupInit (

> > > > > > +  IN UINTN  CryptoNid

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC curve parameters. While elliptic curve equation is Y^2 mod

> > P = (X^3 + AX + B) Mod P.

> > > > > > +  This function will set the provided Big Number objects  to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[out] BnPrime    Group prime number.

> > > > > > +  @param[out] BnA        A coefficient.

> > > > > > +  @param[out] BnB        B coefficient..

> > > > > > +  @param[in]  BnCtx      BN context.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *BnPrime,

> > > > > > +  OUT VOID       *BnA,

> > > > > > +  OUT VOID       *BnB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC group order.

> > > > > > +  This function will set the provided Big Number object to the

> > corresponding

> > > > > > +  value. The caller needs to make sure that the "out" BigNumber

> > parameter

> > > > > > +  is properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[out] BnOrder   Group prime number.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetOrder (

> > > > > > +  IN VOID   *EcGroup,

> > > > > > +  OUT VOID  *BnOrder

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC group object using EcGroupInit().

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object to free.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcGroupFree (

> > > > > > +  IN VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EC Point object. This object represents an EC

> > point

> > > > > > +  within the given EC group (curve).

> > > > > > +

> > > > > > +  @param[in]  EC Group, properly initialized using EcGroupInit().

> > > > > > +

> > > > > > +  @retval EC Point object  On success.

> > > > > > +  @retval NULL             On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcPointInit (

> > > > > > +  IN CONST VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC Point object using EcPointInit().

> > > > > > +

> > > > > > +  @param[in]  EcPoint   EC Point to free.

> > > > > > +  @param[in]  Clear     TRUE iff the memory should be cleared.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcPointDeInit (

> > > > > > +  IN VOID     *EcPoint,

> > > > > > +  IN BOOLEAN  Clear

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC point affine (x,y) coordinates.

> > > > > > +  This function will set the provided Big Number objects to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[out] BnX        X coordinate.

> > > > > > +  @param[out] BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointGetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  OUT VOID       *BnX,

> > > > > > +  OUT VOID       *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point affine (x,y) coordinates.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN CONST VOID  *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  EC Point addition. EcPointResult = EcPointA + EcPointB.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPointA         EC Point.

> > > > > > +  @param[in]  EcPointB         EC Point.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointAdd (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Variable EC point multiplication. EcPointResult = EcPoint *

> > BnPScalar.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPoint          EC Point.

> > > > > > +  @param[in]  BnPScalar        P Scalar.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointMul (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN CONST VOID  *BnPScalar,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Calculate the inverse of the supplied EC point.

> > > > > > +

> > > > > > +  @param[in]     EcGroup   EC group object.

> > > > > > +  @param[in,out] EcPoint   EC point to invert.

> > > > > > +  @param[in]     BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointInvert (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN OUT VOID    *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is on EC curve.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On curve.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsOnCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is at infinity.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +

> > > > > > +  @retval TRUE          At infinity.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsAtInfinity (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if EC points are equal.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPointA  EC point A.

> > > > > > +  @param[in]  EcPointB  EC point B.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          A == B.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointEqual (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point compressed coordinates. Points can be described in

> > terms of

> > > > > > +  their compressed coordinates. For a point (x, y), for any given

> > value for x

> > > > > > +  such that the point is on the curve there will only ever be two

> > possible

> > > > > > +  values for y. Therefore, a point can be set using this function

> > where BnX is

> > > > > > +  the x coordinate and YBit is a value 0 or 1 to identify which of the

> > two

> > > > > > +  possible values for y should be used.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC Point.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  YBit       0 or 1 to identify which Y value is used.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetCompressedCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN UINT8       YBit,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Allocates and Initializes one Elliptic Curve Context for subsequent

> > use

> > > > > > +  with the NID.

> > > > > > +

> > > > > > +  @param[in]  Nid cipher NID

> > > > > > +  @return     Pointer to the Elliptic Curve Context that has been

> > initialized.

> > > > > > +              If the allocations fails, EcNewByNid() returns NULL.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcNewByNid (

> > > > > > +  IN UINTN  Nid

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Release the specified EC context.

> > > > > > +

> > > > > > +  @param[in]  EcContext  Pointer to the EC context to be released.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcFree (

> > > > > > +  IN  VOID  *EcContext

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Generates EC key and returns EC public key (X, Y), Please note,

> > this function uses

> > > > > > +  pseudo random number generator. The caller must make sure

> > RandomSeed()

> > > > > > +  function was properly called before.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid.

> > > > > > +  This function generates random secret, and computes the public

> > key (X, Y), which is

> > > > > > +  returned via parameter Public, PublicSize.

> > > > > > +  X is the first half of Public with size being PublicSize / 2,

> > > > > > +  Y is the second half of Public with size being PublicSize / 2.

> > > > > > +  EC context is updated accordingly.

> > > > > > +  If the Public buffer is too small to hold the public X, Y, FALSE is

> > returned and

> > > > > > +  PublicSize is set to the required buffer size to obtain the public X,

> > Y.

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PublicSize is NULL, then return FALSE.

> > > > > > +  If PublicSize is large enough but Public is NULL, then return FALSE.

> > > > > > +  @param[in, out]  EcContext      Pointer to the EC context.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC public X,Y generation succeeded.

> > > > > > +  @retval FALSE  EC public X,Y generation failed.

> > > > > > +  @retval FALSE  PublicKeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGenerateKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Gets the public key component from the established EC context.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid, and

> > successfully

> > > > > > +  generate key pair from EcGenerateKey().

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  @param[in, out]  EcContext      Pointer to EC context being set.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval  TRUE   EC key component was retrieved successfully.

> > > > > > +  @retval  FALSE  Invalid EC key component.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGetPubKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Computes exchanged common key.

> > > > > > +  Given peer's public key (X, Y), this function computes the

> > exchanged common key,

> > > > > > +  based on its own context including value of curve parameter and

> > random secret.

> > > > > > +  X is the first half of PeerPublic with size being PeerPublicSize / 2,

> > > > > > +  Y is the second half of PeerPublic with size being PeerPublicSize /

> > 2.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PeerPublic is NULL, then return FALSE.

> > > > > > +  If PeerPublicSize is 0, then return FALSE.

> > > > > > +  If Key is NULL, then return FALSE.

> > > > > > +  If KeySize is not large enough, then return FALSE.

> > > > > > +  For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-

> > byte is Y.

> > > > > > +  For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-

> > byte is Y.

> > > > > > +  For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-

> > byte is Y.

> > > > > > +  @param[in, out]  EcContext          Pointer to the EC context.

> > > > > > +  @param[in]       PeerPublic         Pointer to the peer's public X,Y.

> > > > > > +  @param[in]       PeerPublicSize     Size of peer's public X,Y in bytes.

> > > > > > +  @param[in]       CompressFlag       Flag of PeerPublic is

> > compressed or not.

> > > > > > +  @param[out]      Key                Pointer to the buffer to receive

> > generated key.

> > > > > > +  @param[in, out]  KeySize            On input, the size of Key buffer in

> > bytes.

> > > > > > +                                      On output, the size of data returned in Key

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC exchanged key generation succeeded.

> > > > > > +  @retval FALSE  EC exchanged key generation failed.

> > > > > > +  @retval FALSE  KeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcDhComputeKey (

> > > > > > +  IN OUT  VOID         *EcContext,

> > > > > > +  IN      CONST UINT8  *PeerPublic,

> > > > > > +  IN      UINTN        PeerPublicSize,

> > > > > > +  IN      CONST INT32  *CompressFlag,

> > > > > > +  OUT     UINT8        *Key,

> > > > > > +  IN OUT  UINTN        *KeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf

> > b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf

> > > > > > index ce6a789dfd..4bc3063485 100644

> > > > > > --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf

> > > > > > @@ -59,6 +59,7 @@

> > > > > >    Pk/CryptTsNull.c

> > > > > >    Pk/CryptRsaPss.c

> > > > > >    Pk/CryptRsaPssSignNull.c

> > > > > > +  Pk/CryptEcNull.c

> > > > > >    Pem/CryptPem.c

> > > > > >    Bn/CryptBnNull.c

> > > > > >

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf

> > > > > b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf

> > > > > > index 354f3d80aa..e1a57ef09f 100644

> > > > > > --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf

> > > > > > @@ -49,6 +49,7 @@

> > > > > >    Pk/CryptX509Null.c

> > > > > >    Pk/CryptAuthenticodeNull.c

> > > > > >    Pk/CryptTsNull.c

> > > > > > +  Pk/CryptEcNull.c

> > > > > >    Pem/CryptPemNull.c

> > > > > >    Rand/CryptRandNull.c

> > > > > >    Pk/CryptRsaPssNull.c

> > > > > > diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c

> > b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c

> > > > > > new file mode 100644

> > > > > > index 0000000000..d9f1004f6c

> > > > > > --- /dev/null

> > > > > > +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c

> > > > > > @@ -0,0 +1,496 @@

> > > > > > +/** @file

> > > > > > +  Elliptic Curve and ECDH API implementation based on OpenSSL

> > > > > > +

> > > > > > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

> > > > > > +  SPDX-License-Identifier: BSD-2-Clause-Patent

> > > > > > +

> > > > > > +**/

> > > > > > +

> > > > > > +#include <Library/BaseCryptLib.h>

> > > > > > +#include <Library/DebugLib.h>

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EcGroup object. This object represents an EC

> > curve and

> > > > > > +  and is used for calculation within this group. This object should be

> > freed

> > > > > > +  using EcGroupFree() function.

> > > > > > +

> > > > > > +  @param[in]  CryptoNid   Identifying number for the ECC curve

> > (Defined in

> > > > > > +                          BaseCryptLib.h).

> > > > > > +

> > > > > > +  @retval EcGroup object  On success.

> > > > > > +  @retval NULL            On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcGroupInit (

> > > > > > +  IN UINTN  CryptoNid

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC curve parameters. While elliptic curve equation is Y^2 mod

> > P = (X^3 + AX + B) Mod P.

> > > > > > +  This function will set the provided Big Number objects  to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[out] BnPrime    Group prime number.

> > > > > > +  @param[out] BnA        A coefficient.

> > > > > > +  @param[out] BnB        B coefficient..

> > > > > > +  @param[in]  BnCtx      BN context.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *BnPrime,

> > > > > > +  OUT VOID       *BnA,

> > > > > > +  OUT VOID       *BnB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC group order.

> > > > > > +  This function will set the provided Big Number object to the

> > corresponding

> > > > > > +  value. The caller needs to make sure that the "out" BigNumber

> > parameter

> > > > > > +  is properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[out] BnOrder   Group prime number.

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGroupGetOrder (

> > > > > > +  IN VOID   *EcGroup,

> > > > > > +  OUT VOID  *BnOrder

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC group object using EcGroupInit().

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object to free.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcGroupFree (

> > > > > > +  IN VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Initialize new opaque EC Point object. This object represents an EC

> > point

> > > > > > +  within the given EC group (curve).

> > > > > > +

> > > > > > +  @param[in]  EC Group, properly initialized using EcGroupInit().

> > > > > > +

> > > > > > +  @retval EC Point object  On success.

> > > > > > +  @retval NULL             On failure.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcPointInit (

> > > > > > +  IN CONST VOID  *EcGroup

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Free previously allocated EC Point object using EcPointInit().

> > > > > > +

> > > > > > +  @param[in]  EcPoint   EC Point to free.

> > > > > > +  @param[in]  Clear     TRUE iff the memory should be cleared.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcPointDeInit (

> > > > > > +  IN VOID     *EcPoint,

> > > > > > +  IN BOOLEAN  Clear

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Get EC point affine (x,y) coordinates.

> > > > > > +  This function will set the provided Big Number objects to the

> > corresponding

> > > > > > +  values. The caller needs to make sure all the "out" BigNumber

> > parameters

> > > > > > +  are properly initialized.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[out] BnX        X coordinate.

> > > > > > +  @param[out] BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointGetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  OUT VOID       *BnX,

> > > > > > +  OUT VOID       *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point affine (x,y) coordinates.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC point object.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  BnY        Y coordinate.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetAffineCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN CONST VOID  *BnY,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  EC Point addition. EcPointResult = EcPointA + EcPointB.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPointA         EC Point.

> > > > > > +  @param[in]  EcPointB         EC Point.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointAdd (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Variable EC point multiplication. EcPointResult = EcPoint *

> > BnPScalar.

> > > > > > +

> > > > > > +  @param[in]  EcGroup          EC group object.

> > > > > > +  @param[out] EcPointResult    EC point to hold the result. The

> > point should

> > > > > > +                               be properly initialized.

> > > > > > +  @param[in]  EcPoint          EC Point.

> > > > > > +  @param[in]  BnPScalar        P Scalar.

> > > > > > +  @param[in]  BnCtx            BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointMul (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  OUT VOID       *EcPointResult,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN CONST VOID  *BnPScalar,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Calculate the inverse of the supplied EC point.

> > > > > > +

> > > > > > +  @param[in]     EcGroup   EC group object.

> > > > > > +  @param[in,out] EcPoint   EC point to invert.

> > > > > > +  @param[in]     BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointInvert (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN OUT VOID    *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is on EC curve.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On curve.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsOnCurve (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if the supplied point is at infinity.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPoint   EC point to check.

> > > > > > +

> > > > > > +  @retval TRUE          At infinity.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointIsAtInfinity (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPoint

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Check if EC points are equal.

> > > > > > +

> > > > > > +  @param[in]  EcGroup   EC group object.

> > > > > > +  @param[in]  EcPointA  EC point A.

> > > > > > +  @param[in]  EcPointB  EC point B.

> > > > > > +  @param[in]  BnCtx     BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          A == B.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointEqual (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN CONST VOID  *EcPointA,

> > > > > > +  IN CONST VOID  *EcPointB,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Set EC point compressed coordinates. Points can be described in

> > terms of

> > > > > > +  their compressed coordinates. For a point (x, y), for any given

> > value for x

> > > > > > +  such that the point is on the curve there will only ever be two

> > possible

> > > > > > +  values for y. Therefore, a point can be set using this function

> > where BnX is

> > > > > > +  the x coordinate and YBit is a value 0 or 1 to identify which of the

> > two

> > > > > > +  possible values for y should be used.

> > > > > > +

> > > > > > +  @param[in]  EcGroup    EC group object.

> > > > > > +  @param[in]  EcPoint    EC Point.

> > > > > > +  @param[in]  BnX        X coordinate.

> > > > > > +  @param[in]  YBit       0 or 1 to identify which Y value is used.

> > > > > > +  @param[in]  BnCtx      BN context, created with

> > BigNumNewContext().

> > > > > > +

> > > > > > +  @retval TRUE          On success.

> > > > > > +  @retval FALSE         Otherwise.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcPointSetCompressedCoordinates (

> > > > > > +  IN CONST VOID  *EcGroup,

> > > > > > +  IN VOID        *EcPoint,

> > > > > > +  IN CONST VOID  *BnX,

> > > > > > +  IN UINT8       YBit,

> > > > > > +  IN VOID        *BnCtx

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Allocates and Initializes one Elliptic Curve Context for subsequent

> > use

> > > > > > +  with the NID.

> > > > > > +

> > > > > > +  @param[in]  Nid cipher NID

> > > > > > +  @return     Pointer to the Elliptic Curve Context that has been

> > initialized.

> > > > > > +              If the allocations fails, EcNewByNid() returns NULL.

> > > > > > +**/

> > > > > > +VOID *

> > > > > > +EFIAPI

> > > > > > +EcNewByNid (

> > > > > > +  IN UINTN  Nid

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return NULL;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Release the specified EC context.

> > > > > > +

> > > > > > +  @param[in]  EcContext  Pointer to the EC context to be released.

> > > > > > +**/

> > > > > > +VOID

> > > > > > +EFIAPI

> > > > > > +EcFree (

> > > > > > +  IN  VOID  *EcContext

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Generates EC key and returns EC public key (X, Y), Please note,

> > this function uses

> > > > > > +  pseudo random number generator. The caller must make sure

> > RandomSeed()

> > > > > > +  function was properly called before.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid.

> > > > > > +  This function generates random secret, and computes the public

> > key (X, Y), which is

> > > > > > +  returned via parameter Public, PublicSize.

> > > > > > +  X is the first half of Public with size being PublicSize / 2,

> > > > > > +  Y is the second half of Public with size being PublicSize / 2.

> > > > > > +  EC context is updated accordingly.

> > > > > > +  If the Public buffer is too small to hold the public X, Y, FALSE is

> > returned and

> > > > > > +  PublicSize is set to the required buffer size to obtain the public X,

> > Y.

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PublicSize is NULL, then return FALSE.

> > > > > > +  If PublicSize is large enough but Public is NULL, then return FALSE.

> > > > > > +  @param[in, out]  EcContext      Pointer to the EC context.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC public X,Y generation succeeded.

> > > > > > +  @retval FALSE  EC public X,Y generation failed.

> > > > > > +  @retval FALSE  PublicKeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGenerateKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Gets the public key component from the established EC context.

> > > > > > +  The Ec context should be correctly initialized by EcNewByNid, and

> > successfully

> > > > > > +  generate key pair from EcGenerateKey().

> > > > > > +  For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte

> > is Y.

> > > > > > +  For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte

> > is Y.

> > > > > > +  For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte

> > is Y.

> > > > > > +  @param[in, out]  EcContext      Pointer to EC context being set.

> > > > > > +  @param[out]      PublicKey      Pointer to t buffer to receive

> > generated public X,Y.

> > > > > > +  @param[in, out]  PublicKeySize  On input, the size of Public buffer

> > in bytes.

> > > > > > +                                  On output, the size of data returned in Public

> > buffer in bytes.

> > > > > > +  @retval  TRUE   EC key component was retrieved successfully.

> > > > > > +  @retval  FALSE  Invalid EC key component.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcGetPubKey (

> > > > > > +  IN OUT  VOID   *EcContext,

> > > > > > +  OUT     UINT8  *PublicKey,

> > > > > > +  IN OUT  UINTN  *PublicKeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > +

> > > > > > +/**

> > > > > > +  Computes exchanged common key.

> > > > > > +  Given peer's public key (X, Y), this function computes the

> > exchanged common key,

> > > > > > +  based on its own context including value of curve parameter and

> > random secret.

> > > > > > +  X is the first half of PeerPublic with size being PeerPublicSize / 2,

> > > > > > +  Y is the second half of PeerPublic with size being PeerPublicSize /

> > 2.

> > > > > > +  If EcContext is NULL, then return FALSE.

> > > > > > +  If PeerPublic is NULL, then return FALSE.

> > > > > > +  If PeerPublicSize is 0, then return FALSE.

> > > > > > +  If Key is NULL, then return FALSE.

> > > > > > +  If KeySize is not large enough, then return FALSE.

> > > > > > +  For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-

> > byte is Y.

> > > > > > +  For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-

> > byte is Y.

> > > > > > +  For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-

> > byte is Y.

> > > > > > +  @param[in, out]  EcContext          Pointer to the EC context.

> > > > > > +  @param[in]       PeerPublic         Pointer to the peer's public X,Y.

> > > > > > +  @param[in]       PeerPublicSize     Size of peer's public X,Y in bytes.

> > > > > > +  @param[in]       CompressFlag       Flag of PeerPublic is

> > compressed or not.

> > > > > > +  @param[out]      Key                Pointer to the buffer to receive

> > generated key.

> > > > > > +  @param[in, out]  KeySize            On input, the size of Key buffer in

> > bytes.

> > > > > > +                                      On output, the size of data returned in Key

> > buffer in bytes.

> > > > > > +  @retval TRUE   EC exchanged key generation succeeded.

> > > > > > +  @retval FALSE  EC exchanged key generation failed.

> > > > > > +  @retval FALSE  KeySize is not large enough.

> > > > > > +**/

> > > > > > +BOOLEAN

> > > > > > +EFIAPI

> > > > > > +EcDhComputeKey (

> > > > > > +  IN OUT  VOID         *EcContext,

> > > > > > +  IN      CONST UINT8  *PeerPublic,

> > > > > > +  IN      UINTN        PeerPublicSize,

> > > > > > +  IN      CONST INT32  *CompressFlag,

> > > > > > +  OUT     UINT8        *Key,

> > > > > > +  IN OUT  UINTN        *KeySize

> > > > > > +  )

> > > > > > +{

> > > > > > +  ASSERT (FALSE);

> > > > > > +  return FALSE;

> > > > > > +}

> > > > > > --

> > > > > > 2.31.1.windows.1

> > > > > >

> > > > > >

> > > > > >

> > > > > >

> > > > > >

 

Join devel@edk2.groups.io to automatically receive all group messages.