CryptoPkg: Add EC key interface to DXE and protocol

The implementation provide EC key interface for EFI
 driver nad EFI BaseCrypt protocol.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4102

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Qi Zhang 2022-10-12 10:47:59 +08:00 committed by mergify[bot]
parent f21a1d48fe
commit 69a50a249b
4 changed files with 412 additions and 2 deletions

View File

@ -6137,6 +6137,142 @@ CryptoServiceEcDhComputeKey (
return CALL_BASECRYPTLIB (Ec.Services.DhComputeKey, EcDhComputeKey, (EcContext, PeerPublic, PeerPublicSize, CompressFlag, Key, KeySize), FALSE);
}
/**
Retrieve the EC Public Key from one DER-encoded X509 certificate.
@param[in] Cert Pointer to the DER-encoded X509 certificate.
@param[in] CertSize Size of the X509 certificate in bytes.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC public key component. Use EcFree() function to free the
resource.
If Cert is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Public Key was retrieved successfully.
@retval FALSE Fail to retrieve EC public key from X509 certificate.
**/
BOOLEAN
EFIAPI
CryptoServiceEcGetPublicKeyFromX509 (
IN CONST UINT8 *Cert,
IN UINTN CertSize,
OUT VOID **EcContext
)
{
return CALL_BASECRYPTLIB (Ec.Services.GetPublicKeyFromX509, EcGetPublicKeyFromX509, (Cert, CertSize, EcContext), FALSE);
}
/**
Retrieve the EC Private Key from the password-protected PEM key data.
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
@param[in] PemSize Size of the PEM key data in bytes.
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC private key component. Use EcFree() function to free the
resource.
If PemData is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Private Key was retrieved successfully.
@retval FALSE Invalid PEM key data or incorrect password.
**/
BOOLEAN
EFIAPI
CryptoServiceEcGetPrivateKeyFromPem (
IN CONST UINT8 *PemData,
IN UINTN PemSize,
IN CONST CHAR8 *Password,
OUT VOID **EcContext
)
{
return CALL_BASECRYPTLIB (Ec.Services.GetPrivateKeyFromPem, EcGetPrivateKeyFromPem, (PemData, PemSize, Password, EcContext), 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
CryptoServiceEcDsaSign (
IN VOID *EcContext,
IN UINTN HashNid,
IN CONST UINT8 *MessageHash,
IN UINTN HashSize,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
)
{
return CALL_BASECRYPTLIB (Ec.Services.DsaSign, EcDsaSign, (EcContext, HashNid, MessageHash, HashSize, Signature, SigSize), 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
CryptoServiceEcDsaVerify (
IN VOID *EcContext,
IN UINTN HashNid,
IN CONST UINT8 *MessageHash,
IN UINTN HashSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize
)
{
return CALL_BASECRYPTLIB (Ec.Services.DsaVerify, EcDsaVerify, (EcContext, HashNid, MessageHash, HashSize, Signature, SigSize), FALSE);
}
const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
/// Version
CryptoServiceGetCryptoVersion,
@ -6416,5 +6552,10 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
CryptoServiceTlsSetSignatureAlgoList,
CryptoServiceTlsSetEcCurve,
/// TLS Get (continued)
CryptoServiceTlsGetExportKey
CryptoServiceTlsGetExportKey,
/// Ec (Continued)
CryptoServiceEcGetPublicKeyFromX509,
CryptoServiceEcGetPrivateKeyFromPem,
CryptoServiceEcDsaSign,
CryptoServiceEcDsaVerify
};

View File

@ -383,6 +383,10 @@ typedef struct {
UINT8 GenerateKey : 1;
UINT8 GetPubKey : 1;
UINT8 DhComputeKey : 1;
UINT8 GetPublicKeyFromX509 : 1;
UINT8 GetPrivateKeyFromPem : 1;
UINT8 DsaSign : 1;
UINT8 DsaVerify : 1;
} Services;
UINT32 Family;
} Ec;

View File

@ -5164,3 +5164,139 @@ EcDhComputeKey (
{
CALL_CRYPTO_SERVICE (EcDhComputeKey, (EcContext, PeerPublic, PeerPublicSize, CompressFlag, Key, KeySize), FALSE);
}
/**
Retrieve the EC Public Key from one DER-encoded X509 certificate.
@param[in] Cert Pointer to the DER-encoded X509 certificate.
@param[in] CertSize Size of the X509 certificate in bytes.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC public key component. Use EcFree() function to free the
resource.
If Cert is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Public Key was retrieved successfully.
@retval FALSE Fail to retrieve EC public key from X509 certificate.
**/
BOOLEAN
EFIAPI
EcGetPublicKeyFromX509 (
IN CONST UINT8 *Cert,
IN UINTN CertSize,
OUT VOID **EcContext
)
{
CALL_CRYPTO_SERVICE (EcGetPublicKeyFromX509, (Cert, CertSize, EcContext), FALSE);
}
/**
Retrieve the EC Private Key from the password-protected PEM key data.
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
@param[in] PemSize Size of the PEM key data in bytes.
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC private key component. Use EcFree() function to free the
resource.
If PemData is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Private Key was retrieved successfully.
@retval FALSE Invalid PEM key data or incorrect password.
**/
BOOLEAN
EFIAPI
EcGetPrivateKeyFromPem (
IN CONST UINT8 *PemData,
IN UINTN PemSize,
IN CONST CHAR8 *Password,
OUT VOID **EcContext
)
{
CALL_CRYPTO_SERVICE (EcGetPrivateKeyFromPem, (PemData, PemSize, Password, EcContext), 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
)
{
CALL_CRYPTO_SERVICE (EcDsaSign, (EcContext, HashNid, MessageHash, HashSize, Signature, SigSize), 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
)
{
CALL_CRYPTO_SERVICE (EcDsaVerify, (EcContext, HashNid, MessageHash, HashSize, Signature, SigSize), FALSE);
}

View File

@ -21,7 +21,7 @@
/// the EDK II Crypto Protocol is extended, this version define must be
/// increased.
///
#define EDKII_CRYPTO_VERSION 14
#define EDKII_CRYPTO_VERSION 15
///
/// EDK II Crypto Protocol forward declaration
@ -4821,6 +4821,130 @@ BOOLEAN
IN OUT UINTN *KeySize
);
/**
Retrieve the EC Public Key from one DER-encoded X509 certificate.
@param[in] Cert Pointer to the DER-encoded X509 certificate.
@param[in] CertSize Size of the X509 certificate in bytes.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC public key component. Use EcFree() function to free the
resource.
If Cert is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Public Key was retrieved successfully.
@retval FALSE Fail to retrieve EC public key from X509 certificate.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_EC_GET_PUBLIC_KEY_FROM_X509)(
IN CONST UINT8 *Cert,
IN UINTN CertSize,
OUT VOID **EcContext
);
/**
Retrieve the EC Private Key from the password-protected PEM key data.
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
@param[in] PemSize Size of the PEM key data in bytes.
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC private key component. Use EcFree() function to free the
resource.
If PemData is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Private Key was retrieved successfully.
@retval FALSE Invalid PEM key data or incorrect password.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_EC_GET_PRIVATE_KEY_FROM_PEM)(
IN CONST UINT8 *PemData,
IN UINTN PemSize,
IN CONST CHAR8 *Password,
OUT VOID **EcContext
);
/**
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.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_EC_DSA_SIGN)(
IN VOID *EcContext,
IN UINTN HashNid,
IN CONST UINT8 *MessageHash,
IN UINTN HashSize,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
);
/**
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.
**/
typedef
BOOLEAN
(EFIAPI *EDKII_CRYPTO_EC_DSA_VERIFY)(
IN VOID *EcContext,
IN UINTN HashNid,
IN CONST UINT8 *MessageHash,
IN UINTN HashSize,
IN CONST UINT8 *Signature,
IN UINTN SigSize
);
///
/// EDK II Crypto Protocol
///
@ -5084,6 +5208,11 @@ struct _EDKII_CRYPTO_PROTOCOL {
EDKII_CRYPTO_TLS_SET_EC_CURVE TlsSetEcCurve;
/// TLS Get (continued)
EDKII_CRYPTO_TLS_GET_EXPORT_KEY TlsGetExportKey;
/// Ec (Continued)
EDKII_CRYPTO_EC_GET_PUBLIC_KEY_FROM_X509 EcGetPublicKeyFromX509;
EDKII_CRYPTO_EC_GET_PRIVATE_KEY_FROM_PEM EcGetPrivateKeyFromPem;
EDKII_CRYPTO_EC_DSA_SIGN EcDsaSign;
EDKII_CRYPTO_EC_DSA_VERIFY EcDsaVerify;
};
extern GUID gEdkiiCryptoProtocolGuid;