\r
#include <Uefi/UefiBaseType.h>\r
\r
+#define CRYPTO_NID_NULL 0x0000\r
+\r
+// Key Exchange\r
+#define CRYPTO_NID_SECP256R1 0x0204\r
+#define CRYPTO_NID_SECP384R1 0x0205\r
+#define CRYPTO_NID_SECP521R1 0x0206\r
+\r
///\r
/// MD5 digest size in bytes\r
///\r
OUT VOID *BnRes\r
);\r
\r
+// =====================================================================================\r
+// Basic Elliptic Curve Primitives\r
+// =====================================================================================\r
+\r
+/**\r
+ Initialize new opaque EcGroup object. This object represents an EC curve and\r
+ and is used for calculation within this group. This object should be freed\r
+ using EcGroupFree() function.\r
+\r
+ @param[in] CryptoNid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+\r
+ @retval EcGroup object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcGroupInit (\r
+ IN UINTN CryptoNid\r
+ );\r
+\r
+/**\r
+ Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnPrime Group prime number.\r
+ @param[out] BnA A coefficient.\r
+ @param[out] BnB B coefficient.\r
+ @param[in] BnCtx BN context.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetCurve (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *BnPrime,\r
+ OUT VOID *BnA,\r
+ OUT VOID *BnB,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Get EC group order.\r
+ This function will set the provided Big Number object to the corresponding\r
+ value. The caller needs to make sure that the "out" BigNumber parameter\r
+ is properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnOrder Group prime number.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetOrder (\r
+ IN VOID *EcGroup,\r
+ OUT VOID *BnOrder\r
+ );\r
+\r
+/**\r
+ Free previously allocated EC group object using EcGroupInit().\r
+\r
+ @param[in] EcGroup EC group object to free.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcGroupFree (\r
+ IN VOID *EcGroup\r
+ );\r
+\r
+/**\r
+ Initialize new opaque EC Point object. This object represents an EC point\r
+ within the given EC group (curve).\r
+\r
+ @param[in] EC Group, properly initialized using EcGroupInit().\r
+\r
+ @retval EC Point object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcPointInit (\r
+ IN CONST VOID *EcGroup\r
+ );\r
+\r
+/**\r
+ Free previously allocated EC Point object using EcPointInit().\r
+\r
+ @param[in] EcPoint EC Point to free.\r
+ @param[in] Clear TRUE iff the memory should be cleared.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcPointDeInit (\r
+ IN VOID *EcPoint,\r
+ IN BOOLEAN Clear\r
+ );\r
+\r
+/**\r
+ Get EC point affine (x,y) coordinates.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[out] BnX X coordinate.\r
+ @param[out] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointGetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ OUT VOID *BnX,\r
+ OUT VOID *BnY,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Set EC point affine (x,y) coordinates.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN CONST VOID *BnY,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ EC Point addition. EcPointResult = EcPointA + EcPointB.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPointA EC Point.\r
+ @param[in] EcPointB EC Point.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointAdd (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnPScalar P Scalar.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointMul (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPoint,\r
+ IN CONST VOID *BnPScalar,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Calculate the inverse of the supplied EC point.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in,out] EcPoint EC point to invert.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointInvert (\r
+ IN CONST VOID *EcGroup,\r
+ IN OUT VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Check if the supplied point is on EC curve.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On curve.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsOnCurve (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Check if the supplied point is at infinity.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+\r
+ @retval TRUE At infinity.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsAtInfinity (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint\r
+ );\r
+\r
+/**\r
+ Check if EC points are equal.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPointA EC point A.\r
+ @param[in] EcPointB EC point B.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE A == B.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointEqual (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+/**\r
+ Set EC point compressed coordinates. Points can be described in terms of\r
+ their compressed coordinates. For a point (x, y), for any given value for x\r
+ such that the point is on the curve there will only ever be two possible\r
+ values for y. Therefore, a point can be set using this function where BnX is\r
+ the x coordinate and YBit is a value 0 or 1 to identify which of the two\r
+ possible values for y should be used.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] YBit 0 or 1 to identify which Y value is used.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetCompressedCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN UINT8 YBit,\r
+ IN VOID *BnCtx\r
+ );\r
+\r
+// =====================================================================================\r
+// Elliptic Curve Diffie Hellman Primitives\r
+// =====================================================================================\r
+\r
+/**\r
+ Allocates and Initializes one Elliptic Curve Context for subsequent use\r
+ with the NID.\r
+\r
+ @param[in] Nid cipher NID\r
+ @return Pointer to the Elliptic Curve Context that has been initialized.\r
+ If the allocations fails, EcNewByNid() returns NULL.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcNewByNid (\r
+ IN UINTN Nid\r
+ );\r
+\r
+/**\r
+ Release the specified EC context.\r
+\r
+ @param[in] EcContext Pointer to the EC context to be released.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcFree (\r
+ IN VOID *EcContext\r
+ );\r
+\r
+/**\r
+ Generates EC key and returns EC public key (X, Y), Please note, this function uses\r
+ pseudo random number generator. The caller must make sure RandomSeed()\r
+ function was properly called before.\r
+ The Ec context should be correctly initialized by EcNewByNid.\r
+ This function generates random secret, and computes the public key (X, Y), which is\r
+ returned via parameter Public, PublicSize.\r
+ X is the first half of Public with size being PublicSize / 2,\r
+ Y is the second half of Public with size being PublicSize / 2.\r
+ EC context is updated accordingly.\r
+ If the Public buffer is too small to hold the public X, Y, FALSE is returned and\r
+ PublicSize is set to the required buffer size to obtain the public X, Y.\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PublicSize is NULL, then return FALSE.\r
+ If PublicSize is large enough but Public is NULL, then return FALSE.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC public X,Y generation succeeded.\r
+ @retval FALSE EC public X,Y generation failed.\r
+ @retval FALSE PublicKeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGenerateKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ );\r
+\r
+/**\r
+ Gets the public key component from the established EC context.\r
+ The Ec context should be correctly initialized by EcNewByNid, and successfully\r
+ generate key pair from EcGenerateKey().\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to EC context being set.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC key component was retrieved successfully.\r
+ @retval FALSE Invalid EC key component.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGetPubKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ );\r
+\r
+/**\r
+ Computes exchanged common key.\r
+ Given peer's public key (X, Y), this function computes the exchanged common key,\r
+ based on its own context including value of curve parameter and random secret.\r
+ X is the first half of PeerPublic with size being PeerPublicSize / 2,\r
+ Y is the second half of PeerPublic with size being PeerPublicSize / 2.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PeerPublic is NULL, then return FALSE.\r
+ If PeerPublicSize is 0, then return FALSE.\r
+ If Key is NULL, then return FALSE.\r
+ If KeySize is not large enough, then return FALSE.\r
+ For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[in] PeerPublic Pointer to the peer's public X,Y.\r
+ @param[in] PeerPublicSize Size of peer's public X,Y in bytes.\r
+ @param[in] CompressFlag Flag of PeerPublic is compressed or not.\r
+ @param[out] Key Pointer to the buffer to receive generated key.\r
+ @param[in, out] KeySize On input, the size of Key buffer in bytes.\r
+ On output, the size of data returned in Key buffer in bytes.\r
+ @retval TRUE EC exchanged key generation succeeded.\r
+ @retval FALSE EC exchanged key generation failed.\r
+ @retval FALSE KeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDhComputeKey (\r
+ IN OUT VOID *EcContext,\r
+ IN CONST UINT8 *PeerPublic,\r
+ IN UINTN PeerPublicSize,\r
+ IN CONST INT32 *CompressFlag,\r
+ OUT UINT8 *Key,\r
+ IN OUT UINTN *KeySize\r
+ );\r
+\r
#endif // __BASE_CRYPT_LIB_H__\r
Pk/CryptTs.c\r
Pk/CryptRsaPss.c\r
Pk/CryptRsaPssSign.c\r
+ Pk/CryptEcNull.c |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled\r
+ Pk/CryptEc.c |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled\r
Pem/CryptPem.c\r
Bn/CryptBn.c\r
\r
Pk/CryptTsNull.c\r
Pk/CryptRsaPss.c\r
Pk/CryptRsaPssSignNull.c\r
+ Pk/CryptEcNull.c\r
Pem/CryptPemNull.c\r
Rand/CryptRandNull.c\r
Bn/CryptBnNull.c\r
--- /dev/null
+/** @file\r
+ Elliptic Curve and ECDH API implementation based on OpenSSL\r
+\r
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/objects.h>\r
+#include <openssl/bn.h>\r
+#include <openssl/ec.h>\r
+\r
+// =====================================================================================\r
+// Basic Elliptic Curve Primitives\r
+// =====================================================================================\r
+\r
+/**\r
+ Return the Nid of certain ECC curve.\r
+\r
+ @param[in] CryptoNid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+\r
+ @retval !=-1 On success.\r
+ @retval -1 ECC curve not supported.\r
+**/\r
+STATIC\r
+INT32\r
+CryptoNidToOpensslNid (\r
+ IN UINTN CryptoNid\r
+ )\r
+{\r
+ INT32 Nid;\r
+\r
+ switch (CryptoNid) {\r
+ case CRYPTO_NID_SECP256R1:\r
+ Nid = NID_X9_62_prime256v1;\r
+ break;\r
+ case CRYPTO_NID_SECP384R1:\r
+ Nid = NID_secp384r1;\r
+ break;\r
+ case CRYPTO_NID_SECP521R1:\r
+ Nid = NID_secp521r1;\r
+ break;\r
+ default:\r
+ return -1;\r
+ }\r
+\r
+ return Nid;\r
+}\r
+\r
+/**\r
+ Initialize new opaque EcGroup object. This object represents an EC curve and\r
+ and is used for calculation within this group. This object should be freed\r
+ using EcGroupFree() function.\r
+\r
+ @param[in] CryptoNid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+\r
+ @retval EcGroup object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcGroupInit (\r
+ IN UINTN CryptoNid\r
+ )\r
+{\r
+ INT32 Nid;\r
+\r
+ Nid = CryptoNidToOpensslNid (CryptoNid);\r
+\r
+ if (Nid < 0) {\r
+ return NULL;\r
+ }\r
+\r
+ return EC_GROUP_new_by_curve_name (Nid);\r
+}\r
+\r
+/**\r
+ Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnPrime Group prime number.\r
+ @param[out] BnA A coefficient.\r
+ @param[out] BnB B coefficient..\r
+ @param[in] BnCtx BN context.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetCurve (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *BnPrime,\r
+ OUT VOID *BnA,\r
+ OUT VOID *BnB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA, BnB, BnCtx);\r
+}\r
+\r
+/**\r
+ Get EC group order.\r
+ This function will set the provided Big Number object to the corresponding\r
+ value. The caller needs to make sure that the "out" BigNumber parameter\r
+ is properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnOrder Group prime number.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetOrder (\r
+ IN VOID *EcGroup,\r
+ OUT VOID *BnOrder\r
+ )\r
+{\r
+ return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder, NULL);\r
+}\r
+\r
+/**\r
+ Free previously allocated EC group object using EcGroupInit().\r
+\r
+ @param[in] EcGroup EC group object to free.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcGroupFree (\r
+ IN VOID *EcGroup\r
+ )\r
+{\r
+ EC_GROUP_free (EcGroup);\r
+}\r
+\r
+/**\r
+ Initialize new opaque EC Point object. This object represents an EC point\r
+ within the given EC group (curve).\r
+\r
+ @param[in] EC Group, properly initialized using EcGroupInit().\r
+\r
+ @retval EC Point object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcPointInit (\r
+ IN CONST VOID *EcGroup\r
+ )\r
+{\r
+ return EC_POINT_new (EcGroup);\r
+}\r
+\r
+/**\r
+ Free previously allocated EC Point object using EcPointInit().\r
+\r
+ @param[in] EcPoint EC Point to free.\r
+ @param[in] Clear TRUE iff the memory should be cleared.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcPointDeInit (\r
+ IN VOID *EcPoint,\r
+ IN BOOLEAN Clear\r
+ )\r
+{\r
+ if (Clear) {\r
+ EC_POINT_clear_free (EcPoint);\r
+ } else {\r
+ EC_POINT_free (EcPoint);\r
+ }\r
+}\r
+\r
+/**\r
+ Get EC point affine (x,y) coordinates.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[out] BnX X coordinate.\r
+ @param[out] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointGetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ OUT VOID *BnX,\r
+ OUT VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx);\r
+}\r
+\r
+/**\r
+ Set EC point affine (x,y) coordinates.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN CONST VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx);\r
+}\r
+\r
+/**\r
+ EC Point addition. EcPointResult = EcPointA + EcPointB.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPointA EC Point.\r
+ @param[in] EcPointB EC Point.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointAdd (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx);\r
+}\r
+\r
+/**\r
+ Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnPScalar P Scalar.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointMul (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPoint,\r
+ IN CONST VOID *BnPScalar,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult, NULL, EcPoint, BnPScalar, BnCtx);\r
+}\r
+\r
+/**\r
+ Calculate the inverse of the supplied EC point.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in,out] EcPoint EC point to invert.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointInvert (\r
+ IN CONST VOID *EcGroup,\r
+ IN OUT VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx);\r
+}\r
+\r
+/**\r
+ Check if the supplied point is on EC curve.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On curve.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsOnCurve (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) == 1;\r
+}\r
+\r
+/**\r
+ Check if the supplied point is at infinity.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+\r
+ @retval TRUE At infinity.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsAtInfinity (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint\r
+ )\r
+{\r
+ return EC_POINT_is_at_infinity (EcGroup, EcPoint) == 1;\r
+}\r
+\r
+/**\r
+ Check if EC points are equal.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPointA EC point A.\r
+ @param[in] EcPointB EC point B.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE A == B.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointEqual (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) == 0;\r
+}\r
+\r
+/**\r
+ Set EC point compressed coordinates. Points can be described in terms of\r
+ their compressed coordinates. For a point (x, y), for any given value for x\r
+ such that the point is on the curve there will only ever be two possible\r
+ values for y. Therefore, a point can be set using this function where BnX is\r
+ the x coordinate and YBit is a value 0 or 1 to identify which of the two\r
+ possible values for y should be used.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] YBit 0 or 1 to identify which Y value is used.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetCompressedCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN UINT8 YBit,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ return (BOOLEAN)EC_POINT_set_compressed_coordinates (EcGroup, EcPoint, BnX, YBit, BnCtx);\r
+}\r
+\r
+// =====================================================================================\r
+// Elliptic Curve Diffie Hellman Primitives\r
+// =====================================================================================\r
+\r
+/**\r
+ Allocates and Initializes one Elliptic Curve Context for subsequent use\r
+ with the NID.\r
+\r
+ @param[in] Nid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+ @return Pointer to the Elliptic Curve Context that has been initialized.\r
+ If the allocations fails, EcNewByNid() returns NULL.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcNewByNid (\r
+ IN UINTN Nid\r
+ )\r
+{\r
+ INT32 OpenSslNid;\r
+\r
+ OpenSslNid = CryptoNidToOpensslNid (Nid);\r
+ if (OpenSslNid < 0) {\r
+ return NULL;\r
+ }\r
+\r
+ return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid);\r
+}\r
+\r
+/**\r
+ Release the specified EC context.\r
+\r
+ @param[in] EcContext Pointer to the EC context to be released.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcFree (\r
+ IN VOID *EcContext\r
+ )\r
+{\r
+ EC_KEY_free ((EC_KEY *)EcContext);\r
+}\r
+\r
+/**\r
+ Generates EC key and returns EC public key (X, Y), Please note, this function uses\r
+ pseudo random number generator. The caller must make sure RandomSeed()\r
+ function was properly called before.\r
+ The Ec context should be correctly initialized by EcNewByNid.\r
+ This function generates random secret, and computes the public key (X, Y), which is\r
+ returned via parameter Public, PublicSize.\r
+ X is the first half of Public with size being PublicSize / 2,\r
+ Y is the second half of Public with size being PublicSize / 2.\r
+ EC context is updated accordingly.\r
+ If the Public buffer is too small to hold the public X, Y, FALSE is returned and\r
+ PublicSize is set to the required buffer size to obtain the public X, Y.\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PublicSize is NULL, then return FALSE.\r
+ If PublicSize is large enough but Public is NULL, then return FALSE.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC public X,Y generation succeeded.\r
+ @retval FALSE EC public X,Y generation failed.\r
+ @retval FALSE PublicKeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGenerateKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ EC_KEY *EcKey;\r
+ CONST EC_GROUP *Group;\r
+ CONST EC_POINT *EcPoint;\r
+ BOOLEAN RetVal;\r
+ BIGNUM *BnX;\r
+ BIGNUM *BnY;\r
+ UINTN HalfSize;\r
+ INTN XSize;\r
+ INTN YSize;\r
+\r
+ if ((EcContext == NULL) || (PublicKeySize == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((PublicKey == NULL) && (*PublicKeySize != 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ EcKey = (EC_KEY *)EcContext;\r
+ Group = EC_KEY_get0_group (EcKey);\r
+ HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;\r
+\r
+ // Assume RAND_seed was called\r
+ if (EC_KEY_generate_key (EcKey) != 1) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (*PublicKeySize < HalfSize * 2) {\r
+ *PublicKeySize = HalfSize * 2;\r
+ return FALSE;\r
+ }\r
+\r
+ *PublicKeySize = HalfSize * 2;\r
+\r
+ EcPoint = EC_KEY_get0_public_key (EcKey);\r
+ if (EcPoint == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ RetVal = FALSE;\r
+ BnX = BN_new ();\r
+ BnY = BN_new ();\r
+ if ((BnX == NULL) || (BnY == NULL)) {\r
+ goto fail;\r
+ }\r
+\r
+ if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) {\r
+ goto fail;\r
+ }\r
+\r
+ XSize = BN_num_bytes (BnX);\r
+ YSize = BN_num_bytes (BnY);\r
+ if ((XSize <= 0) || (YSize <= 0)) {\r
+ goto fail;\r
+ }\r
+\r
+ ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize);\r
+\r
+ ZeroMem (PublicKey, *PublicKeySize);\r
+ BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);\r
+ BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);\r
+\r
+ RetVal = TRUE;\r
+\r
+fail:\r
+ BN_free (BnX);\r
+ BN_free (BnY);\r
+ return RetVal;\r
+}\r
+\r
+/**\r
+ Gets the public key component from the established EC context.\r
+ The Ec context should be correctly initialized by EcNewByNid, and successfully\r
+ generate key pair from EcGenerateKey().\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to EC context being set.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC key component was retrieved successfully.\r
+ @retval FALSE Invalid EC key component.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGetPubKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ EC_KEY *EcKey;\r
+ CONST EC_GROUP *Group;\r
+ CONST EC_POINT *EcPoint;\r
+ BIGNUM *BnX;\r
+ BIGNUM *BnY;\r
+ UINTN HalfSize;\r
+ INTN XSize;\r
+ INTN YSize;\r
+ BOOLEAN RetVal;\r
+\r
+ if ((EcContext == NULL) || (PublicKeySize == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((PublicKey == NULL) && (*PublicKeySize != 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ EcKey = (EC_KEY *)EcContext;\r
+ Group = EC_KEY_get0_group (EcKey);\r
+ HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;\r
+ if (*PublicKeySize < HalfSize * 2) {\r
+ *PublicKeySize = HalfSize * 2;\r
+ return FALSE;\r
+ }\r
+\r
+ *PublicKeySize = HalfSize * 2;\r
+\r
+ EcPoint = EC_KEY_get0_public_key (EcKey);\r
+ if (EcPoint == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ RetVal = FALSE;\r
+ BnX = BN_new ();\r
+ BnY = BN_new ();\r
+ if ((BnX == NULL) || (BnY == NULL)) {\r
+ goto fail;\r
+ }\r
+\r
+ if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != 1) {\r
+ goto fail;\r
+ }\r
+\r
+ XSize = BN_num_bytes (BnX);\r
+ YSize = BN_num_bytes (BnY);\r
+ if ((XSize <= 0) || (YSize <= 0)) {\r
+ goto fail;\r
+ }\r
+\r
+ ASSERT ((UINTN)XSize <= HalfSize && (UINTN)YSize <= HalfSize);\r
+\r
+ if (PublicKey != NULL) {\r
+ ZeroMem (PublicKey, *PublicKeySize);\r
+ BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);\r
+ BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);\r
+ }\r
+\r
+ RetVal = TRUE;\r
+\r
+fail:\r
+ BN_free (BnX);\r
+ BN_free (BnY);\r
+ return RetVal;\r
+}\r
+\r
+/**\r
+ Computes exchanged common key.\r
+ Given peer's public key (X, Y), this function computes the exchanged common key,\r
+ based on its own context including value of curve parameter and random secret.\r
+ X is the first half of PeerPublic with size being PeerPublicSize / 2,\r
+ Y is the second half of PeerPublic with size being PeerPublicSize / 2.\r
+ If public key is compressed, the PeerPublic will only contain half key (X).\r
+ If EcContext is NULL, then return FALSE.\r
+ If PeerPublic is NULL, then return FALSE.\r
+ If PeerPublicSize is 0, then return FALSE.\r
+ If Key is NULL, then return FALSE.\r
+ If KeySize is not large enough, then return FALSE.\r
+ For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[in] PeerPublic Pointer to the peer's public X,Y.\r
+ @param[in] PeerPublicSize Size of peer's public X,Y in bytes.\r
+ @param[in] CompressFlag Flag of PeerPublic is compressed or not.\r
+ @param[out] Key Pointer to the buffer to receive generated key.\r
+ @param[in, out] KeySize On input, the size of Key buffer in bytes.\r
+ On output, the size of data returned in Key buffer in bytes.\r
+ @retval TRUE EC exchanged key generation succeeded.\r
+ @retval FALSE EC exchanged key generation failed.\r
+ @retval FALSE KeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDhComputeKey (\r
+ IN OUT VOID *EcContext,\r
+ IN CONST UINT8 *PeerPublic,\r
+ IN UINTN PeerPublicSize,\r
+ IN CONST INT32 *CompressFlag,\r
+ OUT UINT8 *Key,\r
+ IN OUT UINTN *KeySize\r
+ )\r
+{\r
+ EC_KEY *EcKey;\r
+ EC_KEY *PeerEcKey;\r
+ CONST EC_GROUP *Group;\r
+ BOOLEAN RetVal;\r
+ BIGNUM *BnX;\r
+ BIGNUM *BnY;\r
+ EC_POINT *Point;\r
+ INT32 OpenSslNid;\r
+ UINTN HalfSize;\r
+\r
+ if ((EcContext == NULL) || (PeerPublic == NULL) || (KeySize == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((Key == NULL) && (*KeySize != 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (PeerPublicSize > INT_MAX) {\r
+ return FALSE;\r
+ }\r
+\r
+ EcKey = (EC_KEY *)EcContext;\r
+ Group = EC_KEY_get0_group (EcKey);\r
+ HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;\r
+ if ((CompressFlag == NULL) && (PeerPublicSize != HalfSize * 2)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((CompressFlag != NULL) && (PeerPublicSize != HalfSize)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (*KeySize < HalfSize) {\r
+ *KeySize = HalfSize;\r
+ return FALSE;\r
+ }\r
+\r
+ *KeySize = HalfSize;\r
+\r
+ RetVal = FALSE;\r
+ Point = NULL;\r
+ BnX = BN_bin2bn (PeerPublic, (INT32)HalfSize, NULL);\r
+ BnY = NULL;\r
+ Point = EC_POINT_new (Group);\r
+ PeerEcKey = NULL;\r
+ if ((BnX == NULL) || (Point == NULL)) {\r
+ goto fail;\r
+ }\r
+\r
+ if (CompressFlag == NULL) {\r
+ BnY = BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize, NULL);\r
+ if (BnY == NULL) {\r
+ goto fail;\r
+ }\r
+\r
+ if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY, NULL) != 1) {\r
+ goto fail;\r
+ }\r
+ } else {\r
+ if (EC_POINT_set_compressed_coordinates (Group, Point, BnX, *CompressFlag, NULL) != 1) {\r
+ goto fail;\r
+ }\r
+ }\r
+\r
+ // Validate NIST ECDH public key\r
+ OpenSslNid = EC_GROUP_get_curve_name (Group);\r
+ PeerEcKey = EC_KEY_new_by_curve_name (OpenSslNid);\r
+ if (PeerEcKey == NULL) {\r
+ goto fail;\r
+ }\r
+\r
+ if (EC_KEY_set_public_key (PeerEcKey, Point) != 1) {\r
+ goto fail;\r
+ }\r
+\r
+ if (EC_KEY_check_key (PeerEcKey) != 1) {\r
+ goto fail;\r
+ }\r
+\r
+ if (ECDH_compute_key (Key, *KeySize, Point, EcKey, NULL) <= 0) {\r
+ goto fail;\r
+ }\r
+\r
+ RetVal = TRUE;\r
+\r
+fail:\r
+ BN_free (BnX);\r
+ BN_free (BnY);\r
+ EC_POINT_free (Point);\r
+ EC_KEY_free (PeerEcKey);\r
+ return RetVal;\r
+}\r
--- /dev/null
+/** @file\r
+ Elliptic Curve and ECDH API implementation based on OpenSSL\r
+\r
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+ Initialize new opaque EcGroup object. This object represents an EC curve and\r
+ and is used for calculation within this group. This object should be freed\r
+ using EcGroupFree() function.\r
+\r
+ @param[in] CryptoNid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+\r
+ @retval EcGroup object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcGroupInit (\r
+ IN UINTN CryptoNid\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnPrime Group prime number.\r
+ @param[out] BnA A coefficient.\r
+ @param[out] BnB B coefficient..\r
+ @param[in] BnCtx BN context.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetCurve (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *BnPrime,\r
+ OUT VOID *BnA,\r
+ OUT VOID *BnB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Get EC group order.\r
+ This function will set the provided Big Number object to the corresponding\r
+ value. The caller needs to make sure that the "out" BigNumber parameter\r
+ is properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnOrder Group prime number.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetOrder (\r
+ IN VOID *EcGroup,\r
+ OUT VOID *BnOrder\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Free previously allocated EC group object using EcGroupInit().\r
+\r
+ @param[in] EcGroup EC group object to free.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcGroupFree (\r
+ IN VOID *EcGroup\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Initialize new opaque EC Point object. This object represents an EC point\r
+ within the given EC group (curve).\r
+\r
+ @param[in] EC Group, properly initialized using EcGroupInit().\r
+\r
+ @retval EC Point object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcPointInit (\r
+ IN CONST VOID *EcGroup\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Free previously allocated EC Point object using EcPointInit().\r
+\r
+ @param[in] EcPoint EC Point to free.\r
+ @param[in] Clear TRUE iff the memory should be cleared.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcPointDeInit (\r
+ IN VOID *EcPoint,\r
+ IN BOOLEAN Clear\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Get EC point affine (x,y) coordinates.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[out] BnX X coordinate.\r
+ @param[out] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointGetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ OUT VOID *BnX,\r
+ OUT VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Set EC point affine (x,y) coordinates.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN CONST VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ EC Point addition. EcPointResult = EcPointA + EcPointB.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPointA EC Point.\r
+ @param[in] EcPointB EC Point.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointAdd (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnPScalar P Scalar.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointMul (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPoint,\r
+ IN CONST VOID *BnPScalar,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Calculate the inverse of the supplied EC point.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in,out] EcPoint EC point to invert.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointInvert (\r
+ IN CONST VOID *EcGroup,\r
+ IN OUT VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if the supplied point is on EC curve.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On curve.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsOnCurve (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if the supplied point is at infinity.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+\r
+ @retval TRUE At infinity.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsAtInfinity (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if EC points are equal.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPointA EC point A.\r
+ @param[in] EcPointB EC point B.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE A == B.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointEqual (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Set EC point compressed coordinates. Points can be described in terms of\r
+ their compressed coordinates. For a point (x, y), for any given value for x\r
+ such that the point is on the curve there will only ever be two possible\r
+ values for y. Therefore, a point can be set using this function where BnX is\r
+ the x coordinate and YBit is a value 0 or 1 to identify which of the two\r
+ possible values for y should be used.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] YBit 0 or 1 to identify which Y value is used.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetCompressedCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN UINT8 YBit,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Allocates and Initializes one Elliptic Curve Context for subsequent use\r
+ with the NID.\r
+\r
+ @param[in] Nid cipher NID\r
+ @return Pointer to the Elliptic Curve Context that has been initialized.\r
+ If the allocations fails, EcNewByNid() returns NULL.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcNewByNid (\r
+ IN UINTN Nid\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Release the specified EC context.\r
+\r
+ @param[in] EcContext Pointer to the EC context to be released.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcFree (\r
+ IN VOID *EcContext\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Generates EC key and returns EC public key (X, Y), Please note, this function uses\r
+ pseudo random number generator. The caller must make sure RandomSeed()\r
+ function was properly called before.\r
+ The Ec context should be correctly initialized by EcNewByNid.\r
+ This function generates random secret, and computes the public key (X, Y), which is\r
+ returned via parameter Public, PublicSize.\r
+ X is the first half of Public with size being PublicSize / 2,\r
+ Y is the second half of Public with size being PublicSize / 2.\r
+ EC context is updated accordingly.\r
+ If the Public buffer is too small to hold the public X, Y, FALSE is returned and\r
+ PublicSize is set to the required buffer size to obtain the public X, Y.\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PublicSize is NULL, then return FALSE.\r
+ If PublicSize is large enough but Public is NULL, then return FALSE.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC public X,Y generation succeeded.\r
+ @retval FALSE EC public X,Y generation failed.\r
+ @retval FALSE PublicKeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGenerateKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Gets the public key component from the established EC context.\r
+ The Ec context should be correctly initialized by EcNewByNid, and successfully\r
+ generate key pair from EcGenerateKey().\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to EC context being set.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC key component was retrieved successfully.\r
+ @retval FALSE Invalid EC key component.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGetPubKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Computes exchanged common key.\r
+ Given peer's public key (X, Y), this function computes the exchanged common key,\r
+ based on its own context including value of curve parameter and random secret.\r
+ X is the first half of PeerPublic with size being PeerPublicSize / 2,\r
+ Y is the second half of PeerPublic with size being PeerPublicSize / 2.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PeerPublic is NULL, then return FALSE.\r
+ If PeerPublicSize is 0, then return FALSE.\r
+ If Key is NULL, then return FALSE.\r
+ If KeySize is not large enough, then return FALSE.\r
+ For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[in] PeerPublic Pointer to the peer's public X,Y.\r
+ @param[in] PeerPublicSize Size of peer's public X,Y in bytes.\r
+ @param[in] CompressFlag Flag of PeerPublic is compressed or not.\r
+ @param[out] Key Pointer to the buffer to receive generated key.\r
+ @param[in, out] KeySize On input, the size of Key buffer in bytes.\r
+ On output, the size of data returned in Key buffer in bytes.\r
+ @retval TRUE EC exchanged key generation succeeded.\r
+ @retval FALSE EC exchanged key generation failed.\r
+ @retval FALSE KeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDhComputeKey (\r
+ IN OUT VOID *EcContext,\r
+ IN CONST UINT8 *PeerPublic,\r
+ IN UINTN PeerPublicSize,\r
+ IN CONST INT32 *CompressFlag,\r
+ OUT UINT8 *Key,\r
+ IN OUT UINTN *KeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
Pk/CryptTsNull.c\r
Pk/CryptRsaPss.c\r
Pk/CryptRsaPssSignNull.c\r
+ Pk/CryptEcNull.c\r
Pem/CryptPem.c\r
Bn/CryptBnNull.c\r
\r
Pk/CryptX509Null.c\r
Pk/CryptAuthenticodeNull.c\r
Pk/CryptTsNull.c\r
+ Pk/CryptEcNull.c\r
Pem/CryptPemNull.c\r
Rand/CryptRandNull.c\r
Pk/CryptRsaPssNull.c\r
--- /dev/null
+/** @file\r
+ Elliptic Curve and ECDH API implementation based on OpenSSL\r
+\r
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseCryptLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+ Initialize new opaque EcGroup object. This object represents an EC curve and\r
+ and is used for calculation within this group. This object should be freed\r
+ using EcGroupFree() function.\r
+\r
+ @param[in] CryptoNid Identifying number for the ECC curve (Defined in\r
+ BaseCryptLib.h).\r
+\r
+ @retval EcGroup object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcGroupInit (\r
+ IN UINTN CryptoNid\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Get EC curve parameters. While elliptic curve equation is Y^2 mod P = (X^3 + AX + B) Mod P.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnPrime Group prime number.\r
+ @param[out] BnA A coefficient.\r
+ @param[out] BnB B coefficient..\r
+ @param[in] BnCtx BN context.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetCurve (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *BnPrime,\r
+ OUT VOID *BnA,\r
+ OUT VOID *BnB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Get EC group order.\r
+ This function will set the provided Big Number object to the corresponding\r
+ value. The caller needs to make sure that the "out" BigNumber parameter\r
+ is properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] BnOrder Group prime number.\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGroupGetOrder (\r
+ IN VOID *EcGroup,\r
+ OUT VOID *BnOrder\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Free previously allocated EC group object using EcGroupInit().\r
+\r
+ @param[in] EcGroup EC group object to free.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcGroupFree (\r
+ IN VOID *EcGroup\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Initialize new opaque EC Point object. This object represents an EC point\r
+ within the given EC group (curve).\r
+\r
+ @param[in] EC Group, properly initialized using EcGroupInit().\r
+\r
+ @retval EC Point object On success.\r
+ @retval NULL On failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcPointInit (\r
+ IN CONST VOID *EcGroup\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Free previously allocated EC Point object using EcPointInit().\r
+\r
+ @param[in] EcPoint EC Point to free.\r
+ @param[in] Clear TRUE iff the memory should be cleared.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcPointDeInit (\r
+ IN VOID *EcPoint,\r
+ IN BOOLEAN Clear\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Get EC point affine (x,y) coordinates.\r
+ This function will set the provided Big Number objects to the corresponding\r
+ values. The caller needs to make sure all the "out" BigNumber parameters\r
+ are properly initialized.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[out] BnX X coordinate.\r
+ @param[out] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointGetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ OUT VOID *BnX,\r
+ OUT VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Set EC point affine (x,y) coordinates.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point object.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] BnY Y coordinate.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetAffineCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN CONST VOID *BnY,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ EC Point addition. EcPointResult = EcPointA + EcPointB.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPointA EC Point.\r
+ @param[in] EcPointB EC Point.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointAdd (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Variable EC point multiplication. EcPointResult = EcPoint * BnPScalar.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[out] EcPointResult EC point to hold the result. The point should\r
+ be properly initialized.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnPScalar P Scalar.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointMul (\r
+ IN CONST VOID *EcGroup,\r
+ OUT VOID *EcPointResult,\r
+ IN CONST VOID *EcPoint,\r
+ IN CONST VOID *BnPScalar,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Calculate the inverse of the supplied EC point.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in,out] EcPoint EC point to invert.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointInvert (\r
+ IN CONST VOID *EcGroup,\r
+ IN OUT VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if the supplied point is on EC curve.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On curve.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsOnCurve (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if the supplied point is at infinity.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC point to check.\r
+\r
+ @retval TRUE At infinity.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointIsAtInfinity (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPoint\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check if EC points are equal.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPointA EC point A.\r
+ @param[in] EcPointB EC point B.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE A == B.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointEqual (\r
+ IN CONST VOID *EcGroup,\r
+ IN CONST VOID *EcPointA,\r
+ IN CONST VOID *EcPointB,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Set EC point compressed coordinates. Points can be described in terms of\r
+ their compressed coordinates. For a point (x, y), for any given value for x\r
+ such that the point is on the curve there will only ever be two possible\r
+ values for y. Therefore, a point can be set using this function where BnX is\r
+ the x coordinate and YBit is a value 0 or 1 to identify which of the two\r
+ possible values for y should be used.\r
+\r
+ @param[in] EcGroup EC group object.\r
+ @param[in] EcPoint EC Point.\r
+ @param[in] BnX X coordinate.\r
+ @param[in] YBit 0 or 1 to identify which Y value is used.\r
+ @param[in] BnCtx BN context, created with BigNumNewContext().\r
+\r
+ @retval TRUE On success.\r
+ @retval FALSE Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcPointSetCompressedCoordinates (\r
+ IN CONST VOID *EcGroup,\r
+ IN VOID *EcPoint,\r
+ IN CONST VOID *BnX,\r
+ IN UINT8 YBit,\r
+ IN VOID *BnCtx\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Allocates and Initializes one Elliptic Curve Context for subsequent use\r
+ with the NID.\r
+\r
+ @param[in] Nid cipher NID\r
+ @return Pointer to the Elliptic Curve Context that has been initialized.\r
+ If the allocations fails, EcNewByNid() returns NULL.\r
+**/\r
+VOID *\r
+EFIAPI\r
+EcNewByNid (\r
+ IN UINTN Nid\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Release the specified EC context.\r
+\r
+ @param[in] EcContext Pointer to the EC context to be released.\r
+**/\r
+VOID\r
+EFIAPI\r
+EcFree (\r
+ IN VOID *EcContext\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ Generates EC key and returns EC public key (X, Y), Please note, this function uses\r
+ pseudo random number generator. The caller must make sure RandomSeed()\r
+ function was properly called before.\r
+ The Ec context should be correctly initialized by EcNewByNid.\r
+ This function generates random secret, and computes the public key (X, Y), which is\r
+ returned via parameter Public, PublicSize.\r
+ X is the first half of Public with size being PublicSize / 2,\r
+ Y is the second half of Public with size being PublicSize / 2.\r
+ EC context is updated accordingly.\r
+ If the Public buffer is too small to hold the public X, Y, FALSE is returned and\r
+ PublicSize is set to the required buffer size to obtain the public X, Y.\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PublicSize is NULL, then return FALSE.\r
+ If PublicSize is large enough but Public is NULL, then return FALSE.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC public X,Y generation succeeded.\r
+ @retval FALSE EC public X,Y generation failed.\r
+ @retval FALSE PublicKeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGenerateKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Gets the public key component from the established EC context.\r
+ The Ec context should be correctly initialized by EcNewByNid, and successfully\r
+ generate key pair from EcGenerateKey().\r
+ For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to EC context being set.\r
+ @param[out] PublicKey Pointer to t buffer to receive generated public X,Y.\r
+ @param[in, out] PublicKeySize On input, the size of Public buffer in bytes.\r
+ On output, the size of data returned in Public buffer in bytes.\r
+ @retval TRUE EC key component was retrieved successfully.\r
+ @retval FALSE Invalid EC key component.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcGetPubKey (\r
+ IN OUT VOID *EcContext,\r
+ OUT UINT8 *PublicKey,\r
+ IN OUT UINTN *PublicKeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Computes exchanged common key.\r
+ Given peer's public key (X, Y), this function computes the exchanged common key,\r
+ based on its own context including value of curve parameter and random secret.\r
+ X is the first half of PeerPublic with size being PeerPublicSize / 2,\r
+ Y is the second half of PeerPublic with size being PeerPublicSize / 2.\r
+ If EcContext is NULL, then return FALSE.\r
+ If PeerPublic is NULL, then return FALSE.\r
+ If PeerPublicSize is 0, then return FALSE.\r
+ If Key is NULL, then return FALSE.\r
+ If KeySize is not large enough, then return FALSE.\r
+ For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte is Y.\r
+ For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte is Y.\r
+ For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte is Y.\r
+ @param[in, out] EcContext Pointer to the EC context.\r
+ @param[in] PeerPublic Pointer to the peer's public X,Y.\r
+ @param[in] PeerPublicSize Size of peer's public X,Y in bytes.\r
+ @param[in] CompressFlag Flag of PeerPublic is compressed or not.\r
+ @param[out] Key Pointer to the buffer to receive generated key.\r
+ @param[in, out] KeySize On input, the size of Key buffer in bytes.\r
+ On output, the size of data returned in Key buffer in bytes.\r
+ @retval TRUE EC exchanged key generation succeeded.\r
+ @retval FALSE EC exchanged key generation failed.\r
+ @retval FALSE KeySize is not large enough.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDhComputeKey (\r
+ IN OUT VOID *EcContext,\r
+ IN CONST UINT8 *PeerPublic,\r
+ IN UINTN PeerPublicSize,\r
+ IN CONST INT32 *CompressFlag,\r
+ OUT UINT8 *Key,\r
+ IN OUT UINTN *KeySize\r
+ )\r
+{\r
+ ASSERT (FALSE);\r
+ return FALSE;\r
+}\r