From 97f98500c1d40eba76210961e90ea5d354bcbc18 Mon Sep 17 00:00:00 2001 From: hhtian Date: Mon, 1 Nov 2010 06:30:58 +0000 Subject: Add CryptoPkg (from UDK2010.UP3) git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10987 6f19259b-4bc3-4df7-8a09-765794883524 --- CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 79 ++++ CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c | 145 +++++++ CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c | 145 +++++++ CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c | 145 +++++++ CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 77 ++++ CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c | 160 ++++++++ CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c | 277 +++++++++++++ CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 81 ++++ .../BaseCryptLib/SysCall/BaseMemAllocation.c | 42 ++ .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 281 +++++++++++++ .../Library/BaseCryptLib/SysCall/HelperWrapper.c | 54 +++ .../Library/BaseCryptLib/SysCall/Ia32/Alloca.S | 59 +++ .../BaseCryptLib/SysCall/Ia32/MathDivU64x64.S | 83 ++++ .../BaseCryptLib/SysCall/Ia32/MathDivU64x64.c | 88 +++++ .../BaseCryptLib/SysCall/Ia32/MathLShiftS64.S | 62 +++ .../BaseCryptLib/SysCall/Ia32/MathLShiftS64.c | 54 +++ .../BaseCryptLib/SysCall/Ia32/MathMultS64x64.S | 77 ++++ .../BaseCryptLib/SysCall/Ia32/MathMultS64x64.c | 79 ++++ .../BaseCryptLib/SysCall/Ia32/MathRShiftU64.S | 66 ++++ .../BaseCryptLib/SysCall/Ia32/MathRShiftU64.c | 57 +++ .../BaseCryptLib/SysCall/Ia32/MathReminderU64x64.S | 89 +++++ .../BaseCryptLib/SysCall/Ia32/MathReminderU64x64.c | 93 +++++ .../BaseCryptLib/SysCall/RuntimeMemAllocation.c | 438 +++++++++++++++++++++ .../Library/BaseCryptLib/SysCall/TimerWrapper.c | 102 +++++ 24 files changed, 2833 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c create mode 100644 CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c create mode 100644 CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/HelperWrapper.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.S create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c create mode 100644 CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c (limited to 'CryptoPkg/Library/BaseCryptLib') diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf new file mode 100644 index 0000000000..5395da06a7 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -0,0 +1,79 @@ +## @file +# Cryptographic Library Instance for DXE_DRIVER. +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseCryptLib + FILE_GUID = be3bb803-91b6-4da0-bd91-a8b21c18ca5d + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseCryptLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources] + Hash/CryptMd5.c + Hash/CryptSha1.c + Hash/CryptSha256.c + Pk/CryptRsa.c + Pk/CryptPkcs7.c + + SysCall/CrtWrapper.c + SysCall/TimerWrapper.c + SysCall/BaseMemAllocation.c + +[Sources.Ia32] + SysCall/HelperWrapper.c + + SysCall/Ia32/MathMultS64x64.c | MSFT + SysCall/Ia32/MathDivU64x64.c | MSFT + SysCall/Ia32/MathReminderU64x64.c | MSFT + SysCall/Ia32/MathLShiftS64.c | MSFT + SysCall/Ia32/MathRShiftU64.c | MSFT + + SysCall/Ia32/MathMultS64x64.c | INTEL + SysCall/Ia32/MathDivU64x64.c | INTEL + SysCall/Ia32/MathReminderU64x64.c | INTEL + SysCall/Ia32/MathLShiftS64.c | INTEL + SysCall/Ia32/MathRShiftU64.c | INTEL + + SysCall/Ia32/MathMultS64x64.S | GCC + SysCall/Ia32/MathDivU64x64.S | GCC + SysCall/Ia32/MathReminderU64x64.S | GCC + SysCall/Ia32/MathLShiftS64.S | GCC + SysCall/Ia32/MathRShiftU64.S | GCC + + SysCall/Ia32/Alloca.S | GCC + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + OpensslLib + IntrinsicLib + +# +# Remove these [BuildOptions] after this library is cleaned up +# +[BuildOptions] + GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))" diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c new file mode 100644 index 0000000000..99471a0176 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c @@ -0,0 +1,145 @@ +/** @file + MD5 Digest Wrapper Implementation over OpenSSL. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +#include +#include + + +/** + Retrieves the size, in bytes, of the context buffer required for MD5 hash operations. + + @return The size, in bytes, of the context buffer required for MD5 hash operations. + +**/ +UINTN +EFIAPI +Md5GetContextSize ( + VOID + ) +{ + // + // Retrieves the OpenSSL MD5 Context Size + // + return (UINTN)(sizeof (MD5_CTX)); +} + + +/** + Initializes user-supplied memory pointed by Md5Context as MD5 hash context for + subsequent use. + + If Md5Context is NULL, then ASSERT(). + + @param[in, out] Md5Context Pointer to MD5 Context being initialized. + + @retval TRUE MD5 context initialization succeeded. + @retval FALSE MD5 context initialization failed. + +**/ +BOOLEAN +EFIAPI +Md5Init ( + IN OUT VOID *Md5Context + ) +{ + // + // ASSERT if Md5Context is NULL. + // + ASSERT (Md5Context != NULL); + + // + // OpenSSL MD5 Context Initialization + // + return (BOOLEAN) (MD5_Init ((MD5_CTX *)Md5Context)); +} + + +/** + Performs MD5 digest on a data buffer of the specified length. This function can + be called multiple times to compute the digest of long or discontinuous data streams. + + If Md5Context is NULL, then ASSERT(). + + @param[in, out] Md5Context Pointer to the MD5 context. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataLength Length of Data buffer in bytes. + + @retval TRUE MD5 data digest succeeded. + @retval FALSE Invalid MD5 context. After Md5Final function has been called, the + MD5 context cannot be reused. + +**/ +BOOLEAN +EFIAPI +Md5Update ( + IN OUT VOID *Md5Context, + IN CONST VOID *Data, + IN UINTN DataLength + ) +{ + // + // ASSERT if Md5Context is NULL + // + ASSERT (Md5Context != NULL); + + // + // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL + // + if (Data == NULL) { + ASSERT (DataLength == 0); + } + + // + // OpenSSL MD5 Hash Update + // + return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataLength)); +} + + +/** + Completes MD5 hash computation and retrieves the digest value into the specified + memory. After this function has been called, the MD5 context cannot be used again. + + If Md5Context is NULL, then ASSERT(). + If HashValue is NULL, then ASSERT(). + + @param[in, out] Md5Context Pointer to the MD5 context + @param[out] HashValue Pointer to a buffer that receives the MD5 digest + value (16 bytes). + + @retval TRUE MD5 digest computation succeeded. + @retval FALSE MD5 digest computation failed. + +**/ +BOOLEAN +EFIAPI +Md5Final ( + IN OUT VOID *Md5Context, + OUT UINT8 *HashValue + ) +{ + // + // ASSERT if Md5Context is NULL or HashValue is NULL + // + ASSERT (Md5Context != NULL); + ASSERT (HashValue != NULL); + + // + // OpenSSL MD5 Hash Finalization + // + return (BOOLEAN) (MD5_Final (HashValue, (MD5_CTX *)Md5Context)); +} diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c new file mode 100644 index 0000000000..d774059300 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c @@ -0,0 +1,145 @@ +/** @file + SHA-1 Digest Wrapper Implementation over OpenSSL. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +#include +#include + + +/** + Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations. + + @return The size, in bytes, of the context buffer required for SHA-1 hash operations. + +**/ +UINTN +EFIAPI +Sha1GetContextSize ( + VOID + ) +{ + // + // Retrieves OpenSSL SHA Context Size + // + return (UINTN)(sizeof (SHA_CTX)); +} + + +/** + Initializes user-supplied memory pointed by Sha1Context as the SHA-1 hash context for + subsequent use. + + If Sha1Context is NULL, then ASSERT(). + + @param[in, out] Sha1Context Pointer to the SHA-1 Context being initialized. + + @retval TRUE SHA-1 initialization succeeded. + @retval FALSE SHA-1 initialization failed. + +**/ +BOOLEAN +EFIAPI +Sha1Init ( + IN OUT VOID *Sha1Context + ) +{ + // + // ASSERT if Sha1Context is NULL + // + ASSERT (Sha1Context != NULL); + + // + // OpenSSL SHA-1 Context Initialization + // + return (BOOLEAN) (SHA1_Init ((SHA_CTX *)Sha1Context)); +} + + +/** + Performs SHA-1 digest on a data buffer of the specified length. This function can + be called multiple times to compute the digest of long or discontinuous data streams. + + If Sha1Context is NULL, then ASSERT(). + + @param[in, out] Sha1Context Pointer to the SHA-1 context. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataLength Length of Data buffer in bytes. + + @retval TRUE SHA-1 data digest succeeded. + @retval FALSE Invalid SHA-1 context. After Sha1Final function has been called, the + SHA-1 context cannot be reused. + +**/ +BOOLEAN +EFIAPI +Sha1Update ( + IN OUT VOID *Sha1Context, + IN CONST VOID *Data, + IN UINTN DataLength + ) +{ + // + // ASSERT if Sha1Context is NULL + // + ASSERT (Sha1Context != NULL); + + // + // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL + // + if (Data == NULL) { + ASSERT (DataLength == 0); + } + + // + // OpenSSL SHA-1 Hash Update + // + return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataLength)); +} + + +/** + Completes SHA-1 hash computation and retrieves the digest value into the specified + memory. After this function has been called, the SHA-1 context cannot be used again. + + If Sha1Context is NULL, then ASSERT(). + If HashValue is NULL, then ASSERT(). + + @param[in, out] Sha1Context Pointer to the SHA-1 context + @param[out] HashValue Pointer to a buffer that receives the SHA-1 digest + value (20 bytes). + + @retval TRUE SHA-1 digest computation succeeded. + @retval FALSE SHA-1 digest computation failed. + +**/ +BOOLEAN +EFIAPI +Sha1Final ( + IN OUT VOID *Sha1Context, + OUT UINT8 *HashValue + ) +{ + // + // ASSERT if Sha1Context is NULL or HashValue is NULL + // + ASSERT (Sha1Context != NULL); + ASSERT (HashValue != NULL); + + // + // OpenSSL SHA-1 Hash Finalization + // + return (BOOLEAN) (SHA1_Final (HashValue, (SHA_CTX *)Sha1Context)); +} diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c new file mode 100644 index 0000000000..9b566a4c59 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c @@ -0,0 +1,145 @@ +/** @file + SHA-256 Digest Wrapper Implementation over OpenSSL. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +#include +#include + + +/** + Retrieves the size, in bytes, of the context buffer required for SHA-256 operations. + + @return The size, in bytes, of the context buffer required for SHA-256 operations. + +**/ +UINTN +EFIAPI +Sha256GetContextSize ( + VOID + ) +{ + // + // Retrieves OpenSSL SHA-256 Context Size + // + return (UINTN)(sizeof (SHA256_CTX)); +} + + +/** + Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for + subsequent use. + + If Sha256Context is NULL, then ASSERT(). + + @param[in, out] Sha256Context Pointer to SHA-256 Context being initialized. + + @retval TRUE SHA-256 context initialization succeeded. + @retval FALSE SHA-256 context initialization failed. + +**/ +BOOLEAN +EFIAPI +Sha256Init ( + IN OUT VOID *Sha256Context + ) +{ + // + // ASSERT if Sha256Context is NULL + // + ASSERT (Sha256Context != NULL); + + // + // OpenSSL SHA-256 Context Initialization + // + return (BOOLEAN) (SHA256_Init ((SHA256_CTX *)Sha256Context)); +} + + +/** + Performs SHA-256 digest on a data buffer of the specified length. This function can + be called multiple times to compute the digest of long or discontinuous data streams. + + If Sha256Context is NULL, then ASSERT(). + + @param[in, out] Sha256Context Pointer to the SHA-256 context. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataLength Length of Data buffer in bytes. + + @retval TRUE SHA-256 data digest succeeded. + @retval FALSE Invalid SHA-256 context. After Sha256Final function has been called, the + SHA-256 context cannot be reused. + +**/ +BOOLEAN +EFIAPI +Sha256Update ( + IN OUT VOID *Sha256Context, + IN CONST VOID *Data, + IN UINTN DataLength + ) +{ + // + // ASSERT if Sha256Context is NULL + // + ASSERT (Sha256Context != NULL); + + // + // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL + // + if (Data == NULL) { + ASSERT (DataLength == 0); + } + + // + // OpenSSL SHA-256 Hash Update + // + return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataLength)); +} + + +/** + Completes SHA-256 hash computation and retrieves the digest value into the specified + memory. After this function has been called, the SHA-256 context cannot be used again. + + If Sha256Context is NULL, then ASSERT(). + If HashValue is NULL, then ASSERT(). + + @param[in, out] Sha256Context Pointer to SHA-256 context + @param[out] HashValue Pointer to a buffer that receives the SHA-256 digest + value (32 bytes). + + @retval TRUE SHA-256 digest computation succeeded. + @retval FALSE SHA-256 digest computation failed. + +**/ +BOOLEAN +EFIAPI +Sha256Final ( + IN OUT VOID *Sha256Context, + OUT UINT8 *HashValue + ) +{ + // + // ASSERT if Sha256Context is NULL or HashValue is NULL + // + ASSERT (Sha256Context != NULL); + ASSERT (HashValue != NULL); + + // + // OpenSSL SHA-256 Hash Finalization + // + return (BOOLEAN) (SHA256_Final (HashValue, (SHA256_CTX *)Sha256Context)); +} diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf new file mode 100644 index 0000000000..30061a68ff --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -0,0 +1,77 @@ +## @file +# Cryptographic Library Instance for PEIM. +# +# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiCryptLib + FILE_GUID = 9a2a4375-194c-4e97-9f67-547ec98d96ca + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseCryptLib|PEIM PEI_CORE SEC + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Hash/CryptMd5.c + Hash/CryptSha1.c + Hash/CryptSha256.c + Pk/CryptRsa.c + + SysCall/CrtWrapper.c + SysCall/HelperWrapper.c + SysCall/BaseMemAllocation.c + +[Sources.Ia32] + SysCall/Ia32/MathMultS64x64.c | MSFT + SysCall/Ia32/MathDivU64x64.c | MSFT + SysCall/Ia32/MathReminderU64x64.c | MSFT + SysCall/Ia32/MathLShiftS64.c | MSFT + SysCall/Ia32/MathRShiftU64.c | MSFT + + SysCall/Ia32/MathMultS64x64.c | INTEL + SysCall/Ia32/MathDivU64x64.c | INTEL + SysCall/Ia32/MathReminderU64x64.c | INTEL + SysCall/Ia32/MathLShiftS64.c | INTEL + SysCall/Ia32/MathRShiftU64.c | INTEL + + SysCall/Ia32/MathMultS64x64.S | GCC + SysCall/Ia32/MathDivU64x64.S | GCC + SysCall/Ia32/MathReminderU64x64.S | GCC + SysCall/Ia32/MathLShiftS64.S | GCC + SysCall/Ia32/MathRShiftU64.S | GCC + + SysCall/Ia32/Alloca.S | GCC + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + OpensslLib + IntrinsicLib + +# +# Remove these [BuildOptions] after this library is cleaned up +# +[BuildOptions] + GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))" + diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c new file mode 100644 index 0000000000..d0a6ea544a --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c @@ -0,0 +1,160 @@ +/** @file + PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include +#include +#include +#include + + +/** + Verifies the validility of a PKCS#7 signed data as described in "PKCS #7: Cryptographic + Message Syntax Standard". + + If P7Data is NULL, then ASSERT(). + + @param[in] P7Data Pointer to the PKCS#7 message to verify. + @param[in] P7Length Length of the PKCS#7 message in bytes. + @param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which + is used for certificate chain verification. + @param[in] CertLength Length of the trusted certificate in bytes. + @param[in] InData Pointer to the content to be verified. + @param[in] DataLength Length of InData in bytes. + + @return TRUE The specified PKCS#7 signed data is valid. + @return FALSE Invalid PKCS#7 signed data. + +**/ +BOOLEAN +EFIAPI +Pkcs7Verify ( + IN CONST UINT8 *P7Data, + IN UINTN P7Length, + IN CONST UINT8 *TrustedCert, + IN UINTN CertLength, + IN CONST UINT8 *InData, + IN UINTN DataLength + ) +{ + PKCS7 *Pkcs7; + UINT8 *Content; + BIO *CertBio; + BIO *DataBio; + BOOLEAN Status; + X509 *Cert; + X509_STORE *CertStore; + + // + // ASSERT if P7Data is NULL + // + ASSERT (P7Data != NULL); + + Status = FALSE; + Pkcs7 = NULL; + CertBio = NULL; + DataBio = NULL; + Cert = NULL; + CertStore = NULL; + + // + // Register & Initialize necessary digest algorithms for PKCS#7 Handling + // + EVP_add_digest (EVP_md5()); + EVP_add_digest (EVP_sha1()); + EVP_add_digest (EVP_sha256()); + + // + // Retrieve PKCS#7 Data (DER encoding) + // + Pkcs7 = d2i_PKCS7 (NULL, &P7Data, (int)P7Length); + if (Pkcs7 == NULL) { + goto _Exit; + } + + // + // Check if it's PKCS#7 Signed Data (for Authenticode Scenario) + // + if (!PKCS7_type_is_signed (Pkcs7)) { + goto _Exit; + } + + // + // Check PKCS#7 embedded signed content with InData. + // + if (InData != NULL) { + // + // NOTE: PKCS7_dataDecode() didn't work for Authenticode-format signed data due to + // some authenticode-specific structure. Use opaque ASN.1 string to retrieve + // PKCS#7 ContentInfo here. + // + Content = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data); + + // Ignore two bytes for DER encoding of ASN.1 "SEQUENCE" + if (CompareMem (Content + 2, InData, DataLength) != 0) { + goto _Exit; + } + } + + // + // Read DER-encoded root certificate and Construct X509 Certificate + // + CertBio = BIO_new (BIO_s_mem ()); + BIO_write (CertBio, TrustedCert, (int)CertLength); + if (CertBio == NULL) { + goto _Exit; + } + Cert = d2i_X509_bio (CertBio, NULL); + if (Cert == NULL) { + goto _Exit; + } + + // + // Setup X509 Store for trusted certificate + // + CertStore = X509_STORE_new (); + if (CertStore == NULL) { + goto _Exit; + } + if (!(X509_STORE_add_cert (CertStore, Cert))) { + goto _Exit; + } + + // + // For generic PKCS#7 handling, InData may be NULL if the content is present + // in PKCS#7 structure. So ignore NULL checking here. + // + DataBio = BIO_new (BIO_s_mem ()); + BIO_write (DataBio, InData, (int)DataLength); + + // + // Verifies the PKCS#7 signedData structure + // + Status = (BOOLEAN) PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, 0); + +_Exit: + // + // Release Resources + // + BIO_free (DataBio); + BIO_free (CertBio); + X509_free (Cert); + X509_STORE_free (CertStore); + PKCS7_free (Pkcs7); + + return Status; +} diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c new file mode 100644 index 0000000000..763213ab6b --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c @@ -0,0 +1,277 @@ +/** @file + RSA Asymmetric Cipher Wrapper Implementation over OpenSSL. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include +#include + + +/** + Allocates and Initializes one RSA Context for subsequent use. + + @return Pointer to the RSA Context that has been initialized. + If the allocations fails, RsaNew() returns NULL. + +**/ +VOID * +EFIAPI +RsaNew ( + VOID + ) +{ + // + // Allocates & Initializes RSA Context by OpenSSL RSA_new() + // + return (VOID *)RSA_new (); +} + + +/** + Release the specified RSA Context. + + @param[in] RsaContext Pointer to the RSA context to be released. + +**/ +VOID +EFIAPI +RsaFree ( + IN VOID *RsaContext + ) +{ + // + // Free OpenSSL RSA Context + // + RSA_free ((RSA *)RsaContext); +} + + +/** + Sets the tag-designated RSA key component into the established RSA context from + the user-specified nonnegative integer (octet string format represented in RSA + PKCS#1). + + If RsaContext is NULL, then ASSERT(). + + @param[in, out] RsaContext Pointer to RSA context being set. + @param[in] KeyTag Tag of RSA key component being set. + @param[in] BigNumber Pointer to octet integer buffer. + @param[in] BnLength Length of big number buffer in bytes. + + @return TRUE RSA key component was set successfully. + @return FALSE Invalid RSA key component tag. + +**/ +BOOLEAN +EFIAPI +RsaSetKey ( + IN OUT VOID *RsaContext, + IN RSA_KEY_TAG KeyTag, + IN CONST UINT8 *BigNumber, + IN UINTN BnLength + ) +{ + RSA *RsaKey; + + // + // ASSERT if RsaContext is NULL + // + ASSERT (RsaContext != NULL); + + + RsaKey = (RSA *)RsaContext; + // + // Set RSA Key Components by converting octet string to OpenSSL BN representation. + // NOTE: For RSA public key (used in signature verification), only public components + // (N, e) are needed. + // + switch (KeyTag) { + + // + // RSA Public Modulus (N) + // + case RsaKeyN: + if (RsaKey->n != NULL) { + BN_free (RsaKey->n); + } + RsaKey->n = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->n); + break; + + // + // RSA Public Exponent (e) + // + case RsaKeyE: + if (RsaKey->e != NULL) { + BN_free (RsaKey->e); + } + RsaKey->e = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->e); + break; + + // + // RSA Private Exponent (d) + // + case RsaKeyD: + if (RsaKey->d != NULL) { + BN_free (RsaKey->d); + } + RsaKey->d = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->d); + break; + + // + // RSA Secret Prime Factor of Modulus (p) + // + case RsaKeyP: + if (RsaKey->p != NULL) { + BN_free (RsaKey->p); + } + RsaKey->p = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->p); + break; + + // + // RSA Secret Prime Factor of Modules (q) + // + case RsaKeyQ: + if (RsaKey->q != NULL) { + BN_free (RsaKey->q); + } + RsaKey->q = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->q); + break; + + // + // p's CRT Exponent (== d mod (p - 1)) + // + case RsaKeyDp: + if (RsaKey->dmp1 != NULL) { + BN_free (RsaKey->dmp1); + } + RsaKey->dmp1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmp1); + break; + + // + // q's CRT Exponent (== d mod (q - 1)) + // + case RsaKeyDq: + if (RsaKey->dmq1 != NULL) { + BN_free (RsaKey->dmq1); + } + RsaKey->dmq1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmq1); + break; + + // + // The CRT Coefficient (== 1/q mod p) + // + case RsaKeyQInv: + if (RsaKey->iqmp != NULL) { + BN_free (RsaKey->iqmp); + } + RsaKey->iqmp = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->iqmp); + break; + + default: + return FALSE; + } + + return TRUE; +} + + +/** + Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in + RSA PKCS#1. + + If RsaContext is NULL, then ASSERT(). + If MessageHash is NULL, then ASSERT(). + If Signature is NULL, then ASSERT(). + If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then ASSERT(). + + @param[in] RsaContext Pointer to RSA context for signature verification. + @param[in] MessageHash Pointer to octet message hash to be checked. + @param[in] HashLength Length of the message hash in bytes. + @param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified. + @param[in] SigLength Length of signature in bytes. + + @return TRUE Valid signature encoded in PKCS1-v1_5. + @return FALSE Invalid signature or invalid RSA context. + +**/ +BOOLEAN +EFIAPI +RsaPkcs1Verify ( + IN VOID *RsaContext, + IN CONST UINT8 *MessageHash, + IN UINTN HashLength, + IN UINT8 *Signature, + IN UINTN SigLength + ) +{ + INTN Length; + + // + // ASSERT if RsaContext, MessageHash or Signature is NULL + // + ASSERT (RsaContext != NULL); + ASSERT (MessageHash != NULL); + ASSERT (Signature != NULL); + + // + // ASSERT if unsupported hash length: + // Only MD5, SHA-1 or SHA-256 digest size is supported + // + ASSERT ((HashLength == MD5_DIGEST_SIZE) || (HashLength == SHA1_DIGEST_SIZE) || + (HashLength == SHA256_DIGEST_SIZE)); + + // + // RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key + // + Length = RSA_public_decrypt ( + (int)SigLength, + Signature, + Signature, + RsaContext, + RSA_PKCS1_PADDING + ); + + // + // Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0) + // NOTE: Length should be the addition of HashLength and some DER value. + // Ignore more strict length checking here. + // + if (Length < (INTN) HashLength) { + return FALSE; + } + + // + // Validate the MessageHash and Decoded Signature + // NOTE: The decoded Signature should be the DER encoding of the DigestInfo value + // DigestInfo ::= SEQUENCE { + // digestAlgorithm AlgorithmIdentifier + // digest OCTET STRING + // } + // Then Memory Comparing should skip the DER value of the underlying SEQUENCE + // type and AlgorithmIdentifier. + // + if (CompareMem (MessageHash, Signature + Length - HashLength, HashLength) == 0) { + // + // Valid RSA PKCS#1 Signature + // + return TRUE; + } else { + // + // Failed to verification + // + return FALSE; + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf new file mode 100644 index 0000000000..d31095be20 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf @@ -0,0 +1,81 @@ +## @file +# Cryptographic Library Instance for DXE_RUNTIME_DRIVER +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RuntimeCryptLib + FILE_GUID = 78189cc0-727d-46a4-84ea-f7dd860de64a + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseCryptLib + CONSTRUCTOR = RuntimeCryptLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources] + Hash/CryptMd5.c + Hash/CryptSha1.c + Hash/CryptSha256.c + Pk/CryptRsa.c + + SysCall/CrtWrapper.c + SysCall/TimerWrapper.c + SysCall/HelperWrapper.c + SysCall/RuntimeMemAllocation.c + +[Sources.Ia32] + SysCall/Ia32/MathMultS64x64.c | MSFT + SysCall/Ia32/MathDivU64x64.c | MSFT + SysCall/Ia32/MathReminderU64x64.c | MSFT + SysCall/Ia32/MathLShiftS64.c | MSFT + SysCall/Ia32/MathRShiftU64.c | MSFT + + SysCall/Ia32/MathMultS64x64.c | INTEL + SysCall/Ia32/MathDivU64x64.c | INTEL + SysCall/Ia32/MathReminderU64x64.c | INTEL + SysCall/Ia32/MathLShiftS64.c | INTEL + SysCall/Ia32/MathRShiftU64.c | INTEL + + SysCall/Ia32/MathMultS64x64.S | GCC + SysCall/Ia32/MathDivU64x64.S | GCC + SysCall/Ia32/MathReminderU64x64.S | GCC + SysCall/Ia32/MathLShiftS64.S | GCC + SysCall/Ia32/MathRShiftU64.S | GCC + + SysCall/Ia32/Alloca.S | GCC + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + DebugLib + OpensslLib + IntrinsicLib + +# +# Remove these [BuildOptions] after this library is cleaned up +# +[BuildOptions] + GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))" + diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c b/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c new file mode 100644 index 0000000000..68bc25aba6 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c @@ -0,0 +1,42 @@ +/** @file + Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL + during PEI & DXE phases. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +// +// -- Memory-Allocation Routines -- +// + +/* Allocates memory blocks */ +void *malloc (size_t size) +{ + return AllocatePool ((UINTN)size); +} + +/* Reallocate memory blocks */ +void *realloc (void *ptr, size_t size) +{ + // + // BUG: hardcode OldSize == size! We have no any knowledge about + // memory size of original pointer ptr. + // + return ReallocatePool ((UINTN)size, (UINTN)size, ptr); +} + +/* De-allocates or frees a memory block */ +void free (void *ptr) +{ + FreePool (ptr); +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c new file mode 100644 index 0000000000..4bef42ee7a --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c @@ -0,0 +1,281 @@ +/** @file + C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based + Cryptographic Library. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +typedef +INTN +(*SORT_COMPARE)( + IN VOID *Buffer1, + IN VOID *Buffer2 + ); + +// +// Duplicated from EDKII BaseSortLib for qsort() wrapper +// +STATIC +VOID +QuickSortWorker ( + IN OUT VOID *BufferToSort, + IN CONST UINTN Count, + IN CONST UINTN ElementSize, + IN SORT_COMPARE CompareFunction, + IN VOID *Buffer + ) +{ + VOID *Pivot; + UINTN LoopCount; + UINTN NextSwapLocation; + + ASSERT(BufferToSort != NULL); + ASSERT(CompareFunction != NULL); + ASSERT(Buffer != NULL); + + if (Count < 2 || ElementSize < 1) { + return; + } + + NextSwapLocation = 0; + + // + // Pick a pivot (we choose last element) + // + Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize)); + + // + // Now get the pivot such that all on "left" are below it + // and everything "right" are above it + // + for (LoopCount = 0; LoopCount < Count - 1; LoopCount++) + { + // + // If the element is less than the pivot + // + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) { + // + // Swap + // + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize); + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) * ElementSize), ElementSize); + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize); + + // + // Increment NextSwapLocation + // + NextSwapLocation++; + } + } + // + // Swap pivot to it's final position (NextSwapLocaiton) + // + CopyMem (Buffer, Pivot, ElementSize); + CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize); + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize); + + // + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot' element. + // IE list is sorted left half, pivot element, sorted right half... + // + QuickSortWorker ( + BufferToSort, + NextSwapLocation, + ElementSize, + CompareFunction, + Buffer + ); + + QuickSortWorker ( + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize, + Count - NextSwapLocation - 1, + ElementSize, + CompareFunction, + Buffer + ); + + return; +} + +//--------------------------------------------------------- +// Standard C Run-time Library Interface Wrapper +//--------------------------------------------------------- + +// +// -- String Manipulation Routines -- +// + +/* Scan a string for the last occurrence of a character */ +char *strrchr (const char *str, int c) +{ + char * save; + + for (save = NULL; ; ++str) { + if (*str == c) { + save = (char *)str; + } + if (*str == 0) { + return (save); + } + } +} + +/* Read formatted data from a string */ +int sscanf (const char *buffer, const char *format, ...) +{ + // + // Null sscanf() function implementation to satisfy the linker, since + // no direct functionality logic dependency in present UEFI cases. + // + return 0; +} + +// +// -- Character Classification Routines -- +// + +/* Determines if a particular character is a decimal-digit character */ +int isdigit (int c) +{ + // + // ::= [0-9] + // + return (('0' <= (c)) && ((c) <= '9')); +} + +/* Determine if an integer represents character that is a hex digit */ +int isxdigit (int c) +{ + // + // ::= [0-9] | [a-f] | [A-F] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (('a' <= (c)) && ((c) <= 'f')) || + (('A' <= (c)) && ((c) <= 'F'))); +} + +/* Determines if a particular character represents a space character */ +int isspace (int c) +{ + // + // ::= [ ] + // + return ((c) == ' '); +} + +/* Determine if a particular character is an alphanumeric character */ +int isalnum (int c) +{ + // + // ::= [0-9] | [a-z] | [A-Z] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (('a' <= (c)) && ((c) <= 'z')) || + (('A' <= (c)) && ((c) <= 'Z'))); +} + +/* Determines if a particular character is in upper case */ +int isupper (int c) +{ + // + // := [A-Z] + // + return (('A' <= (c)) && ((c) <= 'Z')); +} + +// +// -- Data Conversion Routines -- +// + +/* Convert strings to a long-integer value */ +long strtol (const char *nptr, char **endptr, int base) +{ + // + // Null strtol() function implementation to satisfy the linker, since there is + // no direct functionality logic dependency in present UEFI cases. + // + return 0; +} + +/* Convert strings to an unsigned long-integer value */ +unsigned long strtoul (const char *nptr, char **endptr, int base) +{ + // + // Null strtoul() function implementation to satisfy the linker, since there is + // no direct functionality logic dependency in present UEFI cases. + // + return 0; +} + +/* Convert character to lowercase */ +int tolower (int c) +{ + if (('A' <= (c)) && ((c) <= 'Z')) { + return (c - ('A' - 'a')); + } + return (c); +} + +// +// -- Searching and Sorting Routines -- +// + +/* Performs a quick sort */ +void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *)) +{ + VOID *Buffer; + + ASSERT (base != NULL); + ASSERT (compare != NULL); + + Buffer = AllocatePool (width); + ASSERT (Buffer != NULL); + + // + // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib. + // + QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer); + + FreePool (Buffer); + return; +} + +// +// -- Process and Environment Control Routines -- +// + +/* Get a value from the current environment */ +char *getenv (const char *varname) +{ + // + // Null getenv() function implementation to satisfy the linker, since there is + // no direct functionality logic dependency in present UEFI cases. + // + return NULL; +} + +// +// -- Stream I/O Routines -- +// + +/* Write formatted output using a pointer to a list of arguments */ +int vfprintf (FILE *stream, const char *format, VA_LIST arg) +{ + return 0; +} + +/* Write data to a stream */ +size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream) +{ + return 0; +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/HelperWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/HelperWrapper.c new file mode 100644 index 0000000000..bf4399ca08 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/HelperWrapper.c @@ -0,0 +1,54 @@ +/** @file + Wrapper Implementation of Helper Routines produced by the C Compiler + for the OpenSSL-based Cryptographic Library. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +//--------------------------------------------------------- +// Helper Routines Wrapper +//--------------------------------------------------------- + +/* Divides a 64-bit signed value with a 64-bit signed value and returns + a 64-bit signed quotient and reminder */ +void _aulldvrm () +{ + // + // Null _aulldvrm() Math function implementation to satisfy the linker, since + // there is no direct functionality logic dependency in present UEFI cases. + // + return; +} + + +/* Converts a scalar double-precision floating point value to a 32-bit integer */ +long _ftol2_sse (double dblSource) +{ + // + // OpenSSL uses this function due to using floating-point inside it. + // It is only present in 32-bit versions of the compiler. + // Null _ftol2_sse() function implementation to satisfy the linker, since + // there is no direct functionality logic dependency in present UEFI cases. + // + return 0; +} + +/* Converts a scalar double-precision floating point value to a 32-bit integer */ +long _ftol2 (double dblSource) +{ + // + // Null _ftol2() function implementation to satisfy the linker, since + // there is no direct functionality logic dependency in present UEFI cases. + // + return 0; +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S new file mode 100644 index 0000000000..8496833ac8 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S @@ -0,0 +1,59 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# Alloca.S +# +# Abstract: +# +# Implementation for allocation of automatically reclaimed memory, which is +# used to allocate space off the runtime stack. +# (NOTE: There is a assumption in this code that the page size equal to 4K) +# +#------------------------------------------------------------------------------ + + + .686: + .code: + +ASM_GLOBAL ASM_PFX(_alloca) + +#------------------------------------------------------------------------------ +# +# void __cdecl _alloca (unsigned size) +# +#------------------------------------------------------------------------------ +ASM_PFX(_alloca): + + pushl %ecx + cmpl $0x1000, %eax + leal 8(%esp), %ecx + jb LastPage + +ProbePages: + subl $0x1000, %ecx + subl $0x1000, %eax + testl %eax, 0(%ecx) + cmpl $0x1000, %eax + jae ProbePages + +LastPage: + subl %eax, %ecx + movl %esp, %eax + testl %eax, 0(%ecx) + + movl %ecx, %esp + movl 0(%eax), %ecx + movl 4(%eax), %eax + pushl %eax + + ret diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.S new file mode 100644 index 0000000000..f46d5b84f4 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.S @@ -0,0 +1,83 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# MathDivU64x64.S +# +# Abstract: +# +# 64-bit Math Worker Function. +# Divides a 64-bit unsigned value with a 64-bit unsigned value and returns +# a 64-bit unsigned result. +# +#------------------------------------------------------------------------------ + + .686: + .code: + +ASM_GLOBAL ASM_PFX(__udivdi3), ASM_PFX(DivU64x64Remainder) + +#------------------------------------------------------------------------------ +# +# void __cdecl __udivdi3 (void) +# +#------------------------------------------------------------------------------ +ASM_PFX(__udivdi3): + # Original local stack when calling __udivdi3 + # ----------------- + # | | + # |---------------| + # | | + # |-- Divisor --| + # | | + # |---------------| + # | | + # |-- Dividend --| + # | | + # |---------------| + # | ReturnAddr** | + # ESP---->|---------------| + # + + # + # Set up the local stack for NULL Reminder pointer + # + xorl %eax, %eax + push %eax + + # + # Set up the local stack for Divisor parameter + # + movl 20(%esp), %eax + push %eax + movl 20(%esp), %eax + push %eax + + # + # Set up the local stack for Dividend parameter + # + movl 20(%esp), %eax + push %eax + movl 20(%esp), %eax + push %eax + + # + # Call native DivU64x64Remainder of BaseLib + # + jmp ASM_PFX(DivU64x64Remainder) + + # + # Adjust stack + # + addl $20, %esp + + ret $16 diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.c b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.c new file mode 100644 index 0000000000..4011653ae5 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathDivU64x64.c @@ -0,0 +1,88 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/* + * Divides a 64-bit unsigned value with a 64-bit unsigned value and returns + * a 64-bit unsigned result. + */ +__declspec(naked) void __cdecl _aulldiv (void) +{ + // + // Wrapper Implementation over EDKII DivU64x64Reminder() routine + // UINT64 + // EFIAPI + // DivU64x64Remainder ( + // IN UINT64 Dividend, + // IN UINT64 Divisor, + // OUT UINT64 *Remainder OPTIONAL + // ) + // + _asm { + + ; Original local stack when calling _aulldiv + ; ----------------- + ; | | + ; |---------------| + ; | | + ; |-- Divisor --| + ; | | + ; |---------------| + ; | | + ; |-- Dividend --| + ; | | + ; |---------------| + ; | ReturnAddr** | + ; ESP---->|---------------| + ; + + ; + ; Set up the local stack for NULL Reminder pointer + ; + xor eax, eax + push eax + + ; + ; Set up the local stack for Divisor parameter + ; + mov eax, [esp + 20] + push eax + mov eax, [esp + 20] + push eax + + ; + ; Set up the local stack for Dividend parameter + ; + mov eax, [esp + 20] + push eax + mov eax, [esp + 20] + push eax + + ; + ; Call native DivU64x64Remainder of BaseLib + ; + call DivU64x64Remainder + + ; + ; Adjust stack + ; + add esp, 20 + + ret 16 + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.S new file mode 100644 index 0000000000..e89f553a08 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.S @@ -0,0 +1,62 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# MathLShiftS64.S +# +# Abstract: +# +# 64-bit Math Worker Function. +# Shifts a 64-bit signed value left by a certain number of bits. +# +#------------------------------------------------------------------------------ + + .686: + .code: + +ASM_GLOBAL ASM_PFX(__ashldi3) + +#------------------------------------------------------------------------------ +# +# void __cdecl __ashldi3 (void) +# +#------------------------------------------------------------------------------ +ASM_PFX(__ashldi3): + # + # Handle shifting of 64 or more bits (return 0) + # + cmpb $64, %cl + jae ReturnZero + + # + # Handle shifting of between 0 and 31 bits + # + cmpb $32, %cl + jae More32 + shld %cl, %eax, %edx + shl %cl, %eax + ret + + # + # Handle shifting of between 32 and 63 bits + # +More32: + movl %eax, %edx + xor %eax, %eax + and $31, %cl + shl %cl, %edx + ret + +ReturnZero: + xor %eax, %eax + xor %edx, %edx + ret diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.c b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.c new file mode 100644 index 0000000000..2ea628a007 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathLShiftS64.c @@ -0,0 +1,54 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +/* + * Shifts a 64-bit signed value left by a particular number of bits. + */ +__declspec(naked) void __cdecl _allshl (void) +{ + _asm { + ; + ; Handle shifting of 64 or more bits (return 0) + ; + cmp cl, 64 + jae short ReturnZero + + ; + ; Handle shifting of between 0 and 31 bits + ; + cmp cl, 32 + jae short More32 + shld edx, eax, cl + shl eax, cl + ret + + ; + ; Handle shifting of between 32 and 63 bits + ; +More32: + mov edx, eax + xor eax, eax + and cl, 31 + shl edx, cl + ret + +ReturnZero: + xor eax,eax + xor edx,edx + ret + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.S new file mode 100644 index 0000000000..8a5f330e45 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.S @@ -0,0 +1,77 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# MathMultS64x64.S +# +# Abstract: +# +# 64-bit Math Worker Function. +# Multiplies a 64-bit signed or unsigned value by a 64-bit signed or unsigned value +# and returns a 64-bit result +# +#------------------------------------------------------------------------------ + + .686: + .code: + +ASM_GLOBAL ASM_PFX(_mulll), ASM_PFX(MultS64x64) + +#------------------------------------------------------------------------------ +# +# void __cdecl __mulll (void) +# +#------------------------------------------------------------------------------ +ASM_PFX(__mulll): + # Original local stack when calling __mulll + # ----------------- + # | | + # |---------------| + # | | + # |--Multiplier --| + # | | + # |---------------| + # | | + # |--Multiplicand-| + # | | + # |---------------| + # | ReturnAddr** | + # ESP---->|---------------| + # + + # + # Set up the local stack for Multiplicand parameter + # + movl 16(%esp), %eax + push %eax + movl 16(%esp), %eax + push %eax + + # + # Set up the local stack for Multiplier parameter + # + movl 16(%esp), %eax + push %eax + movl 16(%esp), %eax + push %eax + + # + # Call native MulS64x64 of BaseLib + # + jmp ASM_PFX(MultS64x64) + + # + # Adjust stack + # + add $16, %esp + + ret $16 diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.c b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.c new file mode 100644 index 0000000000..17a20bf629 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathMultS64x64.c @@ -0,0 +1,79 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +/* + * Multiplies a 64-bit signed or unsigned value by a 64-bit signed or unsigned value + * and returns a 64-bit result. + */ +__declspec(naked) void __cdecl _allmul (void) +{ + // + // Wrapper Implementation over EDKII MultS64x64() routine + // INT64 + // EFIAPI + // MultS64x64 ( + // IN INT64 Multiplicand, + // IN INT64 Multiplier + // ) + // + _asm { + ; Original local stack when calling _allmul + ; ----------------- + ; | | + ; |---------------| + ; | | + ; |--Multiplier --| + ; | | + ; |---------------| + ; | | + ; |--Multiplicand-| + ; | | + ; |---------------| + ; | ReturnAddr** | + ; ESP---->|---------------| + ; + + ; + ; Set up the local stack for Multiplicand parameter + ; + mov eax, [esp + 16] + push eax + mov eax, [esp + 16] + push eax + + ; + ; Set up the local stack for Multiplier parameter + ; + mov eax, [esp + 16] + push eax + mov eax, [esp + 16] + push eax + + ; + ; Call native MulS64x64 of BaseLib + ; + call MultS64x64 + + ; + ; Adjust stack + ; + add esp, 16 + + ret 16 + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S new file mode 100644 index 0000000000..3a8a132564 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S @@ -0,0 +1,66 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# MathRShiftU64.S +# +# Abstract: +# +# 64-bit Math Worker Function. +# Shifts a 64-bit unsigned value right by a certain number of bits. +# +#------------------------------------------------------------------------------ + + + .686: + .code: + +ASM_GLOBAL ASM_PFX(__ashrdi3) + +#------------------------------------------------------------------------------ +# +# void __cdecl __ashrdi3 (void) +# +#------------------------------------------------------------------------------ +ASM_PFX(__ashrdi3): + # + # Checking: Only handle 64bit shifting or more + # + cmpb $64, %cl + jae _Exit + + # + # Handle shifting between 0 and 31 bits + # + cmpb $32, %cl + jae More32 + shrd %cl, %edx, %eax + shr %cl, %edx + ret + + # + # Handle shifting of 32-63 bits + # +More32: + movl %edx, %eax + xor %edx, %edx + and $32, %cl + shr %cl, %eax + ret + + # + # Invalid number (less then 32bits), return 0 + # +_Exit: + xor %eax, %eax + xor %edx, %edx + ret diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.c b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.c new file mode 100644 index 0000000000..b7224d6455 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.c @@ -0,0 +1,57 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +/* + * Shifts a 64-bit unsigned value right by a certain number of bits. + */ +__declspec(naked) void __cdecl _aullshr (void) +{ + _asm { + ; + ; Checking: Only handle 64bit shifting or more + ; + cmp cl, 64 + jae _Exit + + ; + ; Handle shifting between 0 and 31 bits + ; + cmp cl, 32 + jae More32 + shrd eax, edx, cl + shr edx, cl + ret + + ; + ; Handle shifting of 32-63 bits + ; +More32: + mov eax, edx + xor edx, edx + and cl, 31 + shr eax, cl + ret + + ; + ; Invalid number (less then 32bits), return 0 + ; +_Exit: + xor eax, eax + xor edx, edx + ret + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.S new file mode 100644 index 0000000000..7c1f971644 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.S @@ -0,0 +1,89 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# MathReminderU64x64.S +# +# Abstract: +# +# 64-bit Math Worker Function. +# Divides a 64-bit unsigned value by another 64-bit unsigned value and returns +# the 64-bit unsigned remainder +# +#------------------------------------------------------------------------------ + + .686: + .code: + +ASM_GLOBAL ASM_PFX(__umoddi3), ASM_PFX(DivU64x64Remainder) + +#------------------------------------------------------------------------------ +# +# void __cdecl __umoddi3 (void) +# +#------------------------------------------------------------------------------ +ASM_PFX(__umoddi3): + # Original local stack when calling __umoddi3 + # ----------------- + # | | + # |---------------| + # | | + # |-- Divisor --| + # | | + # |---------------| + # | | + # |-- Dividend --| + # | | + # |---------------| + # | ReturnAddr** | + # ESP---->|---------------| + # + + # + # Set up the local stack for Reminder pointer + # + sub $8, %esp + push %esp + + # + # Set up the local stack for Divisor parameter + # + movl 28(%esp), %eax + push %eax + movl 28(%esp), %eax + push %eax + + # + # Set up the local stack for Dividend parameter + # + movl 28(%esp), %eax + push %eax + movl 28(%esp), %eax + push %eax + + # + # Call native DivU64x64Remainder of BaseLib + # + jmp ASM_PFX(DivU64x64Remainder) + + # + # Put the Reminder in EDX:EAX as return value + # + movl 20(%esp), %eax + movl 24(%esp), %edx + + # + # Adjust stack + # + add $28, %esp + + ret $16 diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.c b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.c new file mode 100644 index 0000000000..be70770ebb --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathReminderU64x64.c @@ -0,0 +1,93 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/* + * Divides a 64-bit unsigned value by another 64-bit unsigned value and returns + * the 64-bit unsigned remainder. + */ +__declspec(naked) void __cdecl _aullrem(void) +{ + // + // Wrapper Implementation over EDKII DivU64x64Remainder() routine + // UINT64 + // EFIAPI + // DivU64x64Remainder ( + // IN UINT64 Dividend, + // IN UINT64 Divisor, + // OUT UINT64 *Remainder OPTIONAL + // ) + // + _asm { + ; Original local stack when calling _aullrem + ; ----------------- + ; | | + ; |---------------| + ; | | + ; |-- Divisor --| + ; | | + ; |---------------| + ; | | + ; |-- Dividend --| + ; | | + ; |---------------| + ; | ReturnAddr** | + ; ESP---->|---------------| + ; + + ; + ; Set up the local stack for Reminder pointer + ; + sub esp, 8 + push esp + + ; + ; Set up the local stack for Divisor parameter + ; + mov eax, [esp + 28] + push eax + mov eax, [esp + 28] + push eax + + ; + ; Set up the local stack for Dividend parameter + ; + mov eax, [esp + 28] + push eax + mov eax, [esp + 28] + push eax + + ; + ; Call native DivU64x64Remainder of BaseLib + ; + call DivU64x64Remainder + + ; + ; Put the Reminder in EDX:EAX as return value + ; + mov eax, [esp + 20] + mov edx, [esp + 24] + + ; + ; Adjust stack + ; + add esp, 28 + + ret 16 + } +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c b/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c new file mode 100644 index 0000000000..f615ae8f90 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c @@ -0,0 +1,438 @@ +/** @file + Light-weight Memory Management Routines for OpenSSL-based Crypto + Library at Runtime Phase. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include + +//---------------------------------------------------------------- +// Initial version. Needs further optimizations. +//---------------------------------------------------------------- + +// +// Definitions for Runtime Memory Operations +// +#define RT_PAGE_SIZE 0x200 +#define RT_PAGE_MASK 0x1FF +#define RT_PAGE_SHIFT 9 + +#define RT_SIZE_TO_PAGES(a) (((a) >> RT_PAGE_SHIFT) + (((a) & RT_PAGE_MASK) ? 1 : 0)) +#define RT_PAGES_TO_SIZE(a) ((a) << RT_PAGE_SHIFT) + +// +// Page Flag Definitions +// +#define RT_PAGE_FREE 0x00000000 +#define RT_PAGE_USED 0x00000001 + +#define MIN_REQUIRED_BLOCKS 24 + +// +// Memory Page Table +// +typedef struct { + UINTN StartPageOffset; // Offset of the starting page allocated. + // Only available for USED pages. + UINT32 PageFlag; // Page Attributes. +} RT_MEMORY_PAGE_ENTRY; + +typedef struct { + UINTN PageCount; + UINTN LastEmptyPageOffset; + UINT8 *DataAreaBase; // Pointer to data Area. + RT_MEMORY_PAGE_ENTRY Pages[1]; // Page Table Entries. +} RT_MEMORY_PAGE_TABLE; + +// +// Global Page Table for Runtime Cryptographic Provider. +// +RT_MEMORY_PAGE_TABLE *mRTPageTable = NULL; + +// +// Event for Runtime Address Conversion. +// +EFI_EVENT mVirtualAddressChangeEvent; + + +/** + Initializes pre-allocated memory pointed by ScratchBuffer for subsequent + runtime use. + + @param[in, out] ScratchBuffer Pointer to user-supplied memory buffer. + @param[in] ScratchBufferSize Size of supplied buffer in bytes. + + @retval EFI_SUCCESS Successful initialization. + +**/ +EFI_STATUS +InitializeScratchMemory ( + IN OUT UINT8 *ScratchBuffer, + IN UINTN ScratchBufferSize + ) +{ + UINTN Index; + UINTN MemorySize; + + // + // Parameters Checking + // + if (ScratchBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (ScratchBufferSize < MIN_REQUIRED_BLOCKS * 1024) { + return EFI_BUFFER_TOO_SMALL; + } + + mRTPageTable = (RT_MEMORY_PAGE_TABLE *)ScratchBuffer; + + // + // Initialize Internal Page Table for Memory Management + // + SetMem (mRTPageTable, ScratchBufferSize, 0xFF); + MemorySize = ScratchBufferSize - sizeof (RT_MEMORY_PAGE_TABLE) + sizeof (RT_MEMORY_PAGE_ENTRY); + + mRTPageTable->PageCount = MemorySize / (RT_PAGE_SIZE + sizeof (RT_MEMORY_PAGE_ENTRY)); + mRTPageTable->LastEmptyPageOffset = 0x0; + + for (Index = 0; Index < mRTPageTable->PageCount; Index++) { + mRTPageTable->Pages[Index].PageFlag = RT_PAGE_FREE; + mRTPageTable->Pages[Index].StartPageOffset = 0; + } + + mRTPageTable->DataAreaBase = ScratchBuffer + sizeof (RT_MEMORY_PAGE_TABLE) + + (mRTPageTable->PageCount - 1) * sizeof (RT_MEMORY_PAGE_ENTRY); + + return EFI_SUCCESS; +} + + +/** + Look-up Free memory Region for object allocation. + + @param[in] AllocationSize Bytes to be allocated. + + @return Return available page offset for object allocation. + +**/ +UINTN +LookupFreeMemRegion ( + IN UINTN AllocationSize + ) +{ + UINTN StartPageIndex; + UINTN Index; + UINTN SubIndex; + UINTN ReqPages; + + StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->LastEmptyPageOffset); + ReqPages = RT_SIZE_TO_PAGES (AllocationSize); + + // + // Look up the free memory region with in current memory map table. + // + for (Index = StartPageIndex; Index <= (mRTPageTable->PageCount - ReqPages); ) { + // + // Check consecutive ReqPages pages. + // + for (SubIndex = 0; SubIndex < ReqPages; SubIndex++) { + if ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) { + break; + } + } + + if (SubIndex == ReqPages) { + // + // Succeed! Return the Starting Offset. + // + return RT_PAGES_TO_SIZE (Index); + } + + // + // Failed! Skip current free memory pages and adjacent Used pages + // + while ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) { + SubIndex++; + } + + Index += SubIndex; + } + + // + // Look up the free memory region from the beginning of the memory table + // until the StartCursorOffset + // + for (Index = 0; Index < (StartPageIndex - ReqPages); ) { + // + // Check Consecutive ReqPages Pages. + // + for (SubIndex = 0; SubIndex < ReqPages; SubIndex++) { + if ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) { + break; + } + } + + if (SubIndex == ReqPages) { + // + // Succeed! Return the Starting Offset. + // + return RT_PAGES_TO_SIZE (Index); + } + + // + // Failed! Skip current adjacent Used pages + // + while ((SubIndex < (StartPageIndex - ReqPages)) && + ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0)) { + SubIndex++; + } + + Index += SubIndex; + } + + // + // No availabe region for object allocation! + // + return (UINTN)(-1); +} + + +/** + Allocates a buffer at runtime phase. + + @param[in] AllocationSize Bytes to be allocated. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +RuntimeAllocateMem ( + IN UINTN AllocationSize + ) +{ + UINT8 *AllocPtr; + UINTN ReqPages; + UINTN Index; + UINTN StartPage; + UINTN AllocOffset; + + AllocPtr = NULL; + ReqPages = 0; + + // + // Look for available consecutive memory region starting from LastEmptyPageOffset. + // If no proper memory region found, look up from the beginning. + // If still not found, return NULL to indicate failed allocation. + // + AllocOffset = LookupFreeMemRegion (AllocationSize); + if (AllocOffset == (UINTN)(-1)) { + return NULL; + } + + // + // Allocates consecutive memory pages with length of Size. Update the page + // table status. Returns the starting address. + // + ReqPages = RT_SIZE_TO_PAGES (AllocationSize); + AllocPtr = mRTPageTable->DataAreaBase + AllocOffset; + StartPage = RT_SIZE_TO_PAGES (AllocOffset); + Index = 0; + while (Index < ReqPages) { + mRTPageTable->Pages[StartPage + Index].PageFlag |= RT_PAGE_USED; + mRTPageTable->Pages[StartPage + Index].StartPageOffset = AllocOffset; + + Index++; + } + + mRTPageTable->LastEmptyPageOffset = AllocOffset + RT_PAGES_TO_SIZE (ReqPages); + + ZeroMem (AllocPtr, AllocationSize); + + // + // Returns a void pointer to the allocated space + // + return AllocPtr; +} + + +/** + Frees a buffer that was previously allocated at runtime phase. + + @param[in] Buffer Pointer to the buffer to free. + +**/ +VOID +RuntimeFreeMem ( + IN VOID *Buffer + ) +{ + UINTN StartOffset; + UINTN StartPageIndex; + + StartOffset = (UINTN) ((UINT8 *)Buffer - mRTPageTable->DataAreaBase); + StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->Pages[RT_SIZE_TO_PAGES(StartOffset)].StartPageOffset); + + while (StartPageIndex < mRTPageTable->PageCount) { + if (((mRTPageTable->Pages[StartPageIndex].PageFlag & RT_PAGE_USED) != 0) && + (mRTPageTable->Pages[StartPageIndex].StartPageOffset == StartOffset)) { + // + // Free this page + // + mRTPageTable->Pages[StartPageIndex].PageFlag &= ~RT_PAGE_USED; + mRTPageTable->Pages[StartPageIndex].PageFlag |= RT_PAGE_FREE; + mRTPageTable->Pages[StartPageIndex].StartPageOffset = 0; + + StartPageIndex++; + } else { + break; + } + } + + return; +} + + +/** + Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. + + This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE + event. It converts a pointer to a new virtual address. + + @param[in] Event The event whose notification function is being invoked. + @param[in] Context The pointer to the notification function's context. + +**/ +VOID +EFIAPI +RuntimeCryptLibAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Converts a pointer for runtime memory management to a new virtual address. + // + EfiConvertPointer (0x0, (VOID **) &mRTPageTable->DataAreaBase); + EfiConvertPointer (0x0, (VOID **) &mRTPageTable); +} + + +/** + Constructor routine for runtime crypt library instance. + + The constructor function pre-allocates space for runtime cryptographic operation. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The construction succeeded. + @retval EFI_OUT_OF_RESOURCE Failed to allocate memory. + +**/ +EFI_STATUS +EFIAPI +RuntimeCryptLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + // + // Pre-allocates runtime space for possible cryptographic operations + // + Buffer = AllocateRuntimePool (MIN_REQUIRED_BLOCKS * 1024); + Status = InitializeScratchMemory (Buffer, MIN_REQUIRED_BLOCKS * 1024); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Create address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + RuntimeCryptLibAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mVirtualAddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +// +// -- Memory-Allocation Routines Wrapper for UEFI-OpenSSL Library -- +// + +/* Allocates memory blocks */ +void *malloc (size_t size) +{ + return RuntimeAllocateMem ((UINTN)size); +} + +/* Reallocate memory blocks */ +void *realloc (void *ptr, size_t size) +{ + VOID *NewPtr; + UINTN StartOffset; + UINTN StartPageIndex; + UINTN PageCount; + + // + // Get Original Size of ptr + // + StartOffset = (UINTN) ((UINT8 *)ptr - mRTPageTable->DataAreaBase); + StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->Pages[RT_SIZE_TO_PAGES (StartOffset)].StartPageOffset); + PageCount = 0; + while (StartPageIndex < mRTPageTable->PageCount) { + if (((mRTPageTable->Pages[StartPageIndex].PageFlag & RT_PAGE_USED) != 0) && + (mRTPageTable->Pages[StartPageIndex].StartPageOffset == StartOffset)) { + StartPageIndex++; + PageCount++; + } else { + break; + } + } + + if (size <= RT_PAGES_TO_SIZE (PageCount)) { + // + // Return the original pointer, if Caller try to reduce region size; + // + return ptr; + } + + NewPtr = RuntimeAllocateMem ((UINTN) size); + if (NewPtr == NULL) { + return NULL; + } + + CopyMem (NewPtr, ptr, RT_PAGES_TO_SIZE (PageCount)); + + RuntimeFreeMem (ptr); + + return NewPtr; +} + +/* Deallocates or frees a memory block */ +void free (void *ptr) +{ + RuntimeFreeMem (ptr); +} diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c new file mode 100644 index 0000000000..20928e1595 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c @@ -0,0 +1,102 @@ +/** @file + C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation + for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME). + +Copyright (c) 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +// +// -- Time Management Routines -- +// + +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR (60 * 60) +#define SECSPERDAY (24 * SECSPERHOUR) + +// +// The arrays give the cumulative number of days up to the first of the +// month number used as the index (1 -> 12) for regular and leap years. +// The value at index 13 is for the whole year. +// +UINTN CumulativeDays[2][14] = { + { + 0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + }, + { + 0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + } +}; + +/* Get the system time as seconds elapsed since midnight, January 1, 1970. */ +//INTN time( +// INTN *timer +// ) +time_t time (time_t *timer) +{ + EFI_TIME Time; + UINTN Year; + + // + // Get the current time and date information + // + gRT->GetTime (&Time, NULL); + + // + // Years Handling + // UTime should now be set to 00:00:00 on Jan 1 of the current year. + // + for (Year = 1970, *timer = 0; Year != Time.Year; Year++) { + *timer = *timer + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY); + } + + // + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment + // + *timer = *timer + + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) + + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) + + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) + + (time_t)(Time.Hour * SECSPERHOUR) + + (time_t)(Time.Minute * 60) + + (time_t)Time.Second; + + return *timer; +} -- cgit v1.2.3