From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../BaseCryptLib/SysCall/BaseMemAllocation.c | 112 +++++ .../BaseCryptLib/SysCall/ConstantTimeClock.c | 37 ++ .../Library/BaseCryptLib/SysCall/CrtWrapper.c | 473 +++++++++++++++++++++ .../BaseCryptLib/SysCall/RuntimeMemAllocation.c | 455 ++++++++++++++++++++ .../Library/BaseCryptLib/SysCall/TimerWrapper.c | 168 ++++++++ .../Library/BaseCryptLib/SysCall/inet_pton.c | 257 +++++++++++ 6 files changed, 1502 insertions(+) create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c create mode 100644 roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/inet_pton.c (limited to 'roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall') diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c new file mode 100644 index 000000000..d14644d13 --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c @@ -0,0 +1,112 @@ +/** @file + Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL + during PEI & DXE phases. + +Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +// +// Extra header to record the memory buffer size from malloc routine. +// +#define CRYPTMEM_HEAD_SIGNATURE SIGNATURE_32('c','m','h','d') +typedef struct { + UINT32 Signature; + UINT32 Reserved; + UINTN Size; +} CRYPTMEM_HEAD; + +#define CRYPTMEM_OVERHEAD sizeof(CRYPTMEM_HEAD) + +// +// -- Memory-Allocation Routines -- +// + +/* Allocates memory blocks */ +void *malloc (size_t size) +{ + CRYPTMEM_HEAD *PoolHdr; + UINTN NewSize; + VOID *Data; + + // + // Adjust the size by the buffer header overhead + // + NewSize = (UINTN)(size) + CRYPTMEM_OVERHEAD; + + Data = AllocatePool (NewSize); + if (Data != NULL) { + PoolHdr = (CRYPTMEM_HEAD *)Data; + // + // Record the memory brief information + // + PoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE; + PoolHdr->Size = size; + + return (VOID *)(PoolHdr + 1); + } else { + // + // The buffer allocation failed. + // + return NULL; + } +} + +/* Reallocate memory blocks */ +void *realloc (void *ptr, size_t size) +{ + CRYPTMEM_HEAD *OldPoolHdr; + CRYPTMEM_HEAD *NewPoolHdr; + UINTN OldSize; + UINTN NewSize; + VOID *Data; + + NewSize = (UINTN)size + CRYPTMEM_OVERHEAD; + Data = AllocatePool (NewSize); + if (Data != NULL) { + NewPoolHdr = (CRYPTMEM_HEAD *)Data; + NewPoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE; + NewPoolHdr->Size = size; + if (ptr != NULL) { + // + // Retrieve the original size from the buffer header. + // + OldPoolHdr = (CRYPTMEM_HEAD *)ptr - 1; + ASSERT (OldPoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE); + OldSize = OldPoolHdr->Size; + + // + // Duplicate the buffer content. + // + CopyMem ((VOID *)(NewPoolHdr + 1), ptr, MIN (OldSize, size)); + FreePool ((VOID *)OldPoolHdr); + } + + return (VOID *)(NewPoolHdr + 1); + } else { + // + // The buffer allocation failed. + // + return NULL; + } +} + +/* De-allocates or frees a memory block */ +void free (void *ptr) +{ + CRYPTMEM_HEAD *PoolHdr; + + // + // In Standard C, free() handles a null pointer argument transparently. This + // is not true of FreePool() below, so protect it. + // + if (ptr != NULL) { + PoolHdr = (CRYPTMEM_HEAD *)ptr - 1; + ASSERT (PoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE); + FreePool (PoolHdr); + } +} diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c new file mode 100644 index 000000000..18b04f2af --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c @@ -0,0 +1,37 @@ +/** @file + C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation + for OpenSSL-based Cryptographic Library. + + This C file implements constant time value for time() and NULL for gmtime() + thus should not be used in library instances which require functionality + of following APIs which need system time support: + 1) RsaGenerateKey + 2) RsaCheckKey + 3) RsaPkcs1Sign + 4) Pkcs7Sign + 5) DhGenerateParameter + 6) DhGenerateKey + +Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +// +// -- Time Management Routines -- +// + +time_t time (time_t *timer) +{ + if (timer != NULL) { + *timer = 0; + } + return 0; +} + +struct tm * gmtime (const time_t *timer) +{ + return NULL; +} diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c new file mode 100644 index 000000000..42235ab96 --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c @@ -0,0 +1,473 @@ +/** @file + C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based + Cryptographic Library. + +Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +int errno = 0; + +FILE *stderr = NULL; +FILE *stdin = NULL; +FILE *stdout = NULL; + +typedef +int +(*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 its final position (NextSwapLocation) + // + CopyMem (Buffer, Pivot, ElementSize); + CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize); + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize); + + // + // Now recurse on 2 partial 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 -- +// + +char *strchr(const char *str, int ch) +{ + return ScanMem8 (str, AsciiStrSize (str), (UINT8)ch); +} + +/* 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); + } + } +} + +/* Compare first n bytes of string s1 with string s2, ignoring case */ +int strncasecmp (const char *s1, const char *s2, size_t n) +{ + int Val; + + ASSERT(s1 != NULL); + ASSERT(s2 != NULL); + + if (n != 0) { + do { + Val = tolower(*s1) - tolower(*s2); + if (Val != 0) { + return Val; + } + ++s1; + ++s2; + if (*s1 == '\0') { + break; + } + } while (--n != 0); + } + return 0; +} + +/* 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; +} + +/* Maps errnum to an error-message string */ +char * strerror (int errnum) +{ + return NULL; +} + +/* Computes the length of the maximum initial segment of the string pointed to by s1 + which consists entirely of characters from the string pointed to by s2. */ +size_t strspn (const char *s1 , const char *s2) +{ + UINT8 Map[32]; + UINT32 Index; + size_t Count; + + for (Index = 0; Index < 32; Index++) { + Map[Index] = 0; + } + + while (*s2) { + Map[*s2 >> 3] |= (1 << (*s2 & 7)); + s2++; + } + + if (*s1) { + Count = 0; + while (Map[*s1 >> 3] & (1 << (*s1 & 7))) { + Count++; + s1++; + } + + return Count; + } + + return 0; +} + +/* Computes the length of the maximum initial segment of the string pointed to by s1 + which consists entirely of characters not from the string pointed to by s2. */ +size_t strcspn (const char *s1, const char *s2) +{ + UINT8 Map[32]; + UINT32 Index; + size_t Count; + + for (Index = 0; Index < 32; Index++) { + Map[Index] = 0; + } + + while (*s2) { + Map[*s2 >> 3] |= (1 << (*s2 & 7)); + s2++; + } + + Map[0] |= 1; + + Count = 0; + while (!(Map[*s1 >> 3] & (1 << (*s1 & 7)))) { + Count ++; + s1++; + } + + return Count; +} + +// +// -- 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); + + // + // Use CRT-style malloc to cover BS and RT memory allocation. + // + Buffer = malloc (width); + ASSERT (Buffer != NULL); + + // + // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib. + // + QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer); + + free (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; +} + +/* Get a value from the current environment */ +char *secure_getenv (const char *varname) +{ + // + // Null secure_getenv() function implementation to satisfy the linker, since + // there is no direct functionality logic dependency in present UEFI cases. + // + // From the secure_getenv() manual: 'just like getenv() except that it + // returns NULL in cases where "secure execution" is required'. + // + return NULL; +} + +// +// -- Stream I/O Routines -- +// + +/* Write data to a stream */ +size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream) +{ + return 0; +} + +// +// -- Dummy OpenSSL Support Routines -- +// + +int BIO_printf (void *bio, const char *format, ...) +{ + return 0; +} + +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +{ + return 0; +} + +#ifdef __GNUC__ + +typedef +VOID +(EFIAPI *NoReturnFuncPtr)( + VOID + ) __attribute__((__noreturn__)); + +STATIC +VOID +EFIAPI +NopFunction ( + VOID + ) +{ +} + +void abort (void) +{ + NoReturnFuncPtr NoReturnFunc; + + NoReturnFunc = (NoReturnFuncPtr) NopFunction; + + NoReturnFunc (); +} + +#else + +void abort (void) +{ + // Do nothing +} + +#endif + +int fclose (FILE *f) +{ + return 0; +} + +FILE *fopen (const char *c, const char *m) +{ + return NULL; +} + +size_t fread (void *b, size_t c, size_t i, FILE *f) +{ + return 0; +} + +uid_t getuid (void) +{ + return 0; +} + +uid_t geteuid (void) +{ + return 0; +} + +gid_t getgid (void) +{ + return 0; +} + +gid_t getegid (void) +{ + return 0; +} + +int printf (char const *fmt, ...) +{ + return 0; +} diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c new file mode 100644 index 000000000..3e12a0500 --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/RuntimeMemAllocation.c @@ -0,0 +1,455 @@ +/** @file + Light-weight Memory Management Routines for OpenSSL-based Crypto + Library at Runtime Phase. + +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#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 600 + +// +// 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. +// +STATIC 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); + if (ReqPages > mRTPageTable->PageCount) { + // + // No enough region for object allocation. + // + return (UINTN)(-1); + } + + // + // 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 + // + if (ReqPages > StartPageIndex) { + // + // No enough region for object allocation. + // + return (UINTN)(-1); + } + 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 available 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)Buffer - (UINTN)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; + + if (ptr == NULL) { + return malloc (size); + } + + // + // Get Original Size of ptr + // + StartOffset = (UINTN)ptr - (UINTN)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) +{ + // + // In Standard C, free() handles a null pointer argument transparently. This + // is not true of RuntimeFreeMem() below, so protect it. + // + if (ptr != NULL) { + RuntimeFreeMem (ptr); + } +} diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c new file mode 100644 index 000000000..027e5a942 --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c @@ -0,0 +1,168 @@ +/** @file + C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation + for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME). + +Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +// +// -- Time Management Routines -- +// + +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERMIN (60) +#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_STATUS Status; + EFI_TIME Time; + time_t CalTime; + UINTN Year; + + // + // Get the current time and date information + // + Status = gRT->GetTime (&Time, NULL); + if (EFI_ERROR (Status) || (Time.Year < 1970)) { + return 0; + } + + // + // Years Handling + // UTime should now be set to 00:00:00 on Jan 1 of the current year. + // + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) { + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY); + } + + // + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment + // + CalTime = CalTime + + (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; + + if (timer != NULL) { + *timer = CalTime; + } + + return CalTime; +} + +// +// Convert a time value from type time_t to struct tm. +// +struct tm * gmtime (const time_t *timer) +{ + struct tm *GmTime; + UINT16 DayNo; + UINT16 DayRemainder; + time_t Year; + time_t YearNo; + UINT16 TotalDays; + UINT16 MonthNo; + + if (timer == NULL) { + return NULL; + } + + GmTime = malloc (sizeof (struct tm)); + if (GmTime == NULL) { + return NULL; + } + + ZeroMem ((VOID *) GmTime, (UINTN) sizeof (struct tm)); + + DayNo = (UINT16) (*timer / SECSPERDAY); + DayRemainder = (UINT16) (*timer % SECSPERDAY); + + GmTime->tm_sec = (int) (DayRemainder % SECSPERMIN); + GmTime->tm_min = (int) ((DayRemainder % SECSPERHOUR) / SECSPERMIN); + GmTime->tm_hour = (int) (DayRemainder / SECSPERHOUR); + GmTime->tm_wday = (int) ((DayNo + 4) % 7); + + for (Year = 1970, YearNo = 0; DayNo > 0; Year++) { + TotalDays = (UINT16) (IsLeap (Year) ? 366 : 365); + if (DayNo >= TotalDays) { + DayNo = (UINT16) (DayNo - TotalDays); + YearNo++; + } else { + break; + } + } + + GmTime->tm_year = (int) (YearNo + (1970 - 1900)); + GmTime->tm_yday = (int) DayNo; + + for (MonthNo = 12; MonthNo > 1; MonthNo--) { + if (DayNo >= CumulativeDays[IsLeap(Year)][MonthNo]) { + DayNo = (UINT16) (DayNo - (UINT16) (CumulativeDays[IsLeap(Year)][MonthNo])); + break; + } + } + + GmTime->tm_mon = (int) MonthNo - 1; + GmTime->tm_mday = (int) DayNo + 1; + + GmTime->tm_isdst = 0; + GmTime->tm_gmtoff = 0; + GmTime->tm_zone = NULL; + + return GmTime; +} diff --git a/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/inet_pton.c b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/inet_pton.c new file mode 100644 index 000000000..32e1ab869 --- /dev/null +++ b/roms/edk2/CryptoPkg/Library/BaseCryptLib/SysCall/inet_pton.c @@ -0,0 +1,257 @@ +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2003/11/19 01:51:30 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4 (const char *src, u_char *dst); +static int inet_pton6 (const char *src, u_char *dst); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +inet_pton( + int af, + const char *src, + void *dst + ) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4( + const char *src, + u_char *dst + ) +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int new = *tp * 10 + (u_int)(pch - digits); + + if (new > 255) + return (0); + *tp = (u_char)new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6( + const char *src, + u_char *dst + ) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = (int)(tp - colonp); + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} -- cgit