/** @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; | |
} | |
/** | |
Carries out the EC-DSA signature. | |
This function carries out the EC-DSA signature. | |
If the Signature buffer is too small to hold the contents of signature, FALSE | |
is returned and SigSize is set to the required buffer size to obtain the signature. | |
If EcContext is NULL, then return FALSE. | |
If MessageHash is NULL, then return FALSE. | |
If HashSize need match the HashNid. HashNid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512. | |
If SigSize is large enough but Signature is NULL, then return FALSE. | |
For P-256, the SigSize is 64. First 32-byte is R, Second 32-byte is S. | |
For P-384, the SigSize is 96. First 48-byte is R, Second 48-byte is S. | |
For P-521, the SigSize is 132. First 66-byte is R, Second 66-byte is S. | |
@param[in] EcContext Pointer to EC context for signature generation. | |
@param[in] HashNid hash NID | |
@param[in] MessageHash Pointer to octet message hash to be signed. | |
@param[in] HashSize Size of the message hash in bytes. | |
@param[out] Signature Pointer to buffer to receive EC-DSA signature. | |
@param[in, out] SigSize On input, the size of Signature buffer in bytes. | |
On output, the size of data returned in Signature buffer in bytes. | |
@retval TRUE Signature successfully generated in EC-DSA. | |
@retval FALSE Signature generation failed. | |
@retval FALSE SigSize is too small. | |
**/ | |
BOOLEAN | |
EFIAPI | |
EcDsaSign ( | |
IN VOID *EcContext, | |
IN UINTN HashNid, | |
IN CONST UINT8 *MessageHash, | |
IN UINTN HashSize, | |
OUT UINT8 *Signature, | |
IN OUT UINTN *SigSize | |
) | |
{ | |
ASSERT (FALSE); | |
return FALSE; | |
} | |
/** | |
Verifies the EC-DSA signature. | |
If EcContext is NULL, then return FALSE. | |
If MessageHash is NULL, then return FALSE. | |
If Signature is NULL, then return FALSE. | |
If HashSize need match the HashNid. HashNid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512. | |
For P-256, the SigSize is 64. First 32-byte is R, Second 32-byte is S. | |
For P-384, the SigSize is 96. First 48-byte is R, Second 48-byte is S. | |
For P-521, the SigSize is 132. First 66-byte is R, Second 66-byte is S. | |
@param[in] EcContext Pointer to EC context for signature verification. | |
@param[in] HashNid hash NID | |
@param[in] MessageHash Pointer to octet message hash to be checked. | |
@param[in] HashSize Size of the message hash in bytes. | |
@param[in] Signature Pointer to EC-DSA signature to be verified. | |
@param[in] SigSize Size of signature in bytes. | |
@retval TRUE Valid signature encoded in EC-DSA. | |
@retval FALSE Invalid signature or invalid EC context. | |
**/ | |
BOOLEAN | |
EFIAPI | |
EcDsaVerify ( | |
IN VOID *EcContext, | |
IN UINTN HashNid, | |
IN CONST UINT8 *MessageHash, | |
IN UINTN HashSize, | |
IN CONST UINT8 *Signature, | |
IN UINTN SigSize | |
) | |
{ | |
ASSERT (FALSE); | |
return FALSE; | |
} |