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 3/7] CryptoPkg: Add EC support
Date: Wed, 7 Sep 2022 16:29:20 +0800 [thread overview]
Message-ID: <48a98f3b77d5740f13313a407fb632d06a469503.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
This patch is used to add CryptEc library, which is wrapped
over OpenSSL.
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/Include/Library/BaseCryptLib.h | 424 ++++++++++
.../Library/BaseCryptLib/BaseCryptLib.inf | 2 +
.../Library/BaseCryptLib/PeiCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c | 755 ++++++++++++++++++
.../Library/BaseCryptLib/Pk/CryptEcNull.c | 496 ++++++++++++
.../Library/BaseCryptLib/SmmCryptLib.inf | 1 +
.../BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
.../Library/BaseCryptLibNull/Pk/CryptEcNull.c | 496 ++++++++++++
8 files changed, 2176 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..ea3ed5270f 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
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..e9b0391a56
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c
@@ -0,0 +1,755 @@
+/** @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
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 ` yi1 li [this message]
2022-09-07 8:29 ` [PATCH 4/7] CryptoPkg: Add EC APIs " yi1 li
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=48a98f3b77d5740f13313a407fb632d06a469503.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