From: "yi1 li" <yi1.li@intel.com>
To: devel@edk2.groups.io
Cc: Yi Li <yi1.li@intel.com>, Jiewen Yao <jiewen.yao@intel.com>,
Jian J Wang <jian.j.wang@intel.com>,
Xiaoyu Lu <xiaoyux.lu@intel.com>,
Guomin Jiang <guomin.jiang@intel.com>
Subject: [PATCH 4/7] CryptoPkg: Add EC APIs to DXE and protocol
Date: Wed, 7 Sep 2022 16:29:21 +0800 [thread overview]
Message-ID: <773ff43142ec6cfe0ab8def41c123b1aa7bd1f17.1662539080.git.yi1.li@intel.com> (raw)
In-Reply-To: <cover.1662539079.git.yi1.li@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828
The implementation provides CryptEc library functions
for EFI Driveer and EFI BaseCrypt Protocol.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Yi Li <yi1.li@intel.com>
---
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Driver/Crypto.c | 496 ++++++++++++++++++
.../Pcd/PcdCryptoServiceFamilyEnable.h | 25 +
.../BaseCryptLibOnProtocolPpi/CryptLib.c | 469 +++++++++++++++++
CryptoPkg/Private/Protocol/Crypto.h | 431 +++++++++++++++
5 files changed, 1422 insertions(+)
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index a766851728..4f6cece6ee 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -169,6 +169,7 @@
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Bn.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
+ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Ec.Family | 0
!endif
!if $(CRYPTO_SERVICES) == MIN_PEI
diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c
index 07150ad2f2..f7b9287218 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -5074,6 +5074,481 @@ CryptoServiceBigNumAddMod (
return CALL_BASECRYPTLIB (Bn.Services.AddMod, BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE);
}
+// =====================================================================================
+// 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
+CryptoServiceEcGroupInit (
+ IN UINTN CryptoNid
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.GroupInit, EcGroupInit, (CryptoNid), 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
+CryptoServiceEcGroupGetCurve (
+ IN CONST VOID *EcGroup,
+ OUT VOID *BnPrime,
+ OUT VOID *BnA,
+ OUT VOID *BnB,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.GroupGetCurve, EcGroupGetCurve, (EcGroup, BnPrime, BnA, BnB, BnCtx), 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
+CryptoServiceEcGroupGetOrder (
+ IN VOID *EcGroup,
+ OUT VOID *BnOrder
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.GroupGetOrder, EcGroupGetOrder, (EcGroup, BnOrder), FALSE);
+}
+
+/**
+ Free previously allocated EC group object using EcGroupInit().
+
+ @param[in] EcGroup EC group object to free.
+**/
+VOID
+EFIAPI
+CryptoServiceEcGroupFree (
+ IN VOID *EcGroup
+ )
+{
+ CALL_VOID_BASECRYPTLIB (Ec.Services.GroupFree, EcGroupFree, (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
+CryptoServiceEcPointInit (
+ IN CONST VOID *EcGroup
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointInit, EcPointInit, (EcGroup), 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
+CryptoServiceEcPointDeInit (
+ IN VOID *EcPoint,
+ IN BOOLEAN Clear
+ )
+{
+ CALL_VOID_BASECRYPTLIB (Ec.Services.PointDeInit, EcPointDeInit, (EcPoint, 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
+CryptoServiceEcPointGetAffineCoordinates (
+ IN CONST VOID *EcGroup,
+ IN CONST VOID *EcPoint,
+ OUT VOID *BnX,
+ OUT VOID *BnY,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointGetAffineCoordinates, EcPointGetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), 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
+CryptoServiceEcPointSetAffineCoordinates (
+ IN CONST VOID *EcGroup,
+ IN VOID *EcPoint,
+ IN CONST VOID *BnX,
+ IN CONST VOID *BnY,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointSetAffineCoordinates, EcPointSetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), 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
+CryptoServiceEcPointAdd (
+ IN CONST VOID *EcGroup,
+ OUT VOID *EcPointResult,
+ IN CONST VOID *EcPointA,
+ IN CONST VOID *EcPointB,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointAdd, EcPointAdd, (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx), 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
+CryptoServiceEcPointMul (
+ IN CONST VOID *EcGroup,
+ OUT VOID *EcPointResult,
+ IN CONST VOID *EcPoint,
+ IN CONST VOID *BnPScalar,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointMul, EcPointMul, (EcGroup, EcPointResult, EcPoint, BnPScalar, BnCtx), 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
+CryptoServiceEcPointInvert (
+ IN CONST VOID *EcGroup,
+ IN OUT VOID *EcPoint,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointInvert, EcPointInvert, (EcGroup, EcPoint, BnCtx), 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
+CryptoServiceEcPointIsOnCurve (
+ IN CONST VOID *EcGroup,
+ IN CONST VOID *EcPoint,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointIsOnCurve, EcPointIsOnCurve, (EcGroup, EcPoint, BnCtx), 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
+CryptoServiceEcPointIsAtInfinity (
+ IN CONST VOID *EcGroup,
+ IN CONST VOID *EcPoint
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointIsAtInfinity, EcPointIsAtInfinity, (EcGroup, EcPoint), 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
+CryptoServiceEcPointEqual (
+ IN CONST VOID *EcGroup,
+ IN CONST VOID *EcPointA,
+ IN CONST VOID *EcPointB,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointEqual, EcPointEqual, (EcGroup, EcPointA, EcPointB, BnCtx), 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
+CryptoServiceEcPointSetCompressedCoordinates (
+ IN CONST VOID *EcGroup,
+ IN VOID *EcPoint,
+ IN CONST VOID *BnX,
+ IN UINT8 YBit,
+ IN VOID *BnCtx
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.PointSetCompressedCoordinates, EcPointSetCompressedCoordinates, (EcGroup, EcPoint, BnX, YBit, BnCtx), FALSE);
+}
+
+// =====================================================================================
+// 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
+CryptoServiceEcNewByNid (
+ IN UINTN Nid
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.NewByNid, EcNewByNid, (Nid), NULL);
+}
+
+/**
+ Release the specified EC context.
+
+ @param[in] EcContext Pointer to the EC context to be released.
+**/
+VOID
+EFIAPI
+CryptoServiceEcFree (
+ IN VOID *EcContext
+ )
+{
+ CALL_VOID_BASECRYPTLIB (Ec.Services.Free, EcFree, (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
+CryptoServiceEcGenerateKey (
+ IN OUT VOID *EcContext,
+ OUT UINT8 *PublicKey,
+ IN OUT UINTN *PublicKeySize
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.GenerateKey, EcGenerateKey, (EcContext, PublicKey, PublicKeySize), 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
+CryptoServiceEcGetPubKey (
+ IN OUT VOID *EcContext,
+ OUT UINT8 *PublicKey,
+ IN OUT UINTN *PublicKeySize
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.GetPubKey, EcGetPubKey, (EcContext, PublicKey, PublicKeySize), 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
+CryptoServiceEcDhComputeKey (
+ IN OUT VOID *EcContext,
+ IN CONST UINT8 *PeerPublic,
+ IN UINTN PeerPublicSize,
+ IN CONST INT32 *CompressFlag,
+ OUT UINT8 *Key,
+ IN OUT UINTN *KeySize
+ )
+{
+ return CALL_BASECRYPTLIB (Ec.Services.DhComputeKey, EcDhComputeKey, (EcContext, PeerPublic, PeerPublicSize, CompressFlag ,Key, KeySize), FALSE);
+}
+
const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
/// Version
CryptoServiceGetCryptoVersion,
@@ -5306,4 +5781,25 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
CryptoServiceBigNumContextFree,
CryptoServiceBigNumSetUint,
CryptoServiceBigNumAddMod,
+ /// EC
+ CryptoServiceEcGroupInit,
+ CryptoServiceEcGroupGetCurve,
+ CryptoServiceEcGroupGetOrder,
+ CryptoServiceEcGroupFree,
+ CryptoServiceEcPointInit,
+ CryptoServiceEcPointDeInit,
+ CryptoServiceEcPointGetAffineCoordinates,
+ CryptoServiceEcPointSetAffineCoordinates,
+ CryptoServiceEcPointAdd,
+ CryptoServiceEcPointMul,
+ CryptoServiceEcPointInvert,
+ CryptoServiceEcPointIsOnCurve,
+ CryptoServiceEcPointIsAtInfinity,
+ CryptoServiceEcPointEqual,
+ CryptoServiceEcPointSetCompressedCoordinates,
+ CryptoServiceEcNewByNid,
+ CryptoServiceEcFree,
+ CryptoServiceEcGenerateKey,
+ CryptoServiceEcGetPubKey,
+ CryptoServiceEcDhComputeKey,
};
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 1b3c9d8f52..65ea7807dc 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -331,6 +331,31 @@ typedef struct {
} Services;
UINT32 Family;
} Bn;
+ union {
+ struct {
+ UINT8 GroupInit : 1;
+ UINT8 GroupGetCurve : 1;
+ UINT8 GroupGetOrder : 1;
+ UINT8 GroupFree : 1;
+ UINT8 PointInit : 1;
+ UINT8 PointDeInit : 1;
+ UINT8 PointGetAffineCoordinates : 1;
+ UINT8 PointSetAffineCoordinates : 1;
+ UINT8 PointAdd : 1;
+ UINT8 PointMul : 1;
+ UINT8 PointInvert : 1;
+ UINT8 PointIsOnCurve : 1;
+ UINT8 PointIsAtInfinity : 1;
+ UINT8 PointEqual : 1;
+ UINT8 PointSetCompressedCoordinates : 1;
+ UINT8 NewByNid : 1;
+ UINT8 Free : 1;
+ UINT8 GenerateKey : 1;
+ UINT8 GetPubKey : 1;
+ UINT8 DhComputeKey : 1;
+ } Services;
+ UINT32 Family;
+ } Ec;
} PCD_CRYPTO_SERVICE_FAMILY_ENABLE;
#endif
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index c5d71b5269..3746c823d9 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -4104,3 +4104,472 @@ BigNumAddMod (
{
CALL_CRYPTO_SERVICE (BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE);
}
+
+/**
+ 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcGroupInit, (CryptoNid), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcGroupGetCurve, (EcGroup, BnPrime, BnA, BnB, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcGroupGetOrder, (EcGroup, BnOrder), FALSE);
+}
+
+/**
+ Free previously allocated EC group object using EcGroupInit().
+
+ @param[in] EcGroup EC group object to free.
+**/
+VOID
+EFIAPI
+EcGroupFree (
+ IN VOID *EcGroup
+ )
+{
+ CALL_VOID_CRYPTO_SERVICE (EcGroupFree, (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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointInit, (EcGroup), 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
+ )
+{
+ CALL_VOID_CRYPTO_SERVICE (EcPointDeInit, (EcPoint, 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointGetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointSetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointAdd, (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointMul, (EcGroup, EcPointResult, EcPoint, BnPScalar, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointInvert, (EcGroup, EcPoint, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointIsOnCurve, (EcGroup, EcPoint, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointIsAtInfinity, (EcGroup, EcPoint), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointEqual, (EcGroup, EcPointA, EcPointB, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcPointSetCompressedCoordinates, (EcGroup, EcPoint, BnX, YBit, BnCtx), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcNewByNid, (Nid), NULL);
+}
+
+/**
+ Release the specified EC context.
+
+ @param[in] EcContext Pointer to the EC context to be released.
+**/
+VOID
+EFIAPI
+EcFree (
+ IN VOID *EcContext
+ )
+{
+ CALL_VOID_CRYPTO_SERVICE (EcFree, (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 the 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcGenerateKey, (EcContext, PublicKey, PublicKeySize), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcGetPubKey, (EcContext, PublicKey, PublicKeySize), 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
+ )
+{
+ CALL_CRYPTO_SERVICE (EcDhComputeKey, (EcContext, PeerPublic, PeerPublicSize, CompressFlag, Key, KeySize), FALSE);
+}
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index ec3cba8e93..84d9fbba32 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3887,6 +3887,416 @@ BOOLEAN
OUT VOID *BnRes
);
+/**
+ 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
+**/
+typedef
+VOID *
+(EFIAPI *EDKII_CRYPTO_EC_GROUP_INIT)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_GROUP_GET_CURVE)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_GROUP_GET_ORDER)(
+ IN VOID *EcGroup,
+ OUT VOID *BnOrder
+ );
+
+/**
+ Free previously allocated EC group object using EcGroupInit()
+
+ @param[in] EcGroup EC group object to free
+**/
+typedef
+VOID
+(EFIAPI *EDKII_CRYPTO_EC_GROUP_FREE)(
+ 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
+**/
+typedef
+VOID *
+(EFIAPI *EDKII_CRYPTO_EC_POINT_INIT)(
+ 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
+**/
+typedef
+VOID
+(EFIAPI *EDKII_CRYPTO_EC_POINT_DE_INIT)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_GET_AFFINE_COORDINATES)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_SET_AFFINE_COORDINATES)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_ADD)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_MUL)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_INVERT)(
+ 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
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_IS_ON_CURVE)(
+ 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
+ @param[in] BnCtx BN context, created with BigNumNewContext()
+
+ @retval TRUE At infinity
+ @retval FALSE Otherwise
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_IS_AT_INFINITY)(
+ 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
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_EQUAL)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_POINT_SET_COMPRESSED_COORDINATES)(
+ IN CONST VOID *EcGroup,
+ IN VOID *EcPoint,
+ IN CONST VOID *BnX,
+ IN UINT8 YBit,
+ IN VOID *BnCtx
+ );
+
+/**
+ 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.
+**/
+typedef
+VOID *
+(EFIAPI *EDKII_CRYPTO_EC_NEW_BY_NID)(
+ IN UINTN Nid
+ );
+
+/**
+ Release the specified EC context.
+
+ @param[in] EcContext Pointer to the EC context to be released.
+**/
+typedef
+VOID
+(EFIAPI *EDKII_CRYPTO_EC_FREE)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_GENERATE_KEY)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_GET_PUB_KEY)(
+ 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.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_EC_DH_COMPUTE_KEY)(
+ IN OUT VOID *EcContext,
+ IN CONST UINT8 *PeerPublic,
+ IN UINTN PeerPublicSize,
+ IN CONST INT32 *CompressFlag,
+ OUT UINT8 *Key,
+ IN OUT UINTN *KeySize
+ );
+
///
/// EDK II Crypto Protocol
///
@@ -4102,6 +4512,27 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_BIGNUM_CONTEXT_FREE BigNumContextFree;
EDKII_CRYPTO_BIGNUM_SET_UINT BigNumSetUint;
EDKII_CRYPTO_BIGNUM_ADD_MOD BigNumAddMod;
+ /// EC
+ EDKII_CRYPTO_EC_GROUP_INIT EcGroupInit;
+ EDKII_CRYPTO_EC_GROUP_GET_CURVE EcGroupGetCurve;
+ EDKII_CRYPTO_EC_GROUP_GET_ORDER EcGroupGetOrder;
+ EDKII_CRYPTO_EC_GROUP_FREE EcGroupFree;
+ EDKII_CRYPTO_EC_POINT_INIT EcPointInit;
+ EDKII_CRYPTO_EC_POINT_DE_INIT EcPointDeInit;
+ EDKII_CRYPTO_EC_POINT_GET_AFFINE_COORDINATES EcPointGetAffineCoordinates;
+ EDKII_CRYPTO_EC_POINT_SET_AFFINE_COORDINATES EcPointSetAffineCoordinates;
+ EDKII_CRYPTO_EC_POINT_ADD EcPointAdd;
+ EDKII_CRYPTO_EC_POINT_MUL EcPointMul;
+ EDKII_CRYPTO_EC_POINT_INVERT EcPointInvert;
+ EDKII_CRYPTO_EC_POINT_IS_ON_CURVE EcPointIsOnCurve;
+ EDKII_CRYPTO_EC_POINT_IS_AT_INFINITY EcPointIsAtInfinity;
+ EDKII_CRYPTO_EC_POINT_EQUAL EcPointEqual;
+ EDKII_CRYPTO_EC_POINT_SET_COMPRESSED_COORDINATES EcPointSetCompressedCoordinates;
+ EDKII_CRYPTO_EC_NEW_BY_NID EcNewByNid;
+ EDKII_CRYPTO_EC_FREE EcFree;
+ EDKII_CRYPTO_EC_GENERATE_KEY EcGenerateKey;
+ EDKII_CRYPTO_EC_GET_PUB_KEY EcGetPubKey;
+ EDKII_CRYPTO_EC_DH_COMPUTE_KEY EcDhComputeKey;
};
extern GUID gEdkiiCryptoProtocolGuid;
--
2.31.1.windows.1
next prev parent reply other threads:[~2022-09-07 8:29 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-07 8:29 [PATCH 0/7] CryptoPkg: Add BigNum and EC support to BaseCryptLib yi1 li
2022-09-07 8:29 ` [PATCH 1/7] CryptoPkg: Add BigNum support yi1 li
2022-09-07 8:29 ` [PATCH 2/7] CryptoPkg: Add BigNum API to DXE and protocol yi1 li
2022-09-07 8:29 ` [PATCH 3/7] CryptoPkg: Add EC support yi1 li
2022-09-07 8:29 ` yi1 li [this message]
2022-09-07 8:29 ` [PATCH 5/7] CryptoPkg/Test: Add unit test for CryptoBn yi1 li
2022-09-07 8:29 ` [PATCH 6/7] CryptoPkg/Test: Add unit test for CryptoEc yi1 li
2022-09-07 8:29 ` [PATCH 7/7] CryptoPkg: Run uncrustify tools on EC and BN change yi1 li
2022-09-20 16:01 ` [PATCH 0/7] CryptoPkg: Add BigNum and EC support to BaseCryptLib Yao, Jiewen
2022-09-21 4:56 ` yi1 li
2022-09-21 10:46 ` Yao, Jiewen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=773ff43142ec6cfe0ab8def41c123b1aa7bd1f17.1662539080.git.yi1.li@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox