BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545
Cc: Laszlo Ersek <ler...@redhat.com> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Jian J Wang <jian.j.w...@intel.com> Cc: Xiaoyu Lu <xiaoyux...@intel.com> Signed-off-by: Christopher J Zurcher <christopher.j.zurc...@intel.com> --- CryptoPkg/CryptoPkg.dsc | 3 + CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 ++ CryptoPkg/Private/Protocol/Crypto.h | 131 +++++++++++++++++ CryptoPkg/Driver/Crypto.c | 152 +++++++++++++++++++- CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 144 +++++++++++++++++++ 5 files changed, 439 insertions(+), 1 deletion(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 1af78468a1..af3fceb99f 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -159,6 +159,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Tls.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif !if $(CRYPTO_SERVICES) == MIN_PEI @@ -173,6 +174,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.Free | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.SetKey | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Pkcs.Services.Pkcs5HashPassword | TRUE + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif !if $(CRYPTO_SERVICES) == MIN_DXE_MIN_SMM @@ -203,6 +205,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.Init | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcEncrypt | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcDecrypt | TRUE + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif ################################################################################################### diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 44fb0262f4..b79c98d679 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -288,6 +288,16 @@ typedef struct { } Services; UINT32 Family; } TlsGet; + union { + struct { + UINT8 Init:1; + UINT8 Duplicate:1; + UINT8 Update:1; + UINT8 Final:1; + UINT8 HashAll:1; + } Services; + UINT32 Family; + } EvpMd; } PCD_CRYPTO_SERVICE_FAMILY_ENABLE; #endif diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index c399e0d67a..a3dffc0ce0 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -3434,6 +3434,131 @@ EFI_STATUS IN OUT UINTN *DataSize ); +/** + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use. + + If DigestName is NULL, then return FALSE. + + @param[in] DigestName Pointer to the digest name as a NULL-terminated ASCII string. + Valid digest names are: + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 + SHA3-224, SHA3-256, SHA3-384, SHA3-512 + SM3 + + @return Pointer to the EVP_MD_CTX context that has been allocated and initialized. + If DigestName is invalid, returns NULL. + If the allocations fails, returns NULL. + If initialization fails, returns NULL. + +**/ +typedef +VOID * +(EFIAPI* EDKII_CRYPTO_EVPMD_INIT)( + IN CONST CHAR8 *DigestName + ); + +/** + Makes a copy of an existing EVP_MD context. + + If EvpMdContext is NULL, then return FALSE. + If NewEvpMdContext is NULL, then return FALSE. + + @param[in] EvpMdContext Pointer to EVP_MD context being copied. + @param[out] NewEvpMdContext Pointer to new EVP_MD context. + + @retval TRUE EVP_MD context copy succeeded. + @retval FALSE EVP_MD context copy failed. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_DUPLICATE)( + IN CONST VOID *EvpMdContext, + OUT VOID *NewEvpMdContext + ); + +/** + Digests the input data and updates EVP_MD context. + + This function performs EVP digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + EVP_MD context should be already correctly initialized by EvpMdInit(), and should not + be finalized by EvpMdFinal(). Behavior with invalid context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP_MD context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE EVP data digest succeeded. + @retval FALSE EVP data digest failed. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_UPDATE)( + IN OUT VOID *EvpMdContext, + IN CONST VOID *Data, + IN UINTN DataSize + ); + +/** + Completes computation of the EVP digest value. + Releases the specified EVP_MD_CTX context. + + This function completes EVP hash computation and retrieves the digest value into + the specified memory. After this function has been called, the EVP context cannot + be used again. + EVP context should be already correctly initialized by EvpMdInit(), and should + not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If DigestValue is NULL, free the Context then return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP context. + @param[out] Digest Pointer to a buffer that receives the EVP digest value. + + @retval TRUE EVP digest computation succeeded. + @retval FALSE EVP digest computation failed. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_FINAL)( + IN OUT VOID *EvpMdContext, + OUT UINT8 *DigestValue + ); + +/** + Computes the message digest of an input data buffer. + + This function performs the message digest of a given data buffer, and places + the digest value into the specified memory. + + If DigestName is NULL, return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + If HashValue is NULL, return FALSE. + + @param[in] DigestName Pointer to the digest name. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataSize Size of Data buffer in bytes. + @param[out] HashValue Pointer to a buffer that receives the digest value. + + @retval TRUE Digest computation succeeded. + @retval FALSE Digest computation failed. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_HASH_ALL)( + IN CONST CHAR8 *DigestName, + IN CONST VOID *Data, + IN UINTN DataSize, + OUT UINT8 *HashValue + ); + /// /// EDK II Crypto Protocol @@ -3619,6 +3744,12 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert; EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey; EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationList; + /// Digest Envelope (EVP MD) + EDKII_CRYPTO_EVPMD_INIT EvpMdInit; + EDKII_CRYPTO_EVPMD_DUPLICATE EvpMdDuplicate; + EDKII_CRYPTO_EVPMD_UPDATE EvpMdUpdate; + EDKII_CRYPTO_EVPMD_FINAL EvpMdFinal; + EDKII_CRYPTO_EVPMD_HASH_ALL EvpMdHashAll; }; extern GUID gEdkiiCryptoProtocolGuid; diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index d9096ea603..c50ac4a6da 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -4463,6 +4463,150 @@ CryptoServiceTlsGetCertRevocationList ( return CALL_BASECRYPTLIB (TlsGet.Services.CertRevocationList, TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED); } +//===================================================================================== +// EVP (Envelope) Primitive +//===================================================================================== + +/** + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use. + + If DigestName is NULL, then return FALSE. + + @param[in] DigestName Pointer to the digest name as a NULL-terminated ASCII string. + Valid digest names are: + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 + SHA3-224, SHA3-256, SHA3-384, SHA3-512 + SM3 + + @return Pointer to the EVP_MD_CTX context that has been allocated and initialized. + If DigestName is invalid, returns NULL. + If the allocations fails, returns NULL. + If initialization fails, returns NULL. + +**/ +VOID * +EFIAPI +CryptoServiceEvpMdInit ( + IN CONST CHAR8 *DigestName + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Init, EvpMdInit, (DigestName), NULL); +} + +/** + Makes a copy of an existing EVP_MD context. + + If EvpMdContext is NULL, then return FALSE. + If NewEvpMdContext is NULL, then return FALSE. + + @param[in] EvpMdContext Pointer to EVP_MD context being copied. + @param[out] NewEvpMdContext Pointer to new EVP_MD context. + + @retval TRUE EVP_MD context copy succeeded. + @retval FALSE EVP_MD context copy failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceEvpMdDuplicate ( + IN CONST VOID *EvpMdContext, + OUT VOID *NewEvpMdContext + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Duplicate, EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE); +} + +/** + Digests the input data and updates EVP_MD context. + + This function performs EVP digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + EVP_MD context should be already correctly initialized by EvpMdInit(), and should not + be finalized by EvpMdFinal(). Behavior with invalid context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP_MD context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE EVP data digest succeeded. + @retval FALSE EVP data digest failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceEvpMdUpdate ( + IN OUT VOID *EvpMdContext, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Update, EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE); +} + +/** + Completes computation of the EVP digest value. + Releases the specified EVP_MD_CTX context. + + This function completes EVP hash computation and retrieves the digest value into + the specified memory. After this function has been called, the EVP context cannot + be used again. + EVP context should be already correctly initialized by EvpMdInit(), and should + not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If DigestValue is NULL, free the Context then return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP context. + @param[out] Digest Pointer to a buffer that receives the EVP digest value. + + @retval TRUE EVP digest computation succeeded. + @retval FALSE EVP digest computation failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceEvpMdFinal ( + IN OUT VOID *EvpMdContext, + OUT UINT8 *DigestValue + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Final, EvpMdFinal, (EvpMdContext, DigestValue), FALSE); +} + +/** + Computes the message digest of an input data buffer. + + This function performs the message digest of a given data buffer, and places + the digest value into the specified memory. + + If DigestName is NULL, return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + If HashValue is NULL, return FALSE. + + @param[in] DigestName Pointer to the digest name. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataSize Size of Data buffer in bytes. + @param[out] HashValue Pointer to a buffer that receives the digest value. + + @retval TRUE Digest computation succeeded. + @retval FALSE Digest computation failed. + +**/ +BOOLEAN +EFIAPI +CryptoServiceEvpMdHashAll ( + IN CONST CHAR8 *DigestName, + IN CONST VOID *Data, + IN UINTN DataSize, + OUT UINT8 *HashValue + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.HashAll, EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE); +} + const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { /// Version CryptoServiceGetCryptoVersion, @@ -4663,5 +4807,11 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceTlsGetCaCertificate, CryptoServiceTlsGetHostPublicCert, CryptoServiceTlsGetHostPrivateKey, - CryptoServiceTlsGetCertRevocationList + CryptoServiceTlsGetCertRevocationList, + /// Digest Envelope (EVP MD) + CryptoServiceEvpMdInit, + CryptoServiceEvpMdDuplicate, + CryptoServiceEvpMdUpdate, + CryptoServiceEvpMdFinal, + CryptoServiceEvpMdHashAll }; diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 3f14c6d262..0a68d0682e 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -3499,3 +3499,147 @@ TlsGetCertRevocationList ( { CALL_CRYPTO_SERVICE (TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED); } + +//===================================================================================== +// EVP (Envelope) Primitive +//===================================================================================== + +/** + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD use. + + If DigestName is NULL, then return FALSE. + + @param[in] DigestName Pointer to the digest name as a NULL-terminated ASCII string. + Valid digest names are: + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 + SHA3-224, SHA3-256, SHA3-384, SHA3-512 + SM3 + + @return Pointer to the EVP_MD_CTX context that has been allocated and initialized. + If DigestName is invalid, returns NULL. + If the allocations fails, returns NULL. + If initialization fails, returns NULL. + +**/ +VOID * +EFIAPI +EvpMdInit ( + IN CONST CHAR8 *DigestName + ) +{ + CALL_CRYPTO_SERVICE (EvpMdInit, (DigestName), NULL); +} + +/** + Makes a copy of an existing EVP_MD context. + + If EvpMdContext is NULL, then return FALSE. + If NewEvpMdContext is NULL, then return FALSE. + + @param[in] EvpMdContext Pointer to EVP_MD context being copied. + @param[out] NewEvpMdContext Pointer to new EVP_MD context. + + @retval TRUE EVP_MD context copy succeeded. + @retval FALSE EVP_MD context copy failed. + +**/ +BOOLEAN +EFIAPI +EvpMdDuplicate ( + IN CONST VOID *EvpMdContext, + OUT VOID *NewEvpMdContext + ) +{ + CALL_CRYPTO_SERVICE (EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE); +} + +/** + Digests the input data and updates EVP_MD context. + + This function performs EVP digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + EVP_MD context should be already correctly initialized by EvpMdInit(), and should not + be finalized by EvpMdFinal(). Behavior with invalid context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP_MD context. + @param[in] Data Pointer to the buffer containing the data to be digested. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE EVP data digest succeeded. + @retval FALSE EVP data digest failed. + +**/ +BOOLEAN +EFIAPI +EvpMdUpdate ( + IN OUT VOID *EvpMdContext, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + CALL_CRYPTO_SERVICE (EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE); +} + +/** + Completes computation of the EVP digest value. + Releases the specified EVP_MD_CTX context. + + This function completes EVP hash computation and retrieves the digest value into + the specified memory. After this function has been called, the EVP context cannot + be used again. + EVP context should be already correctly initialized by EvpMdInit(), and should + not be finalized by EvpMdFinal(). Behavior with invalid EVP context is undefined. + + If EvpMdContext is NULL, then return FALSE. + If DigestValue is NULL, free the Context then return FALSE. + + @param[in, out] EvpMdContext Pointer to the EVP context. + @param[out] Digest Pointer to a buffer that receives the EVP digest value. + + @retval TRUE EVP digest computation succeeded. + @retval FALSE EVP digest computation failed. + +**/ +BOOLEAN +EFIAPI +EvpMdFinal ( + IN OUT VOID *EvpMdContext, + OUT UINT8 *DigestValue + ) +{ + CALL_CRYPTO_SERVICE (EvpMdFinal, (EvpMdContext, DigestValue), FALSE); +} + +/** + Computes the message digest of an input data buffer. + + This function performs the message digest of a given data buffer, and places + the digest value into the specified memory. + + If DigestName is NULL, return FALSE. + If Data is NULL and DataSize is not zero, return FALSE. + If HashValue is NULL, return FALSE. + + @param[in] DigestName Pointer to the digest name. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataSize Size of Data buffer in bytes. + @param[out] HashValue Pointer to a buffer that receives the digest value. + + @retval TRUE Digest computation succeeded. + @retval FALSE Digest computation failed. + +**/ +BOOLEAN +EFIAPI +EvpMdHashAll ( + IN CONST CHAR8 *DigestName, + IN CONST VOID *Data, + IN UINTN DataSize, + OUT UINT8 *HashValue + ) +{ + CALL_CRYPTO_SERVICE (EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE); +} -- 2.28.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#65290): https://edk2.groups.io/g/devel/message/65290 Mute This Topic: https://groups.io/mt/76878640/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-