This commit introduces a Unified Hash API to calculate hash using a hashing algorithm specified by the PCD, PcdHashApiLibPolicy. This library interfaces with the various hashing API, such as, MD4, MD5, SHA1, SHA256, SHA512 and SM3_256 implemented in BaseCryptLib. The user can calculate the desired hash by setting PcdHashApiLibPolicy to appropriate value.
Cc: Jiewen Yao <[email protected]> Cc: Jian J Wang <[email protected]> Cc: Michael D Kinney <[email protected]> Signed-off-by: Sukerkar, Amol N <[email protected]> --- Notes: v6 - Changed the PCD name to PcdHashApiLibPolicy - Changed the lib nabme to HashApiLib - Changes lib MODULE_TYPE to BASE CryptoPkg/Library/HashApiLib/HashApiLib.c | 333 ++++++++++++++++++++ CryptoPkg/CryptoPkg.dec | 21 ++ CryptoPkg/CryptoPkg.dsc | 7 +- CryptoPkg/CryptoPkg.uni | 17 + CryptoPkg/Include/Library/HashApiLib.h | 122 +++++++ CryptoPkg/Library/HashApiLib/HashApiLib.inf | 45 +++ CryptoPkg/Library/HashApiLib/HashApiLib.uni | 17 + 7 files changed, 561 insertions(+), 1 deletion(-) diff --git a/CryptoPkg/Library/HashApiLib/HashApiLib.c b/CryptoPkg/Library/HashApiLib/HashApiLib.c new file mode 100644 index 000000000000..0f5b594fb7c0 --- /dev/null +++ b/CryptoPkg/Library/HashApiLib/HashApiLib.c @@ -0,0 +1,333 @@ +/** @file + Unified Hash API Implementation + + This file implements the Unified Hash API. + + This API, when called, will calculate the Hash using the + hashing algorithm specified by PcdHashApiLibPolicy. + + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Base.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/BaseCryptLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/HashApiLib.h> + +/** + Retrieves the size, in bytes, of the context buffer required for hash operations. + + @return The size, in bytes, of the context buffer required for hash operations. + +**/ +UINTN +EFIAPI +HashApiGetContextSize ( + VOID + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4GetContextSize (); + break; + + case HASH_API_ALGO_MD5: + return Md5GetContextSize (); + break; + + case HASH_API_ALGO_SHA1: + return Sha1GetContextSize (); + break; + + case HASH_API_ALGO_SHA256: + return Sha256GetContextSize (); + break; + + case HASH_API_ALGO_SHA384: + return Sha384GetContextSize (); + break; + + case HASH_API_ALGO_SHA512: + return Sha512GetContextSize (); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3GetContextSize (); + break; + + default: + ASSERT (FALSE); + return 0; + break; + } +} + +/** + Init hash sequence. + + @param[out] HashContext Hash context. + + @retval TRUE Hash start and HashHandle returned. + @retval FALSE Hash Init unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiInit ( + OUT HASH_API_CONTEXT *HashContext + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4Init (HashContext); + break; + + case HASH_API_ALGO_MD5: + return Md5Init (HashContext); + break; + + case HASH_API_ALGO_SHA1: + return Sha1Init (HashContext); + break; + + case HASH_API_ALGO_SHA256: + return Sha256Init (HashContext); + break; + + case HASH_API_ALGO_SHA384: + return Sha384Init (HashContext); + break; + + case HASH_API_ALGO_SHA512: + return Sha512Init (HashContext); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3Init (HashContext); + break; + + default: + ASSERT (FALSE); + return FALSE; + break; + } +} + +/** + Makes a copy of an existing hash context. + + @param[in] HashContext Hash context. + @param[out] NewHashContext New copy of hash context. + + @retval TRUE Hash context copy succeeded. + @retval FALSE Hash context copy failed. + +**/ +BOOLEAN +EFIAPI +HashApiDuplicate ( + IN HASH_API_CONTEXT *HashContext, + OUT VOID *NewHashContext + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_MD5: + return Md5Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_SHA1: + return Sha1Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_SHA256: + return Sha256Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_SHA384: + return Sha384Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_SHA512: + return Sha512Duplicate (HashContext, NewHashContext); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3Duplicate (HashContext, NewHashContext); + break; + + default: + ASSERT (FALSE); + return FALSE; + break; + } +} + +/** + Update hash data. + + @param[in] HashContext Hash context. + @param[in] DataToHash Data to be hashed. + @param[in] DataToHashLen Data size. + + @retval TRUE Hash updated. + @retval FALSE Hash updated unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiUpdate ( + IN HASH_API_CONTEXT *HashContext, + IN VOID *DataToHash, + IN UINTN DataToHashLen + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_MD5: + return Md5Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_SHA1: + return Sha1Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_SHA256: + return Sha256Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_SHA384: + return Sha384Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_SHA512: + return Sha512Update (HashContext, DataToHash, DataToHashLen); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3Update (HashContext, DataToHash, DataToHashLen); + break; + + default: + ASSERT (FALSE); + return FALSE; + break; + } +} + +/** + Hash complete. + + @param[in] HashContext Hash context. + @param[out] Digest Hash Digest. + + @retval TRUE Hash complete and Digest is returned. + @retval FALSE Hash complete unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiFinal ( + IN HASH_API_CONTEXT *HashContext, + OUT UINT8 *Digest + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4Final (HashContext, Digest); + break; + + case HASH_API_ALGO_MD5: + return Md5Final (HashContext, Digest); + break; + + case HASH_API_ALGO_SHA1: + return Sha1Final (HashContext, Digest); + break; + + case HASH_API_ALGO_SHA256: + return Sha256Final (HashContext, Digest); + break; + + case HASH_API_ALGO_SHA384: + return Sha384Final (HashContext, Digest); + break; + + case HASH_API_ALGO_SHA512: + return Sha512Final (HashContext, Digest); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3Final (HashContext, Digest); + break; + + default: + ASSERT (FALSE); + return FALSE; + break; + } +} + +/** + Computes hash message digest of a input data buffer. + + @param[in] DataToHash Data to be hashed. + @param[in] DataToHashLen Data size. + @param[out] Digest Hash Digest. + + @retval TRUE Hash digest computation succeeded. + @retval FALSE Hash digest computation failed. + +**/ +BOOLEAN +EFIAPI +HashApiHashAll ( + IN CONST VOID *DataToHash, + IN UINTN DataToHashLen, + OUT UINT8 *Digest + ) +{ + switch (PcdGet8 (PcdHashApiLibPolicy)) { + case HASH_API_ALGO_MD4: + return Md4HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_MD5: + return Md5HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_SHA1: + return Sha1HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_SHA256: + return Sha256HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_SHA384: + return Sha384HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_SHA512: + return Sha512HashAll (DataToHash, DataToHashLen, Digest); + break; + + case HASH_API_ALGO_SM3_256: + return Sm3HashAll (DataToHash, DataToHashLen, Digest); + break; + + default: + ASSERT (FALSE); + return FALSE; + break; + } +} diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index 5986a988f790..bf0a408099db 100644 --- a/CryptoPkg/CryptoPkg.dec +++ b/CryptoPkg/CryptoPkg.dec @@ -33,9 +33,30 @@ [LibraryClasses] ## TlsLib|Include/Library/TlsLib.h + ## @libraryclass Provides Unified API for different hash implementations. + # + HashApiLib|Include/Library/HashApiLib.h + [Guids] ## Security package token space guid. gEfiCryptoPkgTokenSpaceGuid = { 0xd3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba }} +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] + ## This PCD indicates the HASH algorithm to verify unsigned PE/COFF image + # Based on the value set, the required algorithm is chosen to verify + # the unsigned image during Secure Boot.<BR> + # The hashing algorithm selected must match the hashing algorithm used to + # hash the image to be added to DB using tools such as KeyEnroll.<BR> + # 0x00000001 - MD4.<BR> + # 0x00000002 - MD5.<BR> + # 0x00000003 - SHA1.<BR> + # 0x00000004 - SHA256.<BR> + # 0x00000005 - SHA384.<BR> + # 0x00000006 - SHA512.<BR> + # 0x00000007 - SM3_256.<BR> + # @Prompt Set policy for hashing unsigned image for Secure Boot. + # @ValidRange 0x80000001 | 0x00000001 - 0x00000007 + gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy|0x04|UINT8|0x00000001 + [UserExtensions.TianoCore."ExtraFiles"] CryptoPkgExtra.uni diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index ec43c1f0a47e..1a9e70e5bf12 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -1,7 +1,7 @@ ## @file # Cryptographic Library Package for UEFI Security Implementation. # -# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -62,15 +62,19 @@ [LibraryClasses.ARM] [LibraryClasses.common.PEIM] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf + HashApiLib|CryptoPkg/Library/HashApiLib/HashApiLib.inf [LibraryClasses.common.DXE_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + HashApiLib|CryptoPkg/Library/HashApiLib/HashApiLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf + HashApiLib|CryptoPkg/Library/HashApiLib/HashApiLib.inf [LibraryClasses.common.DXE_SMM_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf + HashApiLib|CryptoPkg/Library/HashApiLib/HashApiLib.inf [LibraryClasses.common.UEFI_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -120,6 +124,7 @@ [Components] CryptoPkg/Library/TlsLibNull/TlsLibNull.inf CryptoPkg/Library/OpensslLib/OpensslLib.inf CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf + CryptoPkg/Library/HashApiLib/HashApiLib.inf [Components.IA32, Components.X64] CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf diff --git a/CryptoPkg/CryptoPkg.uni b/CryptoPkg/CryptoPkg.uni index beb0036ef583..8da39fa0f613 100644 --- a/CryptoPkg/CryptoPkg.uni +++ b/CryptoPkg/CryptoPkg.uni @@ -17,3 +17,20 @@ +#string STR_gEfiCryptoPkgTokenSpaceGuid_PcdHashApiLibPolicy_PROMPT #language en-US "HASH algorithm to verify unsigned PE/COFF image" + +#string STR_gEfiCryptoPkgTokenSpaceGuid_PcdHashApiLibPolicy_HELP #language en-US "This PCD indicates the HASH algorithm to verify unsigned PE/COFF image.<BR><BR>\n" + "Based on the value set, the required algorithm is chosen to verify\n" + "the unsigned image during Secure Boot.<BR>\n" + "The hashing algorithm selected must match the hashing algorithm used to\n" + "hash the image to be added to DB using tools such as KeyEnroll.<BR>\n" + "0x00000001 - MD4.<BR>\n" + "0x00000002 - MD5.<BR>\n" + "0x00000003 - SHA1.<BR>\n" + "0x00000004 - SHA256.<BR>\n" + "0x00000005 - SHA384.<BR>\n" + "0x00000006 - SHA512.<BR>\n" + "0x00000007 - SM3.<BR>" + + + diff --git a/CryptoPkg/Include/Library/HashApiLib.h b/CryptoPkg/Include/Library/HashApiLib.h new file mode 100644 index 000000000000..354b0c02b6ab --- /dev/null +++ b/CryptoPkg/Include/Library/HashApiLib.h @@ -0,0 +1,122 @@ +/** @file + Unified Hash API Defines + + This API when called will calculate the Hash using the + hashing algorithm specified by PcdHashApiLibPolicy. + + Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __HASHAPILIB_H_ +#define __HASHAPILIB_H_ + +typedef VOID HASH_API_CONTEXT; + +// +// Hash Algorithms +// +#define HASH_API_ALGO_INVALID 0x00000000 +#define HASH_API_ALGO_MD4 0x00000001 +#define HASH_API_ALGO_MD5 0x00000002 +#define HASH_API_ALGO_SHA1 0x00000003 +#define HASH_API_ALGO_SHA256 0x00000004 +#define HASH_API_ALGO_SHA384 0x00000005 +#define HASH_API_ALGO_SHA512 0x00000006 +#define HASH_API_ALGO_SM3_256 0x00000007 + +/** + Retrieves the size of the context buffer required for hash operations. + + @return The size of the context buffer required for hash operations (in bytes). +**/ +UINTN +EFIAPI +HashApiGetContextSize ( + VOID +); + +/** + Init hash sequence. + + @param[out] HashContext Hash context. + + @retval TRUE Hash start and HashHandle returned. + @retval FALSE Hash Init unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiInit ( + OUT HASH_API_CONTEXT *HashContext +); + +/** + Makes a copy of an existing hash context. + + @param[in] HashContext Hash context. + @param[out] NewHashContext New copy of hash context. + + @retval TRUE Hash context copy succeeded. + @retval FALSE Hash context copy failed. +**/ +BOOLEAN +EFIAPI +HashApiDuplicate ( + IN HASH_API_CONTEXT *HashContext, + OUT VOID *NewHashContext +); + +/** + Update hash data. + + @param[in] HashContext Hash context. + @param[in] DataToHash Data to be hashed. + @param[in] DataToHashLen Data size. + + @retval TRUE Hash updated. + @retval FALSE Hash updated unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiUpdate ( + IN HASH_API_CONTEXT *HashContext, + IN VOID *DataToHash, + IN UINTN DataToHashLen +); + +/** + Hash complete. + + @param[in] HashContext Hash context. + @param[out] Digest Hash Digest. + + @retval TRUE Hash complete and Digest is returned. + @retval FALSE Hash complete unsuccessful. +**/ +BOOLEAN +EFIAPI +HashApiFinal ( + IN HASH_API_CONTEXT *HashContext, + OUT UINT8 *Digest +); + +/** + Computes hash message digest of a input data buffer. + + @param[in] DataToHash Data to be hashed. + @param[in] DataToHashLen Data size. + @param[out] Digest Hash Digest. + + @retval TRUE Hash digest computation succeeded. + @retval FALSE Hash digest computation failed. +**/ +BOOLEAN +EFIAPI +HashApiHashAll ( + IN CONST VOID *DataToHash, + IN UINTN DataToHashLen, + OUT UINT8 *Digest +); + +#endif diff --git a/CryptoPkg/Library/HashApiLib/HashApiLib.inf b/CryptoPkg/Library/HashApiLib/HashApiLib.inf new file mode 100644 index 000000000000..1eeda4dd55e6 --- /dev/null +++ b/CryptoPkg/Library/HashApiLib/HashApiLib.inf @@ -0,0 +1,45 @@ +## @file +# Provides Unified API for Hash Calculation +# +# This library is HashApiLib. It will redirect hash request to each +# individual hash API, such as SHA1, SHA256, SHA384, SM3 based on +# hashing algorithm specified by PcdHashApiLibPolicy. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = HashApiLib + MODULE_UNI_FILE = HashApiLib.uni + FILE_GUID = DDCBCFBA-8EEB-488a-96D6-097831A6E50B + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = HashApiLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + HashApiLib.c + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + BaseCryptLib + PcdLib + +[Pcd] + gEfiCryptoPkgTokenSpaceGuid.PcdHashApiLibPolicy ## CONSUMES diff --git a/CryptoPkg/Library/HashApiLib/HashApiLib.uni b/CryptoPkg/Library/HashApiLib/HashApiLib.uni new file mode 100644 index 000000000000..2e09642a3197 --- /dev/null +++ b/CryptoPkg/Library/HashApiLib/HashApiLib.uni @@ -0,0 +1,17 @@ +// /** @file +// Provides Unified API for Hash Calculation +// +// This library is HashApiLib. It will redirect hash request to each +// individual hash API, such as SHA1, SHA256, SHA384, SM3 based on +// hashing algorithm specified by PcdHashApiLibPolicy. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides hash service by specified hash handler" + +#string STR_MODULE_DESCRIPTION #language en-US "This library is Unified Hash API. It will redirect hash request to the hash handler specified by PcdHashApiLibPolicy." -- 2.16.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53515): https://edk2.groups.io/g/devel/message/53515 Mute This Topic: https://groups.io/mt/70223677/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
