--- /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