parent
13535f2d48
commit
40090957c4
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="vmexit_handler.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="types.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <intrin.h>
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#include <cstddef>
|
||||||
|
#define PORT_NUM 0x2F8
|
||||||
|
#define DBG_PRINT(arg) \
|
||||||
|
__outbytestring(PORT_NUM, (unsigned char*)arg, sizeof arg);
|
||||||
|
|
||||||
|
typedef struct _context_t
|
||||||
|
{
|
||||||
|
uintptr_t rax;
|
||||||
|
uintptr_t rcx;
|
||||||
|
uintptr_t rdx;
|
||||||
|
uintptr_t rbx;
|
||||||
|
uintptr_t rsp;
|
||||||
|
uintptr_t rbp;
|
||||||
|
uintptr_t rsi;
|
||||||
|
uintptr_t rdi;
|
||||||
|
uintptr_t r8;
|
||||||
|
uintptr_t r9;
|
||||||
|
uintptr_t r10;
|
||||||
|
uintptr_t r11;
|
||||||
|
uintptr_t r12;
|
||||||
|
uintptr_t r13;
|
||||||
|
uintptr_t r14;
|
||||||
|
uintptr_t r15;
|
||||||
|
__m128 xmm0;
|
||||||
|
__m128 xmm1;
|
||||||
|
__m128 xmm2;
|
||||||
|
__m128 xmm3;
|
||||||
|
__m128 xmm4;
|
||||||
|
__m128 xmm5;
|
||||||
|
} context_t, *pcontext_t;
|
||||||
|
using vmexit_handler_t = void (__fastcall*)(pcontext_t* context, void* unknown1, void* unknown2, void* unknown3);
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct _VOYAGER_DATA_T
|
||||||
|
{
|
||||||
|
vmexit_handler_t vmexit_handler;
|
||||||
|
uintptr_t hyperv_module_base;
|
||||||
|
uintptr_t hyperv_module_size;
|
||||||
|
uintptr_t record_base;
|
||||||
|
uintptr_t record_size;
|
||||||
|
} VOYAGER_DATA_T, *PVOYAGER_DATA_T;
|
||||||
|
#pragma pack(pop)
|
||||||
|
__declspec(dllexport) inline PVOYAGER_DATA_T pvoyager_context = nullptr;
|
@ -0,0 +1,8 @@
|
|||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
void vmexit_handler(pcontext_t* context, void* unknown1, void* unknown2, void* unknown3)
|
||||||
|
{
|
||||||
|
DBG_PRINT("vmexit called....\n");
|
||||||
|
DBG_PRINT("calling original vmexit handler....\n");
|
||||||
|
pvoyager_context->vmexit_handler(context, unknown1, unknown2, unknown3);
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
#include "BootMgfw.h"
|
||||||
|
|
||||||
|
SHITHOOK BootMgfwShitHook;
|
||||||
|
EFI_DEVICE_PATH* EFIAPI GetBootMgfwPath(VOID)
|
||||||
|
{
|
||||||
|
UINTN HandleCount = NULL;
|
||||||
|
EFI_STATUS Result;
|
||||||
|
EFI_HANDLE* Handles = NULL;
|
||||||
|
EFI_DEVICE_PATH* DevicePath = NULL;
|
||||||
|
EFI_FILE_HANDLE VolumeHandle;
|
||||||
|
EFI_FILE_HANDLE BootMgfwHandle;
|
||||||
|
EFI_FILE_IO_INTERFACE* FileSystem = NULL;
|
||||||
|
|
||||||
|
// get all the handles to file systems...
|
||||||
|
if (EFI_ERROR((Result = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles))))
|
||||||
|
{
|
||||||
|
Print(L"error getting file system handles -> 0x%p\n", Result);
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for each handle to the file system, open a protocol with it...
|
||||||
|
for (UINT32 Idx = 0u; Idx < HandleCount && !FileSystem; ++Idx)
|
||||||
|
{
|
||||||
|
if (EFI_ERROR((Result = gBS->OpenProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, (VOID**)&FileSystem, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))
|
||||||
|
{
|
||||||
|
Print(L"error opening protocol -> 0x%p\n", Result);
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR((Result = FileSystem->OpenVolume(FileSystem, &VolumeHandle))))
|
||||||
|
{
|
||||||
|
Print(L"error opening file system -> 0x%p\n", Result);
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we found the correct file (\\efi\\microsoft\\boot\\bootmgfw.efi)
|
||||||
|
if (!EFI_ERROR(VolumeHandle->Open(VolumeHandle, &BootMgfwHandle, WINDOWS_BOOTMGR_PATH, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY)))
|
||||||
|
DevicePath = FileDevicePath(Handles[Idx], WINDOWS_BOOTMGR_PATH);
|
||||||
|
|
||||||
|
VolumeHandle->Close(BootMgfwHandle);
|
||||||
|
if (EFI_ERROR((Result = gBS->CloseProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, gImageHandle, NULL))))
|
||||||
|
{
|
||||||
|
Print(L"error closing protocol -> 0x%p\n", Result);
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI InstallBootMgfwHooks(EFI_HANDLE BootMgfwPath)
|
||||||
|
{
|
||||||
|
EFI_STATUS Result = EFI_SUCCESS;
|
||||||
|
EFI_LOADED_IMAGE* BootMgfw = NULL;
|
||||||
|
|
||||||
|
if (EFI_ERROR((Result = gBS->HandleProtocol(BootMgfwPath, &gEfiLoadedImageProtocolGuid, (VOID**)&BootMgfw))))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Print(L"Image Base -> 0x%p\n", BootMgfw->ImageBase);
|
||||||
|
Print(L"Image Size -> 0x%x\n", BootMgfw->ImageSize);
|
||||||
|
|
||||||
|
VOID* ArchStartBootApplication =
|
||||||
|
FindPattern(
|
||||||
|
BootMgfw->ImageBase,
|
||||||
|
BootMgfw->ImageSize,
|
||||||
|
START_BOOT_APPLICATION,
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
);
|
||||||
|
|
||||||
|
Print(L"ArchStartBootApplication -> 0x%p\n", ArchStartBootApplication);
|
||||||
|
MakeShitHook(&BootMgfwShitHook, ArchStartBootApplication, &ArchStartBootApplicationHook, TRUE);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ArchStartBootApplicationHook(VOID* AppEntry, VOID* ImageBase, UINT32 ImageSize, UINT8 BootOption, VOID* ReturnArgs)
|
||||||
|
{
|
||||||
|
DisableShitHook(&BootMgfwShitHook);
|
||||||
|
VOID* LdrLoadImage = GetExport(ImageBase, "BlLdrLoadImage");
|
||||||
|
VOID* ImgAllocateImageBuffer =
|
||||||
|
FindPattern(
|
||||||
|
ImageBase,
|
||||||
|
ImageSize,
|
||||||
|
ALLOCATE_IMAGE_BUFFER_SIG,
|
||||||
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
);
|
||||||
|
|
||||||
|
Print(L"PE PayLoad Size -> 0x%x\n", GetGoldenRecordSize());
|
||||||
|
Print(L"winload base -> 0x%p\n", ImageBase);
|
||||||
|
Print(L"winload size -> 0x%x\n", ImageSize);
|
||||||
|
Print(L"winload.BlLdrLoadImage -> 0x%p\n", LdrLoadImage);
|
||||||
|
Print(L"winload.BlImgAllocateImageBuffer -> 0x%p\n", ImgAllocateImageBuffer);
|
||||||
|
MakeShitHook(&WinLoadImageShitHook, LdrLoadImage, &BlLdrLoadImage, TRUE);
|
||||||
|
MakeShitHook(&WinLoadAllocateImageHook, ImgAllocateImageBuffer, &BlImgAllocateImageBuffer, TRUE);
|
||||||
|
return ((IMG_ARCH_START_BOOT_APPLICATION)BootMgfwShitHook.Address)(AppEntry, ImageBase, ImageSize, BootOption, ReturnArgs);
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/LoadedImage.h>
|
||||||
|
#include <IndustryStandard/PeImage.h>
|
||||||
|
#include <Guid/GlobalVariable.h>
|
||||||
|
#include "WinLoad.h"
|
||||||
|
|
||||||
|
#define START_BOOT_APPLICATION "\x48\x8B\xC4\x48\x89\x58\x20\x44\x89\x40\x18\x48\x89\x50\x10\x48\x89\x48\x08\x55\x56\x57\x41\x54"
|
||||||
|
#define WINDOWS_BOOTMGR_PATH L"\\efi\\microsoft\\boot\\bootmgfw.efi"
|
||||||
|
|
||||||
|
extern SHITHOOK BootMgfwShitHook;
|
||||||
|
typedef EFI_STATUS(EFIAPI* IMG_ARCH_START_BOOT_APPLICATION)(VOID*, VOID*, UINT32, UINT8, VOID*);
|
||||||
|
EFI_DEVICE_PATH* EFIAPI GetBootMgfwPath(VOID);
|
||||||
|
EFI_STATUS EFIAPI InstallBootMgfwHooks(EFI_HANDLE BootMgfwPath);
|
||||||
|
EFI_STATUS EFIAPI ArchStartBootApplicationHook(VOID* AppEntry, VOID* ImageBase, UINT32 ImageSize, UINT8 BootOption, VOID* ReturnArgs);
|
@ -0,0 +1,157 @@
|
|||||||
|
#include "Hvix64.h"
|
||||||
|
|
||||||
|
VOID* MapModule(PVOYAGER_DATA_T VoyagerData, UINT8* ImageBase)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER* dosHeaders = (EFI_IMAGE_DOS_HEADER*)ImageBase;
|
||||||
|
if (dosHeaders->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_NT_HEADERS64* ntHeaders = (EFI_IMAGE_NT_HEADERS64*)(ImageBase + dosHeaders->e_lfanew);
|
||||||
|
|
||||||
|
// Map headers
|
||||||
|
MemCopy(VoyagerData->ModuleBase, ImageBase, ntHeaders->OptionalHeader.SizeOfHeaders);
|
||||||
|
|
||||||
|
// Map sections
|
||||||
|
EFI_IMAGE_SECTION_HEADER* sections = (EFI_IMAGE_SECTION_HEADER*)((UINT8*)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader);
|
||||||
|
for (UINT32 i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_SECTION_HEADER* section = §ions[i];
|
||||||
|
if (section->SizeOfRawData)
|
||||||
|
MemCopy(VoyagerData->ModuleBase + section->VirtualAddress, ImageBase + section->PointerToRawData, section->SizeOfRawData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set exported pointer to voyager context...
|
||||||
|
EFI_IMAGE_EXPORT_DIRECTORY* ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(
|
||||||
|
VoyagerData->ModuleBase + ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||||
|
|
||||||
|
UINT32* Address = (UINT32*)(VoyagerData->ModuleBase + ExportDir->AddressOfFunctions);
|
||||||
|
UINT32* Name = (UINT32*)(VoyagerData->ModuleBase + ExportDir->AddressOfNames);
|
||||||
|
UINT16* Ordinal = (UINT16*)(VoyagerData->ModuleBase + ExportDir->AddressOfNameOrdinals);
|
||||||
|
|
||||||
|
for (UINT16 i = 0; i < ExportDir->AddressOfFunctions; i++)
|
||||||
|
{
|
||||||
|
if (AsciiStrStr(VoyagerData->ModuleBase + Name[i], "pvoyager_context"))
|
||||||
|
{
|
||||||
|
*(VOID**)(VoyagerData->ModuleBase + Address[Ordinal[i]]) = VoyagerData;
|
||||||
|
break; // DO NOT REMOVE? Gorilla Code 2020...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve relocations
|
||||||
|
EFI_IMAGE_DATA_DIRECTORY* baseRelocDir = &ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
|
if (baseRelocDir->VirtualAddress)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_BASE_RELOCATION* reloc = (EFI_IMAGE_BASE_RELOCATION*)(VoyagerData->ModuleBase + baseRelocDir->VirtualAddress);
|
||||||
|
for (UINT32 currentSize = 0; currentSize < baseRelocDir->Size; )
|
||||||
|
{
|
||||||
|
UINT32 relocCount = (reloc->SizeOfBlock - sizeof(EFI_IMAGE_BASE_RELOCATION)) / sizeof(UINT16);
|
||||||
|
UINT16* relocData = (UINT16*)((UINT8*)reloc + sizeof(EFI_IMAGE_BASE_RELOCATION));
|
||||||
|
UINT8* relocBase = VoyagerData->ModuleBase + reloc->VirtualAddress;
|
||||||
|
|
||||||
|
for (UINT32 i = 0; i < relocCount; ++i, ++relocData)
|
||||||
|
{
|
||||||
|
UINT16 data = *relocData;
|
||||||
|
UINT16 type = data >> 12;
|
||||||
|
UINT16 offset = data & 0xFFF;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
|
break;
|
||||||
|
case EFI_IMAGE_REL_BASED_DIR64:
|
||||||
|
{
|
||||||
|
UINT64* rva = (UINT64*)(relocBase + offset);
|
||||||
|
*rva = (UINT64)(VoyagerData->ModuleBase + (*rva - ntHeaders->OptionalHeader.ImageBase));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSize += reloc->SizeOfBlock;
|
||||||
|
reloc = (EFI_IMAGE_BASE_RELOCATION*)relocData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VoyagerData->ModuleBase + ntHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOYAGER_DATA_T MakeVoyagerData
|
||||||
|
(
|
||||||
|
VOID* HypervAlloc,
|
||||||
|
UINT64 HypervAllocSize,
|
||||||
|
VOID* GoldenRecordAlloc,
|
||||||
|
UINT64 GoldenRecordSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// the memory for the voyager data is allocated under the memory for the golden record...
|
||||||
|
PVOYAGER_DATA_T VoyagerData = (UINT64)GoldenRecordAlloc + GoldenRecordSize;
|
||||||
|
VoyagerData->HypervModuleBase = HypervAlloc;
|
||||||
|
VoyagerData->HypervModuleSize = HypervAllocSize;
|
||||||
|
VoyagerData->ModuleBase = GoldenRecordAlloc;
|
||||||
|
VoyagerData->ModuleSize = GoldenRecordSize;
|
||||||
|
|
||||||
|
VOID* VmExitHandler =
|
||||||
|
FindPattern(
|
||||||
|
HypervAlloc,
|
||||||
|
HypervAllocSize,
|
||||||
|
VMEXIT_HANDLER,
|
||||||
|
"xxxxxxxxxxxxx?xxxx?x????x"
|
||||||
|
);
|
||||||
|
|
||||||
|
DBG_PRINT("VmExitHandler Call Signature Result -> 0x%p\n", VmExitHandler);
|
||||||
|
|
||||||
|
if (!VmExitHandler)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
.text:FFFFF80000237436 mov rcx, [rsp+arg_18] ; rcx = pointer to stack that contians all register values
|
||||||
|
.text:FFFFF8000023743B mov rdx, [rsp+arg_28]
|
||||||
|
.text:FFFFF80000237440 call vmexit_c_handler ; RIP relative call
|
||||||
|
.text:FFFFF80000237445 jmp loc_FFFFF80000237100
|
||||||
|
*/
|
||||||
|
|
||||||
|
UINT64 VmExitHandlerCall = ((UINT64)VmExitHandler) + 19; // + 19 bytes to -> call vmexit_c_handler
|
||||||
|
UINT64 VmExitHandlerCallRip = (UINT64)VmExitHandlerCall + 5; // + 5 bytes because "call vmexit_c_handler" is 5 bytes
|
||||||
|
UINT64 VmExitFunction = VmExitHandlerCallRip + *(INT32*)((UINT64)(VmExitHandlerCall + 1)); // + 1 to skip E8 (call) and read 4 bytes (RVA)
|
||||||
|
VoyagerData->VmExitHandler = VmExitFunction;
|
||||||
|
|
||||||
|
DBG_PRINT("VmExitHandlerCall -> 0x%p\n", VmExitHandlerCall);
|
||||||
|
DBG_PRINT("VmExitHandlerCallRip -> 0x%p\n", VmExitHandlerCallRip);
|
||||||
|
DBG_PRINT("VmExitFunction -> 0x%p\n", VmExitFunction);
|
||||||
|
return VoyagerData;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID* HookVmExit(VOID* HypervBase, VOID* HypervSize, VOID* VmExitHook)
|
||||||
|
{
|
||||||
|
VOID* VmExitHandler =
|
||||||
|
FindPattern(
|
||||||
|
HypervBase,
|
||||||
|
HypervSize,
|
||||||
|
VMEXIT_HANDLER,
|
||||||
|
"xxxxxxxxxxxxx?xxxx?x????x"
|
||||||
|
);
|
||||||
|
|
||||||
|
DBG_PRINT("VmExitHandler Call Signature Result -> 0x%p\n", VmExitHandler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
.text:FFFFF80000237436 mov rcx, [rsp+arg_18] ; rcx = pointer to stack that contians all register values
|
||||||
|
.text:FFFFF8000023743B mov rdx, [rsp+arg_28]
|
||||||
|
.text:FFFFF80000237440 call vmexit_c_handler ; RIP relative call
|
||||||
|
.text:FFFFF80000237445 jmp loc_FFFFF80000237100
|
||||||
|
*/
|
||||||
|
|
||||||
|
UINT64 VmExitHandlerCall = ((UINT64)VmExitHandler) + 19; // + 19 bytes to -> call vmexit_c_handler
|
||||||
|
UINT64 VmExitHandlerCallRip = (UINT64)VmExitHandlerCall + 5; // + 5 bytes because "call vmexit_c_handler" is 5 bytes
|
||||||
|
UINT64 VmExitFunction = VmExitHandlerCallRip + *(INT32*)((UINT64)(VmExitHandlerCall + 1)); // + 1 to skip E8 (call) and read 4 bytes (RVA)
|
||||||
|
INT32 NewVmExitRVA = ((INT64)VmExitHook) - VmExitHandlerCallRip;
|
||||||
|
*(INT32*)((UINT64)(VmExitHandlerCall + 1)) = NewVmExitRVA;
|
||||||
|
|
||||||
|
DBG_PRINT("VmExitHandlerCall -> 0x%p\n", VmExitHandlerCall);
|
||||||
|
DBG_PRINT("VmExitHandlerCallRip -> 0x%p\n", VmExitHandlerCallRip);
|
||||||
|
DBG_PRINT("VmExitFunction -> 0x%p\n", VmExitFunction);
|
||||||
|
DBG_PRINT("NewVmExitRVA -> 0x%x\n", NewVmExitRVA);
|
||||||
|
|
||||||
|
return VmExitFunction;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TheGoldenRecord.h"
|
||||||
|
#define VMEXIT_HANDLER "\x65\xC6\x04\x25\x6D\x00\x00\x00\x00\x48\x8B\x4C\x24\x20\x48\x8B\x54\x24\x30\xE8\x6B\xBF\xFE\xFF\xE9"
|
||||||
|
|
||||||
|
//
|
||||||
|
// AllocBase is the base address of the extra memory allocated below where hyper-v is
|
||||||
|
// AllocSize is the size of the extra allocated memory... This size == module size...
|
||||||
|
//
|
||||||
|
VOID* MapModule(PVOYAGER_DATA_T VoyagerData, UINT8* ImageBase);
|
||||||
|
|
||||||
|
//
|
||||||
|
// sig scan hv.exe for vmexit call and replace the relative call (RVA) with
|
||||||
|
// an RVA to the vmexit handler hook (which is the golden records entry point)...
|
||||||
|
//
|
||||||
|
// returns a pointer to the original vmexit function address...
|
||||||
|
//
|
||||||
|
VOID* HookVmExit(VOID* HypervBase, VOID* HypervSize, VOID* VmExitHook);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Given hyper-v's base address and size, sig scan it for vmexit handler, then construct "VOYAGER_DATA_T"
|
||||||
|
// using memory already allocated under hyper-v and under the memory allocated for the golden record...
|
||||||
|
//
|
||||||
|
PVOYAGER_DATA_T MakeVoyagerData
|
||||||
|
(
|
||||||
|
VOID* HypervAlloc,
|
||||||
|
UINT64 HypervAllocSize,
|
||||||
|
VOID* GoldenRecordAlloc,
|
||||||
|
UINT64 GoldenRecordSize
|
||||||
|
);
|
@ -0,0 +1,36 @@
|
|||||||
|
#include "ShitHook.h"
|
||||||
|
|
||||||
|
VOID MakeShitHook(PSHITHOOK Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install)
|
||||||
|
{
|
||||||
|
if (!Hook || !HookFrom || !HookTo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char JmpCode[14] =
|
||||||
|
{
|
||||||
|
0xff, 0x25, 0x0, 0x0, 0x0, 0x0, // jmp QWORD PTR[rip + 0x0]
|
||||||
|
|
||||||
|
// jmp address...
|
||||||
|
0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0
|
||||||
|
};
|
||||||
|
|
||||||
|
// save original bytes, and hook related addresses....
|
||||||
|
Hook->Address = HookFrom;
|
||||||
|
Hook->HookAddress = HookTo;
|
||||||
|
gBS->CopyMem(Hook->Code, HookFrom, sizeof Hook->Code);
|
||||||
|
|
||||||
|
// setup hook...
|
||||||
|
gBS->CopyMem(JmpCode + 6, &HookTo, sizeof HookTo);
|
||||||
|
gBS->CopyMem(Hook->JmpCode, JmpCode, sizeof JmpCode);
|
||||||
|
if (Install) EnableShitHook(Hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID EnableShitHook(PSHITHOOK Hook)
|
||||||
|
{
|
||||||
|
gBS->CopyMem(Hook->Address, Hook->JmpCode, sizeof Hook->JmpCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID DisableShitHook(PSHITHOOK Hook)
|
||||||
|
{
|
||||||
|
gBS->CopyMem(Hook->Address, Hook->Code, sizeof Hook->Code);
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Protocol/LoadedImage.h>
|
||||||
|
#include <IndustryStandard/PeImage.h>
|
||||||
|
#include <Guid/GlobalVariable.h>
|
||||||
|
|
||||||
|
typedef struct _SHITHOOK
|
||||||
|
{
|
||||||
|
unsigned char Code[14];
|
||||||
|
unsigned char JmpCode[14];
|
||||||
|
|
||||||
|
void* Address;
|
||||||
|
void* HookAddress;
|
||||||
|
} SHITHOOK, *PSHITHOOK;
|
||||||
|
|
||||||
|
VOID MakeShitHook(PSHITHOOK Hook, VOID* HookFrom, VOID* HookTo, BOOLEAN Install);
|
||||||
|
VOID EnableShitHook(PSHITHOOK Hook);
|
||||||
|
VOID DisableShitHook(PSHITHOOK Hook);
|
@ -0,0 +1,287 @@
|
|||||||
|
#include "TheGoldenRecord.h"
|
||||||
|
|
||||||
|
UINT32 GetGoldenRecordSize(VOID)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER* RecordDosImageHeader = GoldenRecord;
|
||||||
|
if (RecordDosImageHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_NT_HEADERS64* RecordNtHeaders = (UINT64)RecordDosImageHeader + RecordDosImageHeader->e_lfanew;
|
||||||
|
if (RecordNtHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return RecordNtHeaders->OptionalHeader.SizeOfImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID* GetGoldenRecordEntry(VOID* ModuleBase)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER* RecordDosImageHeader = GoldenRecord;
|
||||||
|
if (RecordDosImageHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_NT_HEADERS64* RecordNtHeaders = (UINT64)RecordDosImageHeader + RecordDosImageHeader->e_lfanew;
|
||||||
|
if (RecordNtHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (UINT64)ModuleBase + RecordNtHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char GoldenRecord[3072] =
|
||||||
|
{
|
||||||
|
0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0xFF, 0xFF, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xB8, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD,
|
||||||
|
0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70,
|
||||||
|
0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F,
|
||||||
|
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20,
|
||||||
|
0x44, 0x4F, 0x53, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A,
|
||||||
|
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xBF, 0x31, 0xDD,
|
||||||
|
0x6B, 0xDE, 0x5F, 0x8E, 0x6B, 0xDE, 0x5F, 0x8E, 0x6B, 0xDE, 0x5F, 0x8E,
|
||||||
|
0xDC, 0xAF, 0x5A, 0x8F, 0x6A, 0xDE, 0x5F, 0x8E, 0xDC, 0xAF, 0x5F, 0x8F,
|
||||||
|
0x6A, 0xDE, 0x5F, 0x8E, 0xDC, 0xAF, 0x5D, 0x8F, 0x6A, 0xDE, 0x5F, 0x8E,
|
||||||
|
0x52, 0x69, 0x63, 0x68, 0x6B, 0xDE, 0x5F, 0x8E, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x64, 0x86, 0x05, 0x00,
|
||||||
|
0xB2, 0x81, 0x69, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xF0, 0x00, 0x22, 0x20, 0x0B, 0x02, 0x0E, 0x1B, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||||
|
0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x64, 0xAF, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
|
||||||
|
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||||
|
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||||
|
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00,
|
||||||
|
0x75, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x68, 0x2E, 0x72, 0x64, 0x61,
|
||||||
|
0x74, 0x61, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48,
|
||||||
|
0x2E, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x40, 0x00, 0x00, 0xC8, 0x2E, 0x70, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00,
|
||||||
|
0x0C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x2E, 0x65, 0x64, 0x61,
|
||||||
|
0x74, 0x61, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x4C, 0x89, 0x4C, 0x24, 0x20, 0x4C, 0x89, 0x44,
|
||||||
|
0x24, 0x18, 0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x4C, 0x24, 0x08,
|
||||||
|
0x56, 0x48, 0x83, 0xEC, 0x30, 0x48, 0x8D, 0x05, 0xE0, 0x00, 0x00, 0x00,
|
||||||
|
0x66, 0xBA, 0xF8, 0x02, 0x48, 0x8B, 0xF0, 0xB9, 0x13, 0x00, 0x00, 0x00,
|
||||||
|
0xF3, 0x6E, 0x48, 0x83, 0x3D, 0xCA, 0x1F, 0x00, 0x00, 0x00, 0x74, 0x15,
|
||||||
|
0x48, 0x8D, 0x05, 0xE1, 0x00, 0x00, 0x00, 0x66, 0xBA, 0xF8, 0x02, 0x48,
|
||||||
|
0x8B, 0xF0, 0xB9, 0x2E, 0x00, 0x00, 0x00, 0xF3, 0x6E, 0xC7, 0x44, 0x24,
|
||||||
|
0x20, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0A, 0x8B, 0x44, 0x24, 0x20, 0xFF,
|
||||||
|
0xC0, 0x89, 0x44, 0x24, 0x20, 0x83, 0x7C, 0x24, 0x20, 0x08, 0x73, 0x16,
|
||||||
|
0x8B, 0x44, 0x24, 0x20, 0x48, 0x8D, 0x0D, 0x8D, 0x1F, 0x00, 0x00, 0x66,
|
||||||
|
0xBA, 0xF8, 0x02, 0x0F, 0xB6, 0x04, 0x01, 0xEE, 0xEB, 0xD9, 0xC7, 0x44,
|
||||||
|
0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0A, 0x8B, 0x44, 0x24, 0x24,
|
||||||
|
0xFF, 0xC0, 0x89, 0x44, 0x24, 0x24, 0x83, 0x7C, 0x24, 0x24, 0x08, 0x73,
|
||||||
|
0x16, 0x8B, 0x44, 0x24, 0x24, 0x48, 0x8B, 0x0D, 0x5C, 0x1F, 0x00, 0x00,
|
||||||
|
0x66, 0xBA, 0xF8, 0x02, 0x0F, 0xB6, 0x04, 0x01, 0xEE, 0xEB, 0xD9, 0x48,
|
||||||
|
0x8D, 0x05, 0x9A, 0x00, 0x00, 0x00, 0x66, 0xBA, 0xF8, 0x02, 0x48, 0x8B,
|
||||||
|
0xF0, 0xB9, 0x25, 0x00, 0x00, 0x00, 0xF3, 0x6E, 0x48, 0x8B, 0x05, 0x35,
|
||||||
|
0x1F, 0x00, 0x00, 0x48, 0x8B, 0x00, 0x48, 0x89, 0x44, 0x24, 0x28, 0x4C,
|
||||||
|
0x8B, 0x4C, 0x24, 0x58, 0x4C, 0x8B, 0x44, 0x24, 0x50, 0x48, 0x8B, 0x54,
|
||||||
|
0x24, 0x48, 0x48, 0x8B, 0x4C, 0x24, 0x40, 0xFF, 0x54, 0x24, 0x28, 0x48,
|
||||||
|
0x83, 0xC4, 0x30, 0x5E, 0xC3, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||||
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x6D, 0x65, 0x78,
|
||||||
|
0x69, 0x74, 0x20, 0x63, 0x61, 0x6C, 0x6C, 0x65, 0x64, 0x2E, 0x2E, 0x2E,
|
||||||
|
0x2E, 0x0A, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||||
|
0xCC, 0xCC, 0xCC, 0xCC, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x20,
|
||||||
|
0x74, 0x6F, 0x20, 0x76, 0x6F, 0x79, 0x61, 0x67, 0x65, 0x72, 0x20, 0x63,
|
||||||
|
0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F,
|
||||||
|
0x74, 0x20, 0x6E, 0x75, 0x6C, 0x6C, 0x70, 0x74, 0x72, 0x2E, 0x2E, 0x2E,
|
||||||
|
0x0A, 0x00, 0xCC, 0xCC, 0x63, 0x61, 0x6C, 0x6C, 0x69, 0x6E, 0x67, 0x20,
|
||||||
|
0x6F, 0x72, 0x69, 0x67, 0x69, 0x6E, 0x61, 0x6C, 0x20, 0x76, 0x6D, 0x65,
|
||||||
|
0x78, 0x69, 0x74, 0x20, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x2E,
|
||||||
|
0x2E, 0x2E, 0x2E, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xB2, 0x81, 0x69, 0x5F, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00,
|
||||||
|
0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x81, 0x69, 0x5F,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
|
||||||
|
0x98, 0x20, 0x00, 0x00, 0x98, 0x06, 0x00, 0x00, 0x52, 0x53, 0x44, 0x53,
|
||||||
|
0x15, 0x24, 0xC8, 0xF1, 0xA0, 0x02, 0xC2, 0x40, 0x8E, 0xEB, 0x6B, 0xB2,
|
||||||
|
0x6C, 0x94, 0x11, 0xDD, 0x02, 0x00, 0x00, 0x00, 0x43, 0x3A, 0x5C, 0x55,
|
||||||
|
0x73, 0x65, 0x72, 0x73, 0x5C, 0x78, 0x65, 0x72, 0x6F, 0x78, 0x5C, 0x73,
|
||||||
|
0x6F, 0x75, 0x72, 0x63, 0x65, 0x5C, 0x72, 0x65, 0x70, 0x6F, 0x73, 0x5C,
|
||||||
|
0x56, 0x6F, 0x79, 0x61, 0x67, 0x65, 0x72, 0x20, 0x31, 0x5C, 0x78, 0x36,
|
||||||
|
0x34, 0x5C, 0x52, 0x65, 0x6C, 0x65, 0x61, 0x73, 0x65, 0x5C, 0x54, 0x68,
|
||||||
|
0x65, 0x47, 0x6F, 0x6C, 0x64, 0x65, 0x6E, 0x52, 0x65, 0x63, 0x6F, 0x72,
|
||||||
|
0x64, 0x2E, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78,
|
||||||
|
0x74, 0x24, 0x6D, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
|
||||||
|
0x75, 0x00, 0x00, 0x00, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x24, 0x73, 0x00,
|
||||||
|
0x00, 0x20, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2E, 0x72, 0x64, 0x61,
|
||||||
|
0x74, 0x61, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,
|
||||||
|
0x2E, 0x72, 0x64, 0x61, 0x74, 0x61, 0x24, 0x7A, 0x7A, 0x7A, 0x64, 0x62,
|
||||||
|
0x67, 0x00, 0x00, 0x00, 0x28, 0x21, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||||
|
0x2E, 0x78, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x2E, 0x62, 0x73, 0x73, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2E, 0x70, 0x64, 0x61,
|
||||||
|
0x74, 0x61, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
|
||||||
|
0x2E, 0x65, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x02, 0x19, 0x04, 0x00,
|
||||||
|
0x02, 0x16, 0x00, 0x06, 0x19, 0x52, 0x15, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0xF1, 0x10, 0x00, 0x00, 0x28, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x32, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x50, 0x00, 0x00,
|
||||||
|
0x2C, 0x50, 0x00, 0x00, 0x30, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
|
||||||
|
0x46, 0x50, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x47, 0x6F, 0x6C,
|
||||||
|
0x64, 0x65, 0x6E, 0x52, 0x65, 0x63, 0x6F, 0x72, 0x64, 0x2E, 0x64, 0x6C,
|
||||||
|
0x6C, 0x00, 0x3F, 0x70, 0x76, 0x6F, 0x79, 0x61, 0x67, 0x65, 0x72, 0x5F,
|
||||||
|
0x63, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x40, 0x40, 0x33, 0x50, 0x45,
|
||||||
|
0x41, 0x55, 0x5F, 0x56, 0x4F, 0x59, 0x41, 0x47, 0x45, 0x52, 0x5F, 0x44,
|
||||||
|
0x41, 0x54, 0x41, 0x5F, 0x54, 0x40, 0x40, 0x45, 0x41, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Utils.h"
|
||||||
|
extern unsigned char GoldenRecord[3072];
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct _VOYAGER_DATA_T
|
||||||
|
{
|
||||||
|
VOID* VmExitHandler;
|
||||||
|
UINT64 HypervModuleBase;
|
||||||
|
UINT64 HypervModuleSize;
|
||||||
|
UINT64 ModuleBase;
|
||||||
|
UINT64 ModuleSize;
|
||||||
|
} _VOYAGER_DATA, * PVOYAGER_DATA_T;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
UINT32 GetGoldenRecordSize(VOID);
|
||||||
|
VOID* GetGoldenRecordEntry(VOID);
|
@ -0,0 +1,57 @@
|
|||||||
|
#include "BootMgfw.h"
|
||||||
|
|
||||||
|
CHAR8* gEfiCallerBaseName = "Voyager 1";
|
||||||
|
const UINT32 _gUefiDriverRevision = 0x200;
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI UefiUnload(
|
||||||
|
IN EFI_HANDLE ImageHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Print(L"unloading module from memory...\n");
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI UefiMain
|
||||||
|
(
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE* SystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// get the file path to bootmgfw.efi so we can load it...
|
||||||
|
EFI_DEVICE_PATH* BootMgfwPath = GetBootMgfwPath();
|
||||||
|
Print(L"BootMgfwPath -> %p\n", BootMgfwPath);
|
||||||
|
|
||||||
|
if (!BootMgfwPath)
|
||||||
|
{
|
||||||
|
Print(L"unable to get bootmgfw file path....\n");
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS Result;
|
||||||
|
EFI_HANDLE BootMgfwHandle;
|
||||||
|
|
||||||
|
// load bootmgfw.efi into memory...
|
||||||
|
if (EFI_ERROR((Result = gBS->LoadImage(TRUE, ImageHandle, BootMgfwPath, NULL, 0, &BootMgfwHandle))))
|
||||||
|
{
|
||||||
|
Print(L"failed to load bootmgfw.efi...\n");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print(L"Loaded bootmgfw.efi into memory...\n");
|
||||||
|
|
||||||
|
if (EFI_ERROR(InstallBootMgfwHooks(BootMgfwHandle)))
|
||||||
|
{
|
||||||
|
Print(L"Failed to install bootmgfw hooks...\n");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print(L"installed bootmgfw hooks...\n");
|
||||||
|
|
||||||
|
// start bootmgfw.efi...
|
||||||
|
if (EFI_ERROR(gBS->StartImage(BootMgfwHandle, NULL, NULL)))
|
||||||
|
{
|
||||||
|
Print(L"Failed to start bootmgfw.efi...\n");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
BOOLEAN CheckMask(CHAR8* base, CHAR8* pattern, CHAR8* mask)
|
||||||
|
{
|
||||||
|
for (; *mask; ++base, ++pattern, ++mask)
|
||||||
|
if (*mask == 'x' && *base != *pattern)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID* FindPattern(CHAR8* base, UINTN size, CHAR8* pattern, CHAR8* mask)
|
||||||
|
{
|
||||||
|
size -= AsciiStrLen(mask);
|
||||||
|
for (UINTN i = 0; i <= size; ++i)
|
||||||
|
{
|
||||||
|
VOID* addr = &base[i];
|
||||||
|
if (CheckMask(addr, pattern, mask))
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID* GetExport(UINT8* ModuleBase, CHAR8* export)
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER* dosHeaders = (EFI_IMAGE_DOS_HEADER*)ModuleBase;
|
||||||
|
if (dosHeaders->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_NT_HEADERS64* ntHeaders = (EFI_IMAGE_NT_HEADERS64*)(ModuleBase + dosHeaders->e_lfanew);
|
||||||
|
UINT32 exportsRva = ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||||
|
EFI_IMAGE_EXPORT_DIRECTORY* exports = (EFI_IMAGE_EXPORT_DIRECTORY*)(ModuleBase + exportsRva);
|
||||||
|
UINT32* nameRva = (UINT32*)(ModuleBase + exports->AddressOfNames);
|
||||||
|
|
||||||
|
for (UINT32 i = 0; i < exports->NumberOfNames; ++i)
|
||||||
|
{
|
||||||
|
CHAR8* func = (CHAR8*)(ModuleBase + nameRva[i]);
|
||||||
|
if (AsciiStrCmp(func, export) == 0)
|
||||||
|
{
|
||||||
|
UINT32* funcRva = (UINT32*)(ModuleBase + exports->AddressOfFunctions);
|
||||||
|
UINT16* ordinalRva = (UINT16*)(ModuleBase + exports->AddressOfNameOrdinals);
|
||||||
|
return (VOID*)(((UINT64)ModuleBase) + funcRva[ordinalRva[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID MemCopy(VOID* dest, VOID* src, UINTN size)
|
||||||
|
{
|
||||||
|
for (UINT8* d = dest, *s = src; size--; *d++ = *s++);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ShitHook.h"
|
||||||
|
#define PORT_NUM 0x2F8
|
||||||
|
#define BL_MEMORY_ATTRIBUTE_RWX 0x424000
|
||||||
|
#define SECTION_RWX (EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_EXECUTE)
|
||||||
|
|
||||||
|
VOID __outbytestring(UINT16 Port, UINT8* Buffer, UINT32 Count);
|
||||||
|
void __outbyte(unsigned short Port, unsigned char Data);
|
||||||
|
#pragma intrinsic(__outbytestring)
|
||||||
|
#pragma intrinsic(__outbyte)
|
||||||
|
|
||||||
|
static CHAR8 dbg_buffer[0x100];
|
||||||
|
#define DBG_PRINT(...) \
|
||||||
|
AsciiSPrint(dbg_buffer, sizeof dbg_buffer, __VA_ARGS__); \
|
||||||
|
__outbytestring(PORT_NUM, dbg_buffer, AsciiStrLen(dbg_buffer))
|
||||||
|
|
||||||
|
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||||
|
{
|
||||||
|
LIST_ENTRY InLoadOrderLinks; // 16
|
||||||
|
LIST_ENTRY InMemoryOrderLinks; // 32
|
||||||
|
LIST_ENTRY InInitializationOrderLinks; // 48
|
||||||
|
UINT64 ModuleBase; // 56
|
||||||
|
UINT64 EntryPoint; // 64
|
||||||
|
UINTN SizeOfImage; // 72
|
||||||
|
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY, **PPLDR_DATA_TABLE_ENTRY;
|
||||||
|
|
||||||
|
// taken from umap (btbd)
|
||||||
|
BOOLEAN CheckMask(CHAR8* base, CHAR8* pattern, CHAR8* mask);
|
||||||
|
VOID* FindPattern(CHAR8* base, UINTN size, CHAR8* pattern, CHAR8* mask);
|
||||||
|
VOID* GetExport(UINT8* base, CHAR8* export);
|
||||||
|
VOID MemCopy(VOID* dest, VOID* src, UINTN size);
|
@ -0,0 +1,196 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{540d433f-c2df-49a6-895c-f5c74b014777}</ProjectGuid>
|
||||||
|
<RootNamespace>HyperMe</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>Voyager 1</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PreferredToolArchitecture>x86</PreferredToolArchitecture>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<IncludePath>$(ProjectDir)edk2\CryptoPkg\Include;$(ProjectDir)edk2\ShellPkg\Include;$(ProjectDir)edk2\MdePkg\Include\X64;$(ProjectDir)edk2\MdePkg\Include</IncludePath>
|
||||||
|
<LibraryPath>$(ProjectDir)edk2</LibraryPath>
|
||||||
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<TargetExt>.efi</TargetExt>
|
||||||
|
<SourcePath>$(ProjectDir)</SourcePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<IncludePath>$(ProjectDir)edk2\CryptoPkg\Include;$(ProjectDir)edk2\ShellPkg\Include;$(ProjectDir)edk2\MdePkg\Include\X64;$(ProjectDir)edk2\MdePkg\Include;$(ProjectDir)edk2\StdLib\Include;$(ProjectDir)</IncludePath>
|
||||||
|
<LibraryPath>$(ProjectDir)edk2</LibraryPath>
|
||||||
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<TargetExt>.efi</TargetExt>
|
||||||
|
<SourcePath>$(ProjectDir)</SourcePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>EFI Application</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>EFI Application</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>EFI Application</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>false</DataExecutionPrevention>
|
||||||
|
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<EntryPointSymbol>EfiMain</EntryPointSymbol>
|
||||||
|
</Link>
|
||||||
|
<ProjectReference>
|
||||||
|
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>EFI Application</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<DataExecutionPrevention>false</DataExecutionPrevention>
|
||||||
|
<AdditionalDependencies>UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiApplicationEntryPoint.lib</AdditionalDependencies>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<EntryPointSymbol>EfiMain</EntryPointSymbol>
|
||||||
|
</Link>
|
||||||
|
<ProjectReference>
|
||||||
|
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="BootMgfw.c" />
|
||||||
|
<ClCompile Include="Hvix64.c" />
|
||||||
|
<ClCompile Include="ShitHook.c" />
|
||||||
|
<ClCompile Include="TheGoldenRecord.c" />
|
||||||
|
<ClCompile Include="UefiMain.c" />
|
||||||
|
<ClCompile Include="Utils.c" />
|
||||||
|
<ClCompile Include="WinLoad.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BootMgfw.h" />
|
||||||
|
<ClInclude Include="Hvix64.h" />
|
||||||
|
<ClInclude Include="ShitHook.h" />
|
||||||
|
<ClInclude Include="TheGoldenRecord.h" />
|
||||||
|
<ClInclude Include="Utils.h" />
|
||||||
|
<ClInclude Include="WinLoad.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="UefiMain.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="WinLoad.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BootMgfw.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ShitHook.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Hvix64.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="TheGoldenRecord.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BootMgfw.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="WinLoad.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Hvix64.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ShitHook.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Utils.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="TheGoldenRecord.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
@ -0,0 +1,109 @@
|
|||||||
|
#include "WinLoad.h"
|
||||||
|
|
||||||
|
SHITHOOK WinLoadImageShitHook;
|
||||||
|
SHITHOOK WinLoadAllocateImageHook;
|
||||||
|
SHITHOOK VmExitHandlerShitHook;
|
||||||
|
|
||||||
|
BOOLEAN HookedHyperV = FALSE;
|
||||||
|
BOOLEAN HyperVloading = FALSE;
|
||||||
|
BOOLEAN ExtendedAllocation = FALSE;
|
||||||
|
UINT64 AllocationCount = 0;
|
||||||
|
CHAR8 ModuleNameStr[0x100];
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI BlLdrLoadImage(VOID* Arg1, CHAR16* ModulePath, CHAR16* ModuleName, VOID* Arg4, VOID* Arg5, VOID* Arg6, VOID* Arg7, PPLDR_DATA_TABLE_ENTRY lplpTableEntry,
|
||||||
|
VOID* Arg9, VOID* Arg10, VOID* Arg11, VOID* Arg12, VOID* Arg13, VOID* Arg14, VOID* Arg15, VOID* Arg16)
|
||||||
|
{
|
||||||
|
if (!StrCmp(ModuleName, L"hv.exe"))
|
||||||
|
HyperVloading = TRUE;
|
||||||
|
|
||||||
|
UnicodeStrToAsciiStr(ModuleName, ModuleNameStr);
|
||||||
|
DBG_PRINT(ModuleNameStr);
|
||||||
|
UnicodeStrToAsciiStr(ModulePath, ModuleNameStr);
|
||||||
|
DBG_PRINT(ModuleNameStr);
|
||||||
|
|
||||||
|
DisableShitHook(&WinLoadImageShitHook);
|
||||||
|
EFI_STATUS Result = ((LDR_LOAD_IMAGE)WinLoadImageShitHook.Address)(Arg1, ModulePath, ModuleName, Arg4, Arg5, Arg6, Arg7, lplpTableEntry,
|
||||||
|
Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16);
|
||||||
|
EnableShitHook(&WinLoadImageShitHook);
|
||||||
|
|
||||||
|
// hv.exe has been loaded into memory...
|
||||||
|
if (!HookedHyperV && Result == EFI_SUCCESS && !StrCmp(ModuleName, L"hv.exe"))
|
||||||
|
{
|
||||||
|
HookedHyperV = TRUE;
|
||||||
|
PLDR_DATA_TABLE_ENTRY TableEntry = *lplpTableEntry;
|
||||||
|
EFI_IMAGE_DOS_HEADER* HypervDosHeader = TableEntry->ModuleBase;
|
||||||
|
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
|
||||||
|
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
|
||||||
|
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
|
||||||
|
|
||||||
|
for (UINT16 i = 0; i < HypervNtHeader->FileHeader.NumberOfSections; i += 1, pSection += 1)
|
||||||
|
{
|
||||||
|
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
|
||||||
|
{
|
||||||
|
PVOYAGER_DATA_T VoyagerData = MakeVoyagerData
|
||||||
|
(
|
||||||
|
// hyper-v allocation...
|
||||||
|
TableEntry->ModuleBase,
|
||||||
|
TableEntry->SizeOfImage,
|
||||||
|
|
||||||
|
// space for golden record is going to be in .reloc section after .reloc data (dont overwrite anything)
|
||||||
|
TableEntry->ModuleBase + pSection->VirtualAddress + pSection->Misc.VirtualSize,
|
||||||
|
GetGoldenRecordSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID* VmExitHook = MapModule(VoyagerData, GoldenRecord);
|
||||||
|
// this makes hyper-v not load/work
|
||||||
|
VOID* VmExitFunction = HookVmExit
|
||||||
|
(
|
||||||
|
VoyagerData->HypervModuleBase,
|
||||||
|
VoyagerData->HypervModuleSize,
|
||||||
|
VmExitHook
|
||||||
|
);
|
||||||
|
|
||||||
|
pSection->Characteristics = SECTION_RWX;
|
||||||
|
pSection->Misc.VirtualSize += GetGoldenRecordSize() + sizeof(_VOYAGER_DATA);
|
||||||
|
DBG_PRINT("VmExitHook (PayLoad Entry Point) -> 0x%p\n", VmExitHook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This fixes the allocation size to include whatever we want... dont ask me why this works it just does... LOL
|
||||||
|
HypervNtHeader->OptionalHeader.SizeOfImage += GetGoldenRecordSize() + sizeof(_VOYAGER_DATA);
|
||||||
|
TableEntry->SizeOfImage += GetGoldenRecordSize() + sizeof(_VOYAGER_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_PRINT("[%s] Image Base -> 0x%p, Image Size -> 0x%x\n", __FUNCTION__, (*lplpTableEntry)->ModuleBase, (*lplpTableEntry)->SizeOfImage);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT64 EFIAPI BlImgAllocateImageBuffer(VOID** imageBuffer, UINTN imageSize, UINT32 memoryType, UINT32 attributes, VOID* unused, UINT32 flags)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// The second allocation for hv.exe is used for the actual image... Wait for the second allocation before extending the allocation...
|
||||||
|
//
|
||||||
|
// hv.exe
|
||||||
|
// [BlImgAllocateImageBuffer] Alloc Base -> 0x7FFFF9FE000, Alloc Size -> 0x17C548
|
||||||
|
// [BlImgAllocateImageBuffer] Alloc Base -> 0xFFFFF80608120000, Alloc Size -> 0x1600000
|
||||||
|
// [BlImgAllocateImageBuffer] Alloc Base -> 0xFFFFF80606D68000, Alloc Size -> 0x2148
|
||||||
|
// [BlLdrLoadImage] Image Base -> 0xFFFFF80608120000, Image Size -> 0x1600000
|
||||||
|
//
|
||||||
|
|
||||||
|
if (HyperVloading && !ExtendedAllocation && ++AllocationCount == 2)
|
||||||
|
{
|
||||||
|
ExtendedAllocation = TRUE;
|
||||||
|
imageSize += GetGoldenRecordSize() + sizeof(_VOYAGER_DATA);
|
||||||
|
|
||||||
|
// allocate the entire hyper-v module as rwx...
|
||||||
|
memoryType = BL_MEMORY_ATTRIBUTE_RWX;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableShitHook(&WinLoadAllocateImageHook);
|
||||||
|
UINT64 Result = ((ALLOCATE_IMAGE_BUFFER)WinLoadAllocateImageHook.Address)(imageBuffer, imageSize, memoryType, attributes, unused, flags);
|
||||||
|
EnableShitHook(&WinLoadAllocateImageHook);
|
||||||
|
return Result;
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Hvix64.h"
|
||||||
|
#include "TheGoldenRecord.h"
|
||||||
|
|
||||||
|
extern SHITHOOK WinLoadImageShitHook;
|
||||||
|
extern SHITHOOK WinLoadAllocateImageHook;
|
||||||
|
|
||||||
|
#define ALLOCATE_IMAGE_BUFFER_SIG "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x40\x48\x8B\x31\x4C\x8D\x7A\xFF\x45\x33\xED\x48\x89\x75"
|
||||||
|
typedef UINT64 (EFIAPI* ALLOCATE_IMAGE_BUFFER)(VOID** imageBuffer, UINTN imageSize, UINT32 memoryType, UINT32 attributes, VOID* unused, UINT32 flags);
|
||||||
|
typedef EFI_STATUS (EFIAPI* LDR_LOAD_IMAGE)(VOID* Arg1, CHAR16* ModulePath, CHAR16* ModuleName, VOID* Arg4, VOID* Arg5, VOID* Arg6, VOID* Arg7, PPLDR_DATA_TABLE_ENTRY lplpTableEntry,
|
||||||
|
VOID* Arg9, VOID* Arg10, VOID* Arg11, VOID* Arg12, VOID* Arg13, VOID* Arg14, VOID* Arg15, VOID* Arg16);
|
||||||
|
|
||||||
|
UINT64 EFIAPI BlImgAllocateImageBuffer(VOID** imageBuffer, UINTN imageSize, UINT32 memoryType, UINT32 attributes, VOID* unused, UINT32 flags);
|
||||||
|
EFI_STATUS EFIAPI BlLdrLoadImage(VOID* Arg1, CHAR16* ModulePath, CHAR16* ModuleName, VOID* Arg4, VOID* Arg5, VOID* Arg6, VOID* Arg7, PPLDR_DATA_TABLE_ENTRY lplpTableEntry,
|
||||||
|
VOID* Arg9, VOID* Arg10, VOID* Arg11, VOID* Arg12, VOID* Arg13, VOID* Arg14, VOID* Arg15, VOID* Arg16);
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,43 @@
|
|||||||
|
## @file
|
||||||
|
# Package for cryptography modules.
|
||||||
|
#
|
||||||
|
# This Package provides cryptographic-related libraries for UEFI security modules.
|
||||||
|
# It also provides a test application to test libraries.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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]
|
||||||
|
DEC_SPECIFICATION = 0x00010005
|
||||||
|
PACKAGE_NAME = CryptoPkg
|
||||||
|
PACKAGE_UNI_FILE = CryptoPkg.uni
|
||||||
|
PACKAGE_GUID = 36470E80-36F2-4ba0-8CC8-937C7D9FF888
|
||||||
|
PACKAGE_VERSION = 0.98
|
||||||
|
|
||||||
|
[Includes]
|
||||||
|
Include
|
||||||
|
|
||||||
|
[Includes.Common.Private]
|
||||||
|
Library/Include
|
||||||
|
Library/OpensslLib/openssl/include
|
||||||
|
Library/OpensslLib/openssl/crypto/include
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
## @libraryclass Provides basic library functions for cryptographic primitives.
|
||||||
|
##
|
||||||
|
BaseCryptLib|Include/Library/BaseCryptLib.h
|
||||||
|
|
||||||
|
## @libraryclass Provides TLS library functions for EFI TLS protocol.
|
||||||
|
##
|
||||||
|
TlsLib|Include/Library/TlsLib.h
|
||||||
|
|
||||||
|
[UserExtensions.TianoCore."ExtraFiles"]
|
||||||
|
CryptoPkgExtra.uni
|
@ -0,0 +1,130 @@
|
|||||||
|
## @file
|
||||||
|
# Cryptographic Library Package for UEFI Security Implementation.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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 Section - statements that will be processed to create a Makefile.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
[Defines]
|
||||||
|
PLATFORM_NAME = CryptoPkg
|
||||||
|
PLATFORM_GUID = E1063286-6C8C-4c25-AEF0-67A9A5B6E6B6
|
||||||
|
PLATFORM_VERSION = 0.98
|
||||||
|
DSC_SPECIFICATION = 0x00010005
|
||||||
|
OUTPUT_DIRECTORY = Build/CryptoPkg
|
||||||
|
SUPPORTED_ARCHITECTURES = IA32|X64|ARM|AARCH64
|
||||||
|
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
|
||||||
|
SKUID_IDENTIFIER = DEFAULT
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Library Class section - list of all Library Classes needed by this Platform.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||||
|
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||||
|
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||||
|
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||||
|
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
|
||||||
|
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||||
|
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||||
|
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
|
||||||
|
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||||
|
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
||||||
|
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||||
|
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
|
||||||
|
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
|
||||||
|
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
|
||||||
|
|
||||||
|
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
|
||||||
|
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.ARM, LibraryClasses.AARCH64]
|
||||||
|
#
|
||||||
|
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
|
||||||
|
# This library provides the instrinsic functions generate by a given compiler.
|
||||||
|
# [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library
|
||||||
|
# into all ARM and AARCH64 images.
|
||||||
|
#
|
||||||
|
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
||||||
|
|
||||||
|
# Add support for stack protector
|
||||||
|
NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.ARM]
|
||||||
|
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.PEIM]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.DXE_DRIVER]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.DXE_SMM_DRIVER]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.UEFI_DRIVER]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.common.UEFI_APPLICATION]
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
[PcdsFeatureFlag]
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
|
||||||
|
|
||||||
|
[PcdsFixedAtBuild]
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06
|
||||||
|
|
||||||
|
###################################################################################################
|
||||||
|
#
|
||||||
|
# Components Section - list of the modules and components that will be processed by compilation
|
||||||
|
# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
|
||||||
|
#
|
||||||
|
# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
|
||||||
|
# into firmware volume images. This section is just a list of modules to compile from
|
||||||
|
# source into UEFI-compliant binaries.
|
||||||
|
# It is the FDF file that contains information on combining binary files into firmware
|
||||||
|
# volume images, whose concept is beyond UEFI and is described in PI specification.
|
||||||
|
# Binary modules do not need to be listed in this section, as they should be
|
||||||
|
# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
|
||||||
|
# Logo (Logo.bmp), and etc.
|
||||||
|
# There may also be modules listed in this section that are not required in the FDF file,
|
||||||
|
# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
|
||||||
|
# generated for it, but the binary will not be put into any firmware volume.
|
||||||
|
#
|
||||||
|
###################################################################################################
|
||||||
|
[Components]
|
||||||
|
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
|
||||||
|
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
|
||||||
|
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
|
||||||
|
CryptoPkg/Library/TlsLib/TlsLib.inf
|
||||||
|
CryptoPkg/Library/OpensslLib/OpensslLib.inf
|
||||||
|
|
||||||
|
[Components.IA32, Components.X64]
|
||||||
|
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
|
||||||
|
|
||||||
|
[BuildOptions]
|
||||||
|
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
@ -0,0 +1,25 @@
|
|||||||
|
// /** @file
|
||||||
|
// Package for cryptography modules.
|
||||||
|
//
|
||||||
|
// This Package provides cryptographic-related libraries for UEFI security modules.
|
||||||
|
// It also provides a test application to test libraries.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_PACKAGE_ABSTRACT #language en-US "Provides cryptographic-related libraries for UEFI security modules"
|
||||||
|
|
||||||
|
#string STR_PACKAGE_DESCRIPTION #language en-US "This Package provides cryptographic-related libraries for UEFI security modules."
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
// /** @file
|
||||||
|
// Crypto Package Localized Strings and Content.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
#string STR_PROPERTIES_PACKAGE_NAME
|
||||||
|
#language en-US
|
||||||
|
"Crypto package"
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,800 @@
|
|||||||
|
/** @file
|
||||||
|
Defines TLS Library APIs.
|
||||||
|
|
||||||
|
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __TLS_LIB_H__
|
||||||
|
#define __TLS_LIB_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes the OpenSSL library.
|
||||||
|
|
||||||
|
This function registers ciphers and digests used directly and indirectly
|
||||||
|
by SSL/TLS, and initializes the readable error messages.
|
||||||
|
This function must be called before any other action takes places.
|
||||||
|
|
||||||
|
@retval TRUE The OpenSSL library has been initialized.
|
||||||
|
@retval FALSE Failed to initialize the OpenSSL library.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TlsInitialize (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free an allocated SSL_CTX object.
|
||||||
|
|
||||||
|
@param[in] TlsCtx Pointer to the SSL_CTX object to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
TlsCtxFree (
|
||||||
|
IN VOID *TlsCtx
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
|
||||||
|
connections.
|
||||||
|
|
||||||
|
@param[in] MajorVer Major Version of TLS/SSL Protocol.
|
||||||
|
@param[in] MinorVer Minor Version of TLS/SSL Protocol.
|
||||||
|
|
||||||
|
@return Pointer to an allocated SSL_CTX object.
|
||||||
|
If the creation failed, TlsCtxNew() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
TlsCtxNew (
|
||||||
|
IN UINT8 MajorVer,
|
||||||
|
IN UINT8 MinorVer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free an allocated TLS object.
|
||||||
|
|
||||||
|
This function removes the TLS object pointed to by Tls and frees up the
|
||||||
|
allocated memory. If Tls is NULL, nothing is done.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object to be freed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
TlsFree (
|
||||||
|
IN VOID *Tls
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a new TLS object for a connection.
|
||||||
|
|
||||||
|
This function creates a new TLS object for a connection. The new object
|
||||||
|
inherits the setting of the underlying context TlsCtx: connection method,
|
||||||
|
options, verification setting.
|
||||||
|
|
||||||
|
@param[in] TlsCtx Pointer to the SSL_CTX object.
|
||||||
|
|
||||||
|
@return Pointer to an allocated SSL object.
|
||||||
|
If the creation failed, TlsNew() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
TlsNew (
|
||||||
|
IN VOID *TlsCtx
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the TLS handshake was done.
|
||||||
|
|
||||||
|
This function will check if the specified TLS handshake was done.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object for handshake state checking.
|
||||||
|
|
||||||
|
@retval TRUE The TLS handshake was done.
|
||||||
|
@retval FALSE The TLS handshake was not done.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TlsInHandshake (
|
||||||
|
IN VOID *Tls
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform a TLS/SSL handshake.
|
||||||
|
|
||||||
|
This function will perform a TLS/SSL handshake.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object for handshake operation.
|
||||||
|
@param[in] BufferIn Pointer to the most recently received TLS Handshake packet.
|
||||||
|
@param[in] BufferInSize Packet size in bytes for the most recently received TLS
|
||||||
|
Handshake packet.
|
||||||
|
@param[out] BufferOut Pointer to the buffer to hold the built packet.
|
||||||
|
@param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
|
||||||
|
the buffer size provided by the caller. On output, it
|
||||||
|
is the buffer size in fact needed to contain the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The required TLS packet is built successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
Tls is NULL.
|
||||||
|
BufferIn is NULL but BufferInSize is NOT 0.
|
||||||
|
BufferInSize is 0 but BufferIn is NOT NULL.
|
||||||
|
BufferOutSize is NULL.
|
||||||
|
BufferOut is NULL if *BufferOutSize is not zero.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
|
||||||
|
@retval EFI_ABORTED Something wrong during handshake.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsDoHandshake (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT8 *BufferIn, OPTIONAL
|
||||||
|
IN UINTN BufferInSize, OPTIONAL
|
||||||
|
OUT UINT8 *BufferOut, OPTIONAL
|
||||||
|
IN OUT UINTN *BufferOutSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Handle Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
|
||||||
|
TLS session has errors and the response packet needs to be Alert message based on error type.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object for state checking.
|
||||||
|
@param[in] BufferIn Pointer to the most recently received TLS Alert packet.
|
||||||
|
@param[in] BufferInSize Packet size in bytes for the most recently received TLS
|
||||||
|
Alert packet.
|
||||||
|
@param[out] BufferOut Pointer to the buffer to hold the built packet.
|
||||||
|
@param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
|
||||||
|
the buffer size provided by the caller. On output, it
|
||||||
|
is the buffer size in fact needed to contain the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The required TLS packet is built successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
Tls is NULL.
|
||||||
|
BufferIn is NULL but BufferInSize is NOT 0.
|
||||||
|
BufferInSize is 0 but BufferIn is NOT NULL.
|
||||||
|
BufferOutSize is NULL.
|
||||||
|
BufferOut is NULL if *BufferOutSize is not zero.
|
||||||
|
@retval EFI_ABORTED An error occurred.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsHandleAlert (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT8 *BufferIn, OPTIONAL
|
||||||
|
IN UINTN BufferInSize, OPTIONAL
|
||||||
|
OUT UINT8 *BufferOut, OPTIONAL
|
||||||
|
IN OUT UINTN *BufferOutSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build the CloseNotify packet.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object for state checking.
|
||||||
|
@param[in, out] Buffer Pointer to the buffer to hold the built packet.
|
||||||
|
@param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
|
||||||
|
the buffer size provided by the caller. On output, it
|
||||||
|
is the buffer size in fact needed to contain the
|
||||||
|
packet.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The required TLS packet is built successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||||
|
Tls is NULL.
|
||||||
|
BufferSize is NULL.
|
||||||
|
Buffer is NULL if *BufferSize is not zero.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsCloseNotify (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *Buffer,
|
||||||
|
IN OUT UINTN *BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attempts to read bytes from one TLS object and places the data in Buffer.
|
||||||
|
|
||||||
|
This function will attempt to read BufferSize bytes from the TLS object
|
||||||
|
and places the data in Buffer.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] Buffer Pointer to the buffer to store the data.
|
||||||
|
@param[in] BufferSize The size of Buffer in bytes.
|
||||||
|
|
||||||
|
@retval >0 The amount of data successfully read from the TLS object.
|
||||||
|
@retval <=0 No data was successfully read.
|
||||||
|
|
||||||
|
**/
|
||||||
|
INTN
|
||||||
|
EFIAPI
|
||||||
|
TlsCtrlTrafficOut (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT VOID *Buffer,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attempts to write data from the buffer to TLS object.
|
||||||
|
|
||||||
|
This function will attempt to write BufferSize bytes data from the Buffer
|
||||||
|
to the TLS object.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] Buffer Pointer to the data buffer.
|
||||||
|
@param[in] BufferSize The size of Buffer in bytes.
|
||||||
|
|
||||||
|
@retval >0 The amount of data successfully written to the TLS object.
|
||||||
|
@retval <=0 No data was successfully written.
|
||||||
|
|
||||||
|
**/
|
||||||
|
INTN
|
||||||
|
EFIAPI
|
||||||
|
TlsCtrlTrafficIn (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN VOID *Buffer,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attempts to read bytes from the specified TLS connection into the buffer.
|
||||||
|
|
||||||
|
This function tries to read BufferSize bytes data from the specified TLS
|
||||||
|
connection into the Buffer.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS connection for data reading.
|
||||||
|
@param[in,out] Buffer Pointer to the data buffer.
|
||||||
|
@param[in] BufferSize The size of Buffer in bytes.
|
||||||
|
|
||||||
|
@retval >0 The read operation was successful, and return value is the
|
||||||
|
number of bytes actually read from the TLS connection.
|
||||||
|
@retval <=0 The read operation was not successful.
|
||||||
|
|
||||||
|
**/
|
||||||
|
INTN
|
||||||
|
EFIAPI
|
||||||
|
TlsRead (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT VOID *Buffer,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attempts to write data to a TLS connection.
|
||||||
|
|
||||||
|
This function tries to write BufferSize bytes data from the Buffer into the
|
||||||
|
specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS connection for data writing.
|
||||||
|
@param[in] Buffer Pointer to the data buffer.
|
||||||
|
@param[in] BufferSize The size of Buffer in bytes.
|
||||||
|
|
||||||
|
@retval >0 The write operation was successful, and return value is the
|
||||||
|
number of bytes actually written to the TLS connection.
|
||||||
|
@retval <=0 The write operation was not successful.
|
||||||
|
|
||||||
|
**/
|
||||||
|
INTN
|
||||||
|
EFIAPI
|
||||||
|
TlsWrite (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN VOID *Buffer,
|
||||||
|
IN UINTN BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set a new TLS/SSL method for a particular TLS object.
|
||||||
|
|
||||||
|
This function sets a new TLS/SSL method for a particular TLS object.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to a TLS object.
|
||||||
|
@param[in] MajorVer Major Version of TLS/SSL Protocol.
|
||||||
|
@param[in] MinorVer Minor Version of TLS/SSL Protocol.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS/SSL method was set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetVersion (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT8 MajorVer,
|
||||||
|
IN UINT8 MinorVer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set TLS object to work in client or server mode.
|
||||||
|
|
||||||
|
This function prepares a TLS object to work in client or server mode.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to a TLS object.
|
||||||
|
@param[in] IsServer Work in server mode.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetConnectionEnd (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN BOOLEAN IsServer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the ciphers list to be used by the TLS object.
|
||||||
|
|
||||||
|
This function sets the ciphers for use by a specified TLS object.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to a TLS object.
|
||||||
|
@param[in] CipherId Array of UINT16 cipher identifiers. Each UINT16
|
||||||
|
cipher identifier comes from the TLS Cipher Suite
|
||||||
|
Registry of the IANA, interpreting Byte1 and Byte2
|
||||||
|
in network (big endian) byte order.
|
||||||
|
@param[in] CipherNum The number of cipher in the list.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The ciphers list was set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED No supported TLS cipher was found in CipherId.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetCipherList (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT16 *CipherId,
|
||||||
|
IN UINTN CipherNum
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the compression method for TLS/SSL operations.
|
||||||
|
|
||||||
|
This function handles TLS/SSL integrated compression methods.
|
||||||
|
|
||||||
|
@param[in] CompMethod The compression method ID.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The compression method for the communication was
|
||||||
|
set successfully.
|
||||||
|
@retval EFI_UNSUPPORTED Unsupported compression method.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetCompressionMethod (
|
||||||
|
IN UINT8 CompMethod
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set peer certificate verification mode for the TLS connection.
|
||||||
|
|
||||||
|
This function sets the verification mode flags for the TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] VerifyMode A set of logically or'ed verification mode flags.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
TlsSetVerify (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT32 VerifyMode
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets a TLS/SSL session ID to be used during TLS/SSL connect.
|
||||||
|
|
||||||
|
This function sets a session ID to be used when the TLS/SSL connection is
|
||||||
|
to be established.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] SessionId Session ID data used for session resumption.
|
||||||
|
@param[in] SessionIdLen Length of Session ID in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Session ID was set successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED No available session for ID setting.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetSessionId (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN UINT8 *SessionId,
|
||||||
|
IN UINT16 SessionIdLen
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds the CA to the cert store when requesting Server or Client authentication.
|
||||||
|
|
||||||
|
This function adds the CA certificate to the list of CAs when requesting
|
||||||
|
Server or Client authentication for the chosen TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] Data Pointer to the data buffer of a DER-encoded binary
|
||||||
|
X.509 certificate or PEM-encoded X.509 certificate.
|
||||||
|
@param[in] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
|
||||||
|
@retval EFI_ABORTED Invalid X.509 certificate.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetCaCertificate (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Loads the local public certificate into the specified TLS object.
|
||||||
|
|
||||||
|
This function loads the X.509 certificate into the specified TLS object
|
||||||
|
for TLS negotiation.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] Data Pointer to the data buffer of a DER-encoded binary
|
||||||
|
X.509 certificate or PEM-encoded X.509 certificate.
|
||||||
|
@param[in] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
|
||||||
|
@retval EFI_ABORTED Invalid X.509 certificate.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetHostPublicCert (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds the local private key to the specified TLS object.
|
||||||
|
|
||||||
|
This function adds the local private key (PEM-encoded RSA or PKCS#8 private
|
||||||
|
key) into the specified TLS object for TLS negotiation.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in] Data Pointer to the data buffer of a PEM-encoded RSA
|
||||||
|
or PKCS#8 private key.
|
||||||
|
@param[in] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_ABORTED Invalid private key data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetHostPrivateKey (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds the CA-supplied certificate revocation list for certificate validation.
|
||||||
|
|
||||||
|
This function adds the CA-supplied certificate revocation list data for
|
||||||
|
certificate validity checking.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
|
||||||
|
@param[in] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_ABORTED Invalid CRL data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsSetCertRevocationList (
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the protocol version used by the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the protocol version used by the specified TLS
|
||||||
|
connection.
|
||||||
|
|
||||||
|
If Tls is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
|
||||||
|
@return The protocol version of the specified TLS connection.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
TlsGetVersion (
|
||||||
|
IN VOID *Tls
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the connection end of the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the connection end (as client or as server) used by
|
||||||
|
the specified TLS connection.
|
||||||
|
|
||||||
|
If Tls is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
|
||||||
|
@return The connection end used by the specified TLS connection.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT8
|
||||||
|
EFIAPI
|
||||||
|
TlsGetConnectionEnd (
|
||||||
|
IN VOID *Tls
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the cipher suite used by the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns current cipher suite used by the specified
|
||||||
|
TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] CipherId The cipher suite used by the TLS object.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The cipher suite was returned successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED Unsupported cipher suite.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetCurrentCipher (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT16 *CipherId
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the compression methods used by the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns current integrated compression methods used by
|
||||||
|
the specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] CompressionId The current compression method used by
|
||||||
|
the TLS object.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The compression method was returned successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_ABORTED Invalid Compression method.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetCurrentCompressionId (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *CompressionId
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the verification mode currently set in the TLS connection.
|
||||||
|
|
||||||
|
This function returns the peer verification mode currently set in the
|
||||||
|
specified TLS connection.
|
||||||
|
|
||||||
|
If Tls is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
|
||||||
|
@return The verification mode set in the specified TLS connection.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT32
|
||||||
|
EFIAPI
|
||||||
|
TlsGetVerify (
|
||||||
|
IN VOID *Tls
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the session ID used by the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the TLS/SSL session ID currently used by the
|
||||||
|
specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] SessionId Buffer to contain the returned session ID.
|
||||||
|
@param[in,out] SessionIdLen The length of Session ID in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The Session ID was returned successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED Invalid TLS/SSL session.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetSessionId (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *SessionId,
|
||||||
|
IN OUT UINT16 *SessionIdLen
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the client random data used in the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the TLS/SSL client random data currently used in
|
||||||
|
the specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] ClientRandom Buffer to contain the returned client
|
||||||
|
random data (32 bytes).
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
TlsGetClientRandom (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *ClientRandom
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the server random data used in the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the TLS/SSL server random data currently used in
|
||||||
|
the specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] ServerRandom Buffer to contain the returned server
|
||||||
|
random data (32 bytes).
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
TlsGetServerRandom (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *ServerRandom
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the master key data used in the specified TLS connection.
|
||||||
|
|
||||||
|
This function returns the TLS/SSL master key material currently used in
|
||||||
|
the specified TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[in,out] KeyMaterial Buffer to contain the returned key material.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Key material was returned successfully.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_UNSUPPORTED Invalid TLS/SSL session.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetKeyMaterial (
|
||||||
|
IN VOID *Tls,
|
||||||
|
IN OUT UINT8 *KeyMaterial
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the CA Certificate from the cert store.
|
||||||
|
|
||||||
|
This function returns the CA certificate for the chosen
|
||||||
|
TLS connection.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[out] Data Pointer to the data buffer to receive the CA
|
||||||
|
certificate data sent to the client.
|
||||||
|
@param[in,out] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetCaCertificate (
|
||||||
|
IN VOID *Tls,
|
||||||
|
OUT VOID *Data,
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the local public Certificate set in the specified TLS object.
|
||||||
|
|
||||||
|
This function returns the local public certificate which was currently set
|
||||||
|
in the specified TLS object.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[out] Data Pointer to the data buffer to receive the local
|
||||||
|
public certificate.
|
||||||
|
@param[in,out] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||||
|
@retval EFI_NOT_FOUND The certificate is not found.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetHostPublicCert (
|
||||||
|
IN VOID *Tls,
|
||||||
|
OUT VOID *Data,
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the local private key set in the specified TLS object.
|
||||||
|
|
||||||
|
This function returns the local private key data which was currently set
|
||||||
|
in the specified TLS object.
|
||||||
|
|
||||||
|
@param[in] Tls Pointer to the TLS object.
|
||||||
|
@param[out] Data Pointer to the data buffer to receive the local
|
||||||
|
private key data.
|
||||||
|
@param[in,out] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetHostPrivateKey (
|
||||||
|
IN VOID *Tls,
|
||||||
|
OUT VOID *Data,
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the CA-supplied certificate revocation list data set in the specified
|
||||||
|
TLS object.
|
||||||
|
|
||||||
|
This function returns the CA-supplied certificate revocation list data which
|
||||||
|
was currently set in the specified TLS object.
|
||||||
|
|
||||||
|
@param[out] Data Pointer to the data buffer to receive the CRL data.
|
||||||
|
@param[in,out] DataSize The size of data buffer in bytes.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The operation succeeded.
|
||||||
|
@retval EFI_UNSUPPORTED This function is not supported.
|
||||||
|
@retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TlsGetCertRevocationList (
|
||||||
|
OUT VOID *Data,
|
||||||
|
IN OUT UINTN *DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // __TLS_LIB_H__
|
||||||
|
|
@ -0,0 +1,102 @@
|
|||||||
|
## @file
|
||||||
|
# Cryptographic Library Instance for DXE_DRIVER.
|
||||||
|
#
|
||||||
|
# Caution: This module requires additional review when modified.
|
||||||
|
# This library will have external input - signature.
|
||||||
|
# This external input must be validated carefully to avoid security issues such as
|
||||||
|
# buffer overflow or integer overflow.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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
|
||||||
|
MODULE_UNI_FILE = BaseCryptLib.uni
|
||||||
|
FILE_GUID = be3bb803-91b6-4da0-bd91-a8b21c18ca5d
|
||||||
|
MODULE_TYPE = DXE_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BaseCryptLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
InternalCryptLib.h
|
||||||
|
Hash/CryptMd4.c
|
||||||
|
Hash/CryptMd5.c
|
||||||
|
Hash/CryptSha1.c
|
||||||
|
Hash/CryptSha256.c
|
||||||
|
Hash/CryptSha512.c
|
||||||
|
Hmac/CryptHmacMd5.c
|
||||||
|
Hmac/CryptHmacSha1.c
|
||||||
|
Hmac/CryptHmacSha256.c
|
||||||
|
Cipher/CryptAes.c
|
||||||
|
Cipher/CryptTdes.c
|
||||||
|
Cipher/CryptArc4.c
|
||||||
|
Pk/CryptRsaBasic.c
|
||||||
|
Pk/CryptRsaExt.c
|
||||||
|
Pk/CryptPkcs5Pbkdf2.c
|
||||||
|
Pk/CryptPkcs7Sign.c
|
||||||
|
Pk/CryptPkcs7VerifyCommon.c
|
||||||
|
Pk/CryptPkcs7VerifyBase.c
|
||||||
|
Pk/CryptDh.c
|
||||||
|
Pk/CryptX509.c
|
||||||
|
Pk/CryptAuthenticode.c
|
||||||
|
Pk/CryptTs.c
|
||||||
|
Pem/CryptPem.c
|
||||||
|
|
||||||
|
SysCall/CrtWrapper.c
|
||||||
|
SysCall/TimerWrapper.c
|
||||||
|
SysCall/BaseMemAllocation.c
|
||||||
|
|
||||||
|
[Sources.Ia32]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.ARM]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
CryptoPkg/CryptoPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
DebugLib
|
||||||
|
OpensslLib
|
||||||
|
IntrinsicLib
|
||||||
|
PrintLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove these [BuildOptions] after this library is cleaned up
|
||||||
|
#
|
||||||
|
[BuildOptions]
|
||||||
|
#
|
||||||
|
# suppress the following warnings so we do not break the build with warnings-as-errors:
|
||||||
|
# C4090: 'function' : different 'const' qualifiers
|
||||||
|
#
|
||||||
|
MSFT:*_*_*_CC_FLAGS = /wd4090
|
||||||
|
|
||||||
|
# -JCryptoPkg/Include : To disable the use of the system includes provided by RVCT
|
||||||
|
# --diag_remark=1 : Reduce severity of "#1-D: last line of file ends without a newline"
|
||||||
|
RVCT:*_*_ARM_CC_FLAGS = -JCryptoPkg/Include --diag_remark=1
|
@ -0,0 +1,25 @@
|
|||||||
|
// /** @file
|
||||||
|
// Cryptographic Library Instance for DXE_DRIVER.
|
||||||
|
//
|
||||||
|
// Caution: This module requires additional review when modified.
|
||||||
|
// This library will have external input - signature.
|
||||||
|
// This external input must be validated carefully to avoid security issues such as
|
||||||
|
// buffer overflow or integer overflow.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "Cryptographic Library Instance for DXE_DRIVER"
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "Caution: This module requires additional review when modified. This library will have external input - signature. This external input must be validated carefully to avoid security issues such as buffer overflow or integer overflow."
|
||||||
|
|
@ -0,0 +1,323 @@
|
|||||||
|
/** @file
|
||||||
|
AES Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for AES operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for AES operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
AesGetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// AES uses different key contexts for encryption and decryption, so here memory
|
||||||
|
// for 2 copies of AES_KEY is allocated.
|
||||||
|
//
|
||||||
|
return (UINTN) (2 * sizeof (AES_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as AES context for subsequent use.
|
||||||
|
|
||||||
|
This function initializes user-supplied memory pointed by AesContext as AES context.
|
||||||
|
In addition, it sets up all AES key materials for subsequent encryption and decryption
|
||||||
|
operations.
|
||||||
|
There are 3 options for key length, 128 bits, 192 bits, and 256 bits.
|
||||||
|
|
||||||
|
If AesContext is NULL, then return FALSE.
|
||||||
|
If Key is NULL, then return FALSE.
|
||||||
|
If KeyLength is not valid, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] AesContext Pointer to AES context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied AES key.
|
||||||
|
@param[in] KeyLength Length of AES key in bits.
|
||||||
|
|
||||||
|
@retval TRUE AES context initialization succeeded.
|
||||||
|
@retval FALSE AES context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesInit (
|
||||||
|
OUT VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeyLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AES_KEY *AesKey;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (AesContext == NULL || Key == NULL || (KeyLength != 128 && KeyLength != 192 && KeyLength != 256)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize AES encryption & decryption key schedule.
|
||||||
|
//
|
||||||
|
AesKey = (AES_KEY *) AesContext;
|
||||||
|
if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES encryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
This function performs AES encryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in ECB mode.
|
||||||
|
InputSize must be multiple of block size (16 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
AesContext should be already correctly initialized by AesInit(). Behavior with
|
||||||
|
invalid AES context is undefined.
|
||||||
|
|
||||||
|
If AesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (16 bytes), then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE AES encryption succeeded.
|
||||||
|
@retval FALSE AES encryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesEcbEncrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AES_KEY *AesKey;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AesKey = (AES_KEY *) AesContext;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Perform AES data encryption with ECB mode (block-by-block)
|
||||||
|
//
|
||||||
|
while (InputSize > 0) {
|
||||||
|
AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);
|
||||||
|
Input += AES_BLOCK_SIZE;
|
||||||
|
Output += AES_BLOCK_SIZE;
|
||||||
|
InputSize -= AES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES decryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
This function performs AES decryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in ECB mode.
|
||||||
|
InputSize must be multiple of block size (16 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
AesContext should be already correctly initialized by AesInit(). Behavior with
|
||||||
|
invalid AES context is undefined.
|
||||||
|
|
||||||
|
If AesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (16 bytes), then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES decryption output.
|
||||||
|
|
||||||
|
@retval TRUE AES decryption succeeded.
|
||||||
|
@retval FALSE AES decryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesEcbDecrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AES_KEY *AesKey;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AesKey = (AES_KEY *) AesContext;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Perform AES data decryption with ECB mode (block-by-block)
|
||||||
|
//
|
||||||
|
while (InputSize > 0) {
|
||||||
|
AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);
|
||||||
|
Input += AES_BLOCK_SIZE;
|
||||||
|
Output += AES_BLOCK_SIZE;
|
||||||
|
InputSize -= AES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES encryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
This function performs AES encryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in CBC mode.
|
||||||
|
InputSize must be multiple of block size (16 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
Initialization vector should be one block size (16 bytes).
|
||||||
|
AesContext should be already correctly initialized by AesInit(). Behavior with
|
||||||
|
invalid AES context is undefined.
|
||||||
|
|
||||||
|
If AesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (16 bytes), then return FALSE.
|
||||||
|
If Ivec is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE AES encryption succeeded.
|
||||||
|
@retval FALSE AES encryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesCbcEncrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AES_KEY *AesKey;
|
||||||
|
UINT8 IvecBuffer[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AesKey = (AES_KEY *) AesContext;
|
||||||
|
CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Perform AES data encryption with CBC mode
|
||||||
|
//
|
||||||
|
AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES decryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
This function performs AES decryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in CBC mode.
|
||||||
|
InputSize must be multiple of block size (16 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
Initialization vector should be one block size (16 bytes).
|
||||||
|
AesContext should be already correctly initialized by AesInit(). Behavior with
|
||||||
|
invalid AES context is undefined.
|
||||||
|
|
||||||
|
If AesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (16 bytes), then return FALSE.
|
||||||
|
If Ivec is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE AES decryption succeeded.
|
||||||
|
@retval FALSE AES decryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesCbcDecrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AES_KEY *AesKey;
|
||||||
|
UINT8 IvecBuffer[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
AesKey = (AES_KEY *) AesContext;
|
||||||
|
CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Perform AES data decryption with CBC mode
|
||||||
|
//
|
||||||
|
AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
/** @file
|
||||||
|
AES Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for AES operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
AesGetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as AES context for subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] AesContext Pointer to AES context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied AES key.
|
||||||
|
@param[in] KeyLength Length of AES key in bits.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesInit (
|
||||||
|
OUT VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeyLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES encryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesEcbEncrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES decryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES decryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesEcbDecrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES encryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesCbcEncrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs AES decryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AesContext Pointer to the AES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the AES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AesCbcDecrypt (
|
||||||
|
IN VOID *AesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,211 @@
|
|||||||
|
/** @file
|
||||||
|
ARC4 Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/rc4.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for ARC4 operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for ARC4 operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Arc4GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Memory for 2 copies of RC4_KEY is allocated, one for working copy, and the other
|
||||||
|
// for backup copy. When Arc4Reset() is called, we can use the backup copy to restore
|
||||||
|
// the working copy to the initial state.
|
||||||
|
//
|
||||||
|
return (UINTN) (2 * sizeof (RC4_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as ARC4 context for subsequent use.
|
||||||
|
|
||||||
|
This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.
|
||||||
|
In addition, it sets up all ARC4 key materials for subsequent encryption and decryption
|
||||||
|
operations.
|
||||||
|
|
||||||
|
If Arc4Context is NULL, then return FALSE.
|
||||||
|
If Key is NULL, then return FALSE.
|
||||||
|
If KeySize does not in the range of [5, 256] bytes, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Arc4Context Pointer to ARC4 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied ARC4 key.
|
||||||
|
@param[in] KeySize Size of ARC4 key in bytes.
|
||||||
|
|
||||||
|
@retval TRUE ARC4 context initialization succeeded.
|
||||||
|
@retval FALSE ARC4 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Init (
|
||||||
|
OUT VOID *Arc4Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RC4_KEY *Rc4Key;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Arc4Context == NULL || Key == NULL || (KeySize < 5 || KeySize > 256)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc4Key = (RC4_KEY *) Arc4Context;
|
||||||
|
|
||||||
|
RC4_set_key (Rc4Key, (UINT32) KeySize, Key);
|
||||||
|
|
||||||
|
CopyMem (Rc4Key + 1, Rc4Key, sizeof (RC4_KEY));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs ARC4 encryption on a data buffer of the specified size.
|
||||||
|
|
||||||
|
This function performs ARC4 encryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize.
|
||||||
|
Arc4Context should be already correctly initialized by Arc4Init(). Behavior with
|
||||||
|
invalid ARC4 context is undefined.
|
||||||
|
|
||||||
|
If Arc4Context is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the ARC4 encryption output.
|
||||||
|
|
||||||
|
@retval TRUE ARC4 encryption succeeded.
|
||||||
|
@retval FALSE ARC4 encryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Encrypt (
|
||||||
|
IN OUT VOID *Arc4Context,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RC4_KEY *Rc4Key;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc4Key = (RC4_KEY *) Arc4Context;
|
||||||
|
|
||||||
|
RC4 (Rc4Key, (UINT32) InputSize, Input, Output);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs ARC4 decryption on a data buffer of the specified size.
|
||||||
|
|
||||||
|
This function performs ARC4 decryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize.
|
||||||
|
Arc4Context should be already correctly initialized by Arc4Init(). Behavior with
|
||||||
|
invalid ARC4 context is undefined.
|
||||||
|
|
||||||
|
If Arc4Context is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the ARC4 decryption output.
|
||||||
|
|
||||||
|
@retval TRUE ARC4 decryption succeeded.
|
||||||
|
@retval FALSE ARC4 decryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Decrypt (
|
||||||
|
IN OUT VOID *Arc4Context,
|
||||||
|
IN UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RC4_KEY *Rc4Key;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc4Key = (RC4_KEY *) Arc4Context;
|
||||||
|
|
||||||
|
RC4 (Rc4Key, (UINT32) InputSize, Input, Output);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resets the ARC4 context to the initial state.
|
||||||
|
|
||||||
|
The function resets the ARC4 context to the state it had immediately after the
|
||||||
|
ARC4Init() function call.
|
||||||
|
Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context
|
||||||
|
should be already correctly initialized by ARC4Init().
|
||||||
|
|
||||||
|
If Arc4Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
|
||||||
|
@retval TRUE ARC4 reset succeeded.
|
||||||
|
@retval FALSE ARC4 reset failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Reset (
|
||||||
|
IN OUT VOID *Arc4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RC4_KEY *Rc4Key;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Arc4Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rc4Key = (RC4_KEY *) Arc4Context;
|
||||||
|
|
||||||
|
CopyMem (Rc4Key, Rc4Key + 1, sizeof (RC4_KEY));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
/** @file
|
||||||
|
ARC4 Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for ARC4 operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Arc4GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as ARC4 context for subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] Arc4Context Pointer to ARC4 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied ARC4 key.
|
||||||
|
@param[in] KeySize Size of ARC4 key in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Init (
|
||||||
|
OUT VOID *Arc4Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs ARC4 encryption on a data buffer of the specified size.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the ARC4 encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Encrypt (
|
||||||
|
IN OUT VOID *Arc4Context,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs ARC4 decryption on a data buffer of the specified size.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the ARC4 decryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Decrypt (
|
||||||
|
IN OUT VOID *Arc4Context,
|
||||||
|
IN UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resets the ARC4 context to the initial state.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Arc4Context Pointer to the ARC4 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Arc4Reset (
|
||||||
|
IN OUT VOID *Arc4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,370 @@
|
|||||||
|
/** @file
|
||||||
|
TDES Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/des.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for TDES operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for TDES operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
TdesGetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.
|
||||||
|
//
|
||||||
|
return (UINTN) (3 * sizeof (DES_key_schedule));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as TDES context for subsequent use.
|
||||||
|
|
||||||
|
This function initializes user-supplied memory pointed by TdesContext as TDES context.
|
||||||
|
In addition, it sets up all TDES key materials for subsequent encryption and decryption
|
||||||
|
operations.
|
||||||
|
There are 3 key options as follows:
|
||||||
|
KeyLength = 64, Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)
|
||||||
|
KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)
|
||||||
|
KeyLength = 192 Keying option 3: K1 != K2 != K3 (Strongest)
|
||||||
|
|
||||||
|
If TdesContext is NULL, then return FALSE.
|
||||||
|
If Key is NULL, then return FALSE.
|
||||||
|
If KeyLength is not valid, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] TdesContext Pointer to TDES context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied TDES key.
|
||||||
|
@param[in] KeyLength Length of TDES key in bits.
|
||||||
|
|
||||||
|
@retval TRUE TDES context initialization succeeded.
|
||||||
|
@retval FALSE TDES context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesInit (
|
||||||
|
OUT VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeyLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DES_key_schedule *KeySchedule;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (TdesContext == NULL || Key == NULL || (KeyLength != 64 && KeyLength != 128 && KeyLength != 192)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If input Key is a weak key, return error.
|
||||||
|
//
|
||||||
|
if (DES_is_weak_key ((const_DES_cblock *) Key) == 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);
|
||||||
|
|
||||||
|
if (KeyLength == 64) {
|
||||||
|
CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));
|
||||||
|
CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DES_is_weak_key ((const_DES_cblock *) (Key + 8)) == 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);
|
||||||
|
|
||||||
|
if (KeyLength == 128) {
|
||||||
|
CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DES_is_weak_key ((const_DES_cblock *) (Key + 16)) == 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES encryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
This function performs TDES encryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in ECB mode.
|
||||||
|
InputSize must be multiple of block size (8 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
TdesContext should be already correctly initialized by TdesInit(). Behavior with
|
||||||
|
invalid TDES context is undefined.
|
||||||
|
|
||||||
|
If TdesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (8 bytes), then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE TDES encryption succeeded.
|
||||||
|
@retval FALSE TDES encryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesEcbEncrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DES_key_schedule *KeySchedule;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||||
|
|
||||||
|
while (InputSize > 0) {
|
||||||
|
DES_ecb3_encrypt (
|
||||||
|
(const_DES_cblock *) Input,
|
||||||
|
(DES_cblock *) Output,
|
||||||
|
KeySchedule,
|
||||||
|
KeySchedule + 1,
|
||||||
|
KeySchedule + 2,
|
||||||
|
DES_ENCRYPT
|
||||||
|
);
|
||||||
|
Input += TDES_BLOCK_SIZE;
|
||||||
|
Output += TDES_BLOCK_SIZE;
|
||||||
|
InputSize -= TDES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES decryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
This function performs TDES decryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in ECB mode.
|
||||||
|
InputSize must be multiple of block size (8 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
TdesContext should be already correctly initialized by TdesInit(). Behavior with
|
||||||
|
invalid TDES context is undefined.
|
||||||
|
|
||||||
|
If TdesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (8 bytes), then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES decryption output.
|
||||||
|
|
||||||
|
@retval TRUE TDES decryption succeeded.
|
||||||
|
@retval FALSE TDES decryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesEcbDecrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DES_key_schedule *KeySchedule;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||||
|
|
||||||
|
while (InputSize > 0) {
|
||||||
|
DES_ecb3_encrypt (
|
||||||
|
(const_DES_cblock *) Input,
|
||||||
|
(DES_cblock *) Output,
|
||||||
|
KeySchedule,
|
||||||
|
KeySchedule + 1,
|
||||||
|
KeySchedule + 2,
|
||||||
|
DES_DECRYPT
|
||||||
|
);
|
||||||
|
Input += TDES_BLOCK_SIZE;
|
||||||
|
Output += TDES_BLOCK_SIZE;
|
||||||
|
InputSize -= TDES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES encryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
This function performs TDES encryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in CBC mode.
|
||||||
|
InputSize must be multiple of block size (8 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
Initialization vector should be one block size (8 bytes).
|
||||||
|
TdesContext should be already correctly initialized by TdesInit(). Behavior with
|
||||||
|
invalid TDES context is undefined.
|
||||||
|
|
||||||
|
If TdesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (8 bytes), then return FALSE.
|
||||||
|
If Ivec is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE TDES encryption succeeded.
|
||||||
|
@retval FALSE TDES encryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesCbcEncrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DES_key_schedule *KeySchedule;
|
||||||
|
UINT8 IvecBuffer[TDES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||||
|
CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
DES_ede3_cbc_encrypt (
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
(UINT32) InputSize,
|
||||||
|
KeySchedule,
|
||||||
|
KeySchedule + 1,
|
||||||
|
KeySchedule + 2,
|
||||||
|
(DES_cblock *) IvecBuffer,
|
||||||
|
DES_ENCRYPT
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES decryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
This function performs TDES decryption on data buffer pointed by Input, of specified
|
||||||
|
size of InputSize, in CBC mode.
|
||||||
|
InputSize must be multiple of block size (8 bytes). This function does not perform
|
||||||
|
padding. Caller must perform padding, if necessary, to ensure valid input data size.
|
||||||
|
Initialization vector should be one block size (8 bytes).
|
||||||
|
TdesContext should be already correctly initialized by TdesInit(). Behavior with
|
||||||
|
invalid TDES context is undefined.
|
||||||
|
|
||||||
|
If TdesContext is NULL, then return FALSE.
|
||||||
|
If Input is NULL, then return FALSE.
|
||||||
|
If InputSize is not multiple of block size (8 bytes), then return FALSE.
|
||||||
|
If Ivec is NULL, then return FALSE.
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval TRUE TDES decryption succeeded.
|
||||||
|
@retval FALSE TDES decryption failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesCbcDecrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DES_key_schedule *KeySchedule;
|
||||||
|
UINT8 IvecBuffer[TDES_BLOCK_SIZE];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||||
|
CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
DES_ede3_cbc_encrypt (
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
(UINT32) InputSize,
|
||||||
|
KeySchedule,
|
||||||
|
KeySchedule + 1,
|
||||||
|
KeySchedule + 2,
|
||||||
|
(DES_cblock *) IvecBuffer,
|
||||||
|
DES_DECRYPT
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,166 @@
|
|||||||
|
/** @file
|
||||||
|
TDES Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for TDES operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
TdesGetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory as TDES context for subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] TdesContext Pointer to TDES context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied TDES key.
|
||||||
|
@param[in] KeyLength Length of TDES key in bits.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesInit (
|
||||||
|
OUT VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeyLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES encryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesEcbEncrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES decryption on a data buffer of the specified size in ECB mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be decrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES decryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesEcbDecrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES encryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesCbcEncrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs TDES decryption on a data buffer of the specified size in CBC mode.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] TdesContext Pointer to the TDES context.
|
||||||
|
@param[in] Input Pointer to the buffer containing the data to be encrypted.
|
||||||
|
@param[in] InputSize Size of the Input buffer in bytes.
|
||||||
|
@param[in] Ivec Pointer to initialization vector.
|
||||||
|
@param[out] Output Pointer to a buffer that receives the TDES encryption output.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TdesCbcDecrypt (
|
||||||
|
IN VOID *TdesContext,
|
||||||
|
IN CONST UINT8 *Input,
|
||||||
|
IN UINTN InputSize,
|
||||||
|
IN CONST UINT8 *Ivec,
|
||||||
|
OUT UINT8 *Output
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,229 @@
|
|||||||
|
/** @file
|
||||||
|
MD4 Digest Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/md4.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for MD4 hash operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for MD4 hash operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Md4GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves the OpenSSL MD4 Context Size
|
||||||
|
//
|
||||||
|
return (UINTN) (sizeof (MD4_CTX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Md4Context as MD4 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If Md4Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Md4Context Pointer to MD4 context being initialized.
|
||||||
|
|
||||||
|
@retval TRUE MD4 context initialization succeeded.
|
||||||
|
@retval FALSE MD4 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Init (
|
||||||
|
OUT VOID *Md4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md4Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD4 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD4_Init ((MD4_CTX *) Md4Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing MD4 context.
|
||||||
|
|
||||||
|
If Md4Context is NULL, then return FALSE.
|
||||||
|
If NewMd4Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Md4Context Pointer to MD4 context being copied.
|
||||||
|
@param[out] NewMd4Context Pointer to new MD4 context.
|
||||||
|
|
||||||
|
@retval TRUE MD4 context copy succeeded.
|
||||||
|
@retval FALSE MD4 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Duplicate (
|
||||||
|
IN CONST VOID *Md4Context,
|
||||||
|
OUT VOID *NewMd4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md4Context == NULL || NewMd4Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewMd4Context, Md4Context, sizeof (MD4_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates MD4 context.
|
||||||
|
|
||||||
|
This function performs MD4 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
MD4 context should be already correctly initialized by Md4Init(), and should not be finalized
|
||||||
|
by Md4Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Md4Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Md4Context Pointer to the MD4 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE MD4 data digest succeeded.
|
||||||
|
@retval FALSE MD4 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Update (
|
||||||
|
IN OUT VOID *Md4Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md4Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD4 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD4_Update ((MD4_CTX *) Md4Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the MD4 digest value.
|
||||||
|
|
||||||
|
This function completes MD4 hash computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the MD4 context cannot
|
||||||
|
be used again.
|
||||||
|
MD4 context should be already correctly initialized by Md4Init(), and should not be
|
||||||
|
finalized by Md4Final(). Behavior with invalid MD4 context is undefined.
|
||||||
|
|
||||||
|
If Md4Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Md4Context Pointer to the MD4 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the MD4 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval TRUE MD4 digest computation succeeded.
|
||||||
|
@retval FALSE MD4 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Final (
|
||||||
|
IN OUT VOID *Md4Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md4Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD4 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD4_Final (HashValue, (MD4_CTX *) Md4Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the MD4 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the MD4 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the MD4 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval TRUE MD4 digest computation succeeded.
|
||||||
|
@retval FALSE MD4 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD4 Hash Computation.
|
||||||
|
//
|
||||||
|
if (MD4 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
/** @file
|
||||||
|
MD4 Digest Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for MD4 hash
|
||||||
|
operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Md4GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Md4Context as MD4 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] Md4Context Pointer to MD4 context being initialized.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Init (
|
||||||
|
OUT VOID *Md4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing MD4 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Md4Context Pointer to MD4 context being copied.
|
||||||
|
@param[out] NewMd4Context Pointer to new MD4 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Duplicate (
|
||||||
|
IN CONST VOID *Md4Context,
|
||||||
|
OUT VOID *NewMd4Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates MD4 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Md4Context Pointer to the MD4 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Update (
|
||||||
|
IN OUT VOID *Md4Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the MD4 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Md4Context Pointer to the MD4 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the MD4 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4Final (
|
||||||
|
IN OUT VOID *Md4Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the MD4 message digest of a input data buffer.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the MD4 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md4HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,231 @@
|
|||||||
|
/** @file
|
||||||
|
MD5 Digest Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 return FALSE.
|
||||||
|
|
||||||
|
@param[out] Md5Context Pointer to MD5 context being initialized.
|
||||||
|
|
||||||
|
@retval TRUE MD5 context initialization succeeded.
|
||||||
|
@retval FALSE MD5 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md5Init (
|
||||||
|
OUT VOID *Md5Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md5Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD5 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD5_Init ((MD5_CTX *) Md5Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing MD5 context.
|
||||||
|
|
||||||
|
If Md5Context is NULL, then return FALSE.
|
||||||
|
If NewMd5Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Md5Context Pointer to MD5 context being copied.
|
||||||
|
@param[out] NewMd5Context Pointer to new MD5 context.
|
||||||
|
|
||||||
|
@retval TRUE MD5 context copy succeeded.
|
||||||
|
@retval FALSE MD5 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md5Duplicate (
|
||||||
|
IN CONST VOID *Md5Context,
|
||||||
|
OUT VOID *NewMd5Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md5Context == NULL || NewMd5Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewMd5Context, Md5Context, sizeof (MD5_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates MD5 context.
|
||||||
|
|
||||||
|
This function performs MD5 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
MD5 context should be already correctly initialized by Md5Init(), and should not be finalized
|
||||||
|
by Md5Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Md5Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Md5Context Pointer to the MD5 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE MD5 data digest succeeded.
|
||||||
|
@retval FALSE MD5 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md5Update (
|
||||||
|
IN OUT VOID *Md5Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md5Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && (DataSize != 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD5 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD5_Update ((MD5_CTX *) Md5Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the MD5 digest value.
|
||||||
|
|
||||||
|
This function 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.
|
||||||
|
MD5 context should be already correctly initialized by Md5Init(), and should not be
|
||||||
|
finalized by Md5Final(). Behavior with invalid MD5 context is undefined.
|
||||||
|
|
||||||
|
If Md5Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Md5Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD5 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (MD5_Final (HashValue, (MD5_CTX *) Md5Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the MD5 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the MD5 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the MD5 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval TRUE MD5 digest computation succeeded.
|
||||||
|
@retval FALSE MD5 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Md5HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && (DataSize != 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL MD5 Hash Computation.
|
||||||
|
//
|
||||||
|
if (MD5 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,230 @@
|
|||||||
|
/** @file
|
||||||
|
SHA-1 Digest Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 SHA-1 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If Sha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Sha1Context Pointer to SHA-1 context being initialized.
|
||||||
|
|
||||||
|
@retval TRUE SHA-1 context initialization succeeded.
|
||||||
|
@retval FALSE SHA-1 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha1Init (
|
||||||
|
OUT VOID *Sha1Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha1Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-1 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA1_Init ((SHA_CTX *) Sha1Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-1 context.
|
||||||
|
|
||||||
|
If Sha1Context is NULL, then return FALSE.
|
||||||
|
If NewSha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Sha1Context Pointer to SHA-1 context being copied.
|
||||||
|
@param[out] NewSha1Context Pointer to new SHA-1 context.
|
||||||
|
|
||||||
|
@retval TRUE SHA-1 context copy succeeded.
|
||||||
|
@retval FALSE SHA-1 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha1Duplicate (
|
||||||
|
IN CONST VOID *Sha1Context,
|
||||||
|
OUT VOID *NewSha1Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha1Context == NULL || NewSha1Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewSha1Context, Sha1Context, sizeof (SHA_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-1 context.
|
||||||
|
|
||||||
|
This function performs SHA-1 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
SHA-1 context should be already correctly initialized by Sha1Init(), and should not be finalized
|
||||||
|
by Sha1Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Sha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@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] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE SHA-1 data digest succeeded.
|
||||||
|
@retval FALSE SHA-1 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha1Update (
|
||||||
|
IN OUT VOID *Sha1Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha1Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-1 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA1_Update ((SHA_CTX *) Sha1Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-1 digest value.
|
||||||
|
|
||||||
|
This function 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.
|
||||||
|
SHA-1 context should be already correctly initialized by Sha1Init(), and should not be
|
||||||
|
finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.
|
||||||
|
|
||||||
|
If Sha1Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha1Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-1 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA1_Final (HashValue, (SHA_CTX *) Sha1Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-1 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the SHA-1 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-1 digest
|
||||||
|
value (20 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-1 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-1 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha1HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-1 Hash Computation.
|
||||||
|
//
|
||||||
|
if (SHA1 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,229 @@
|
|||||||
|
/** @file
|
||||||
|
SHA-256 Digest Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for SHA-256 hash 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 return FALSE.
|
||||||
|
|
||||||
|
@param[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 (
|
||||||
|
OUT VOID *Sha256Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha256Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-256 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA256_Init ((SHA256_CTX *) Sha256Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-256 context.
|
||||||
|
|
||||||
|
If Sha256Context is NULL, then return FALSE.
|
||||||
|
If NewSha256Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Sha256Context Pointer to SHA-256 context being copied.
|
||||||
|
@param[out] NewSha256Context Pointer to new SHA-256 context.
|
||||||
|
|
||||||
|
@retval TRUE SHA-256 context copy succeeded.
|
||||||
|
@retval FALSE SHA-256 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha256Duplicate (
|
||||||
|
IN CONST VOID *Sha256Context,
|
||||||
|
OUT VOID *NewSha256Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha256Context == NULL || NewSha256Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewSha256Context, Sha256Context, sizeof (SHA256_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-256 context.
|
||||||
|
|
||||||
|
This function performs SHA-256 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
SHA-256 context should be already correctly initialized by Sha256Init(), and should not be finalized
|
||||||
|
by Sha256Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Sha256Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@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] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE SHA-256 data digest succeeded.
|
||||||
|
@retval FALSE SHA-256 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha256Update (
|
||||||
|
IN OUT VOID *Sha256Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha256Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-256 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA256_Update ((SHA256_CTX *) Sha256Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-256 digest value.
|
||||||
|
|
||||||
|
This function 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.
|
||||||
|
SHA-256 context should be already correctly initialized by Sha256Init(), and should not be
|
||||||
|
finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.
|
||||||
|
|
||||||
|
If Sha256Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Sha256Context Pointer to the 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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha256Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-256 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA256_Final (HashValue, (SHA256_CTX *) Sha256Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-256 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the SHA-256 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-256 digest
|
||||||
|
value (32 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-256 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-256 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha256HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-256 Hash Computation.
|
||||||
|
//
|
||||||
|
if (SHA256 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,446 @@
|
|||||||
|
/** @file
|
||||||
|
SHA-384 and SHA-512 Digest Wrapper Implementations over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for SHA-384 hash operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Sha384GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves OpenSSL SHA-384 Context Size
|
||||||
|
//
|
||||||
|
return (UINTN) (sizeof (SHA512_CTX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If Sha384Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Sha384Context Pointer to SHA-384 context being initialized.
|
||||||
|
|
||||||
|
@retval TRUE SHA-384 context initialization succeeded.
|
||||||
|
@retval FALSE SHA-384 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Init (
|
||||||
|
OUT VOID *Sha384Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha384Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-384 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA384_Init ((SHA512_CTX *) Sha384Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-384 context.
|
||||||
|
|
||||||
|
If Sha384Context is NULL, then return FALSE.
|
||||||
|
If NewSha384Context is NULL, then return FALSE.
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Sha384Context Pointer to SHA-384 context being copied.
|
||||||
|
@param[out] NewSha384Context Pointer to new SHA-384 context.
|
||||||
|
|
||||||
|
@retval TRUE SHA-384 context copy succeeded.
|
||||||
|
@retval FALSE SHA-384 context copy failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Duplicate (
|
||||||
|
IN CONST VOID *Sha384Context,
|
||||||
|
OUT VOID *NewSha384Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha384Context == NULL || NewSha384Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewSha384Context, Sha384Context, sizeof (SHA512_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-384 context.
|
||||||
|
|
||||||
|
This function performs SHA-384 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
SHA-384 context should be already correctly initialized by Sha384Init(), and should not be finalized
|
||||||
|
by Sha384Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Sha384Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Sha384Context Pointer to the SHA-384 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE SHA-384 data digest succeeded.
|
||||||
|
@retval FALSE SHA-384 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Update (
|
||||||
|
IN OUT VOID *Sha384Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha384Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-384 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA384_Update ((SHA512_CTX *) Sha384Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-384 digest value.
|
||||||
|
|
||||||
|
This function completes SHA-384 hash computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the SHA-384 context cannot
|
||||||
|
be used again.
|
||||||
|
SHA-384 context should be already correctly initialized by Sha384Init(), and should not be
|
||||||
|
finalized by Sha384Final(). Behavior with invalid SHA-384 context is undefined.
|
||||||
|
|
||||||
|
If Sha384Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Sha384Context Pointer to the SHA-384 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
|
||||||
|
value (48 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-384 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-384 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Final (
|
||||||
|
IN OUT VOID *Sha384Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha384Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-384 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha384Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-384 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the SHA-384 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
|
||||||
|
value (48 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-384 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-384 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-384 Hash Computation.
|
||||||
|
//
|
||||||
|
if (SHA384 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for SHA-512 hash operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Sha512GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves OpenSSL SHA-512 Context Size
|
||||||
|
//
|
||||||
|
return (UINTN) (sizeof (SHA512_CTX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If Sha512Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Sha512Context Pointer to SHA-512 context being initialized.
|
||||||
|
|
||||||
|
@retval TRUE SHA-512 context initialization succeeded.
|
||||||
|
@retval FALSE SHA-512 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Init (
|
||||||
|
OUT VOID *Sha512Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha512Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-512 Context Initialization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA512_Init ((SHA512_CTX *) Sha512Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-512 context.
|
||||||
|
|
||||||
|
If Sha512Context is NULL, then return FALSE.
|
||||||
|
If NewSha512Context is NULL, then return FALSE.
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Sha512Context Pointer to SHA-512 context being copied.
|
||||||
|
@param[out] NewSha512Context Pointer to new SHA-512 context.
|
||||||
|
|
||||||
|
@retval TRUE SHA-512 context copy succeeded.
|
||||||
|
@retval FALSE SHA-512 context copy failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Duplicate (
|
||||||
|
IN CONST VOID *Sha512Context,
|
||||||
|
OUT VOID *NewSha512Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha512Context == NULL || NewSha512Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (NewSha512Context, Sha512Context, sizeof (SHA512_CTX));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-512 context.
|
||||||
|
|
||||||
|
This function performs SHA-512 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
SHA-512 context should be already correctly initialized by Sha512Init(), and should not be finalized
|
||||||
|
by Sha512Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If Sha512Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Sha512Context Pointer to the SHA-512 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE SHA-512 data digest succeeded.
|
||||||
|
@retval FALSE SHA-512 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Update (
|
||||||
|
IN OUT VOID *Sha512Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha512Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-512 Hash Update
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA512_Update ((SHA512_CTX *) Sha512Context, Data, DataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-512 digest value.
|
||||||
|
|
||||||
|
This function completes SHA-512 hash computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the SHA-512 context cannot
|
||||||
|
be used again.
|
||||||
|
SHA-512 context should be already correctly initialized by Sha512Init(), and should not be
|
||||||
|
finalized by Sha512Final(). Behavior with invalid SHA-512 context is undefined.
|
||||||
|
|
||||||
|
If Sha512Context is NULL, then return FALSE.
|
||||||
|
If HashValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] Sha512Context Pointer to the SHA-512 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
|
||||||
|
value (64 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-512 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-512 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Final (
|
||||||
|
IN OUT VOID *Sha512Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Sha512Context == NULL || HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-512 Hash Finalization
|
||||||
|
//
|
||||||
|
return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha512Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-512 message digest of a input data buffer.
|
||||||
|
|
||||||
|
This function performs the SHA-512 message digest of a given data buffer, and places
|
||||||
|
the digest value into the specified memory.
|
||||||
|
|
||||||
|
If this interface is not supported, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
|
||||||
|
value (64 bytes).
|
||||||
|
|
||||||
|
@retval TRUE SHA-512 digest computation succeeded.
|
||||||
|
@retval FALSE SHA-512 digest computation failed.
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HashValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL SHA-512 Hash Computation.
|
||||||
|
//
|
||||||
|
if (SHA512 (Data, DataSize, HashValue) == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,281 @@
|
|||||||
|
/** @file
|
||||||
|
SHA-384 and SHA-512 Digest Wrapper Implementations which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Sha384GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] Sha384Context Pointer to SHA-384 context being initialized.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Init (
|
||||||
|
OUT VOID *Sha384Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-384 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Sha384Context Pointer to SHA-384 context being copied.
|
||||||
|
@param[out] NewSha384Context Pointer to new SHA-384 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Duplicate (
|
||||||
|
IN CONST VOID *Sha384Context,
|
||||||
|
OUT VOID *NewSha384Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-384 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Sha384Context Pointer to the SHA-384 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Update (
|
||||||
|
IN OUT VOID *Sha384Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-384 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Sha384Context Pointer to the SHA-384 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
|
||||||
|
value (48 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384Final (
|
||||||
|
IN OUT VOID *Sha384Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-384 message digest of a input data buffer.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-384 digest
|
||||||
|
value (48 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha384HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
Sha512GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] Sha512Context Pointer to SHA-512 context being initialized.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Init (
|
||||||
|
OUT VOID *Sha512Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing SHA-512 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Sha512Context Pointer to SHA-512 context being copied.
|
||||||
|
@param[out] NewSha512Context Pointer to new SHA-512 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Duplicate (
|
||||||
|
IN CONST VOID *Sha512Context,
|
||||||
|
OUT VOID *NewSha512Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates SHA-512 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Sha512Context Pointer to the SHA-512 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Update (
|
||||||
|
IN OUT VOID *Sha512Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the SHA-512 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] Sha512Context Pointer to the SHA-512 context.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
|
||||||
|
value (64 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512Final (
|
||||||
|
IN OUT VOID *Sha512Context,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes the SHA-512 message digest of a input data buffer.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be hashed.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
@param[out] HashValue Pointer to a buffer that receives the SHA-512 digest
|
||||||
|
value (64 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Sha512HashAll (
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT UINT8 *HashValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,256 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-MD5 Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#define HMAC_MD5_CTX_SIZE sizeof(void *) * 4 + sizeof(unsigned int) + \
|
||||||
|
sizeof(unsigned char) * HMAC_MAX_MD_CBLOCK
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacMd5New() / HmacMd5Free() for HMAC-MD5 Context operations.)
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for HMAC-MD5 operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves the OpenSSL HMAC-MD5 Context Size
|
||||||
|
// NOTE: HMAC_CTX object was made opaque in openssl-1.1.x, here we just use the
|
||||||
|
// fixed size as a workaround to make this API work for compatibility.
|
||||||
|
// We should retire HmacMd5GetContextSize() in future, and use HmacMd5New()
|
||||||
|
// and HmacMd5Free() for context allocation and release.
|
||||||
|
//
|
||||||
|
return (UINTN) HMAC_MD5_CTX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-MD5 use.
|
||||||
|
|
||||||
|
@return Pointer to the HMAC_CTX context that has been initialized.
|
||||||
|
If the allocations fails, HmacMd5New() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Allocates & Initializes HMAC_CTX Context by OpenSSL HMAC_CTX_new()
|
||||||
|
//
|
||||||
|
return (VOID *) HMAC_CTX_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
@param[in] HmacMd5Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Free (
|
||||||
|
IN VOID *HmacMd5Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free OpenSSL HMAC_CTX Context
|
||||||
|
//
|
||||||
|
HMAC_CTX_free ((HMAC_CTX *)HmacMd5Ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If HmacMd5Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] HmacMd5Context Pointer to HMAC-MD5 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-MD5 context initialization succeeded.
|
||||||
|
@retval FALSE HMAC-MD5 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Init (
|
||||||
|
OUT VOID *HmacMd5Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacMd5Context == NULL || KeySize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-MD5 Context Initialization
|
||||||
|
//
|
||||||
|
memset(HmacMd5Context, 0, HMAC_MD5_CTX_SIZE);
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacMd5Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_Init_ex ((HMAC_CTX *)HmacMd5Context, Key, (UINT32) KeySize, EVP_md5(), NULL) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-MD5 context.
|
||||||
|
|
||||||
|
If HmacMd5Context is NULL, then return FALSE.
|
||||||
|
If NewHmacMd5Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] HmacMd5Context Pointer to HMAC-MD5 context being copied.
|
||||||
|
@param[out] NewHmacMd5Context Pointer to new HMAC-MD5 context.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-MD5 context copy succeeded.
|
||||||
|
@retval FALSE HMAC-MD5 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Duplicate (
|
||||||
|
IN CONST VOID *HmacMd5Context,
|
||||||
|
OUT VOID *NewHmacMd5Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacMd5Context == NULL || NewHmacMd5Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HMAC_CTX_copy ((HMAC_CTX *)NewHmacMd5Context, (HMAC_CTX *)HmacMd5Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-MD5 context.
|
||||||
|
|
||||||
|
This function performs HMAC-MD5 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
HMAC-MD5 context should be already correctly initialized by HmacMd5Init(), and should not be
|
||||||
|
finalized by HmacMd5Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If HmacMd5Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacMd5Context Pointer to the HMAC-MD5 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-MD5 data digest succeeded.
|
||||||
|
@retval FALSE HMAC-MD5 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Update (
|
||||||
|
IN OUT VOID *HmacMd5Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacMd5Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-MD5 digest update
|
||||||
|
//
|
||||||
|
if (HMAC_Update ((HMAC_CTX *)HmacMd5Context, Data, DataSize) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-MD5 digest value.
|
||||||
|
|
||||||
|
This function completes HMAC-MD5 digest computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the HMAC-MD5 context cannot
|
||||||
|
be used again.
|
||||||
|
HMAC-MD5 context should be already correctly initialized by HmacMd5Init(), and should not be
|
||||||
|
finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.
|
||||||
|
|
||||||
|
If HmacMd5Context is NULL, then return FALSE.
|
||||||
|
If HmacValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacMd5Context Pointer to the HMAC-MD5 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-MD5 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval TRUE HMAC-MD5 digest computation succeeded.
|
||||||
|
@retval FALSE HMAC-MD5 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Final (
|
||||||
|
IN OUT VOID *HmacMd5Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Length;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacMd5Context == NULL || HmacValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-MD5 digest finalization
|
||||||
|
//
|
||||||
|
if (HMAC_Final ((HMAC_CTX *)HmacMd5Context, HmacValue, &Length) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacMd5Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-MD5 Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacMd5New() / HmacMd5Free() for HMAC-MD5 Context operations.)
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-MD5 use.
|
||||||
|
|
||||||
|
Return NULL to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval NULL This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
This function will do nothing.
|
||||||
|
|
||||||
|
@param[in] HmacMd5Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Free (
|
||||||
|
IN VOID *HmacMd5Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] HmacMd5Context Pointer to HMAC-MD5 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Init (
|
||||||
|
OUT VOID *HmacMd5Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-MD5 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] HmacMd5Context Pointer to HMAC-MD5 context being copied.
|
||||||
|
@param[out] NewHmacMd5Context Pointer to new HMAC-MD5 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Duplicate (
|
||||||
|
IN CONST VOID *HmacMd5Context,
|
||||||
|
OUT VOID *NewHmacMd5Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-MD5 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacMd5Context Pointer to the HMAC-MD5 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Update (
|
||||||
|
IN OUT VOID *HmacMd5Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-MD5 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacMd5Context Pointer to the HMAC-MD5 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-MD5 digest
|
||||||
|
value (16 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacMd5Final (
|
||||||
|
IN OUT VOID *HmacMd5Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,256 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-SHA1 Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#define HMAC_SHA1_CTX_SIZE sizeof(void *) * 4 + sizeof(unsigned int) + \
|
||||||
|
sizeof(unsigned char) * HMAC_MAX_MD_CBLOCK
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacSha1New() / HmacSha1Free() for HMAC-SHA1 Context operations.)
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for HMAC-SHA1 operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves the OpenSSL HMAC-SHA1 Context Size
|
||||||
|
// NOTE: HMAC_CTX object was made opaque in openssl-1.1.x, here we just use the
|
||||||
|
// fixed size as a workaround to make this API work for compatibility.
|
||||||
|
// We should retire HmacSha15GetContextSize() in future, and use HmacSha1New()
|
||||||
|
// and HmacSha1Free() for context allocation and release.
|
||||||
|
//
|
||||||
|
return (UINTN) HMAC_SHA1_CTX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA1 use.
|
||||||
|
|
||||||
|
@return Pointer to the HMAC_CTX context that has been initialized.
|
||||||
|
If the allocations fails, HmacSha1New() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Allocates & Initializes HMAC_CTX Context by OpenSSL HMAC_CTX_new()
|
||||||
|
//
|
||||||
|
return (VOID *) HMAC_CTX_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
@param[in] HmacSha1Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Free (
|
||||||
|
IN VOID *HmacSha1Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free OpenSSL HMAC_CTX Context
|
||||||
|
//
|
||||||
|
HMAC_CTX_free ((HMAC_CTX *)HmacSha1Ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If HmacSha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] HmacSha1Context Pointer to HMAC-SHA1 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA1 context initialization succeeded.
|
||||||
|
@retval FALSE HMAC-SHA1 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Init (
|
||||||
|
OUT VOID *HmacSha1Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha1Context == NULL || KeySize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA1 Context Initialization
|
||||||
|
//
|
||||||
|
memset(HmacSha1Context, 0, HMAC_SHA1_CTX_SIZE);
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacSha1Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_Init_ex ((HMAC_CTX *)HmacSha1Context, Key, (UINT32) KeySize, EVP_sha1(), NULL) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-SHA1 context.
|
||||||
|
|
||||||
|
If HmacSha1Context is NULL, then return FALSE.
|
||||||
|
If NewHmacSha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] HmacSha1Context Pointer to HMAC-SHA1 context being copied.
|
||||||
|
@param[out] NewHmacSha1Context Pointer to new HMAC-SHA1 context.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA1 context copy succeeded.
|
||||||
|
@retval FALSE HMAC-SHA1 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Duplicate (
|
||||||
|
IN CONST VOID *HmacSha1Context,
|
||||||
|
OUT VOID *NewHmacSha1Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha1Context == NULL || NewHmacSha1Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HMAC_CTX_copy ((HMAC_CTX *)NewHmacSha1Context, (HMAC_CTX *)HmacSha1Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-SHA1 context.
|
||||||
|
|
||||||
|
This function performs HMAC-SHA1 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
HMAC-SHA1 context should be already correctly initialized by HmacSha1Init(), and should not
|
||||||
|
be finalized by HmacSha1Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If HmacSha1Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA1 data digest succeeded.
|
||||||
|
@retval FALSE HMAC-SHA1 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Update (
|
||||||
|
IN OUT VOID *HmacSha1Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha1Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA1 digest update
|
||||||
|
//
|
||||||
|
if (HMAC_Update ((HMAC_CTX *)HmacSha1Context, Data, DataSize) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-SHA1 digest value.
|
||||||
|
|
||||||
|
This function completes HMAC-SHA1 digest computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the HMAC-SHA1 context cannot
|
||||||
|
be used again.
|
||||||
|
HMAC-SHA1 context should be already correctly initialized by HmacSha1Init(), and should
|
||||||
|
not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.
|
||||||
|
|
||||||
|
If HmacSha1Context is NULL, then return FALSE.
|
||||||
|
If HmacValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA1 digest
|
||||||
|
value (20 bytes).
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA1 digest computation succeeded.
|
||||||
|
@retval FALSE HMAC-SHA1 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Final (
|
||||||
|
IN OUT VOID *HmacSha1Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Length;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha1Context == NULL || HmacValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA1 digest finalization
|
||||||
|
//
|
||||||
|
if (HMAC_Final ((HMAC_CTX *)HmacSha1Context, HmacValue, &Length) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacSha1Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-SHA1 Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacSha1New() / HmacSha1Free() for HMAC-SHA1 Context operations.)
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA1 use.
|
||||||
|
|
||||||
|
Return NULL to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@return NULL This interface is not supported..
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
This function will do nothing.
|
||||||
|
|
||||||
|
@param[in] HmacSha1Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Free (
|
||||||
|
IN VOID *HmacSha1Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] HmacSha1Context Pointer to HMAC-SHA1 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Init (
|
||||||
|
OUT VOID *HmacSha1Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-SHA1 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] HmacSha1Context Pointer to HMAC-SHA1 context being copied.
|
||||||
|
@param[out] NewHmacSha1Context Pointer to new HMAC-SHA1 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Duplicate (
|
||||||
|
IN CONST VOID *HmacSha1Context,
|
||||||
|
OUT VOID *NewHmacSha1Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-SHA1 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Update (
|
||||||
|
IN OUT VOID *HmacSha1Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-SHA1 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha1Context Pointer to the HMAC-SHA1 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA1 digest
|
||||||
|
value (20 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha1Final (
|
||||||
|
IN OUT VOID *HmacSha1Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,256 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-SHA256 Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#define HMAC_SHA256_CTX_SIZE sizeof(void *) * 4 + sizeof(unsigned int) + \
|
||||||
|
sizeof(unsigned char) * HMAC_MAX_MD_CBLOCK
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA256 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacSha256New() / HmacSha256Free() for HMAC-SHA256 Context operations.)
|
||||||
|
|
||||||
|
@return The size, in bytes, of the context buffer required for HMAC-SHA256 operations.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieves the OpenSSL HMAC-SHA256 Context Size
|
||||||
|
// NOTE: HMAC_CTX object was made opaque in openssl-1.1.x, here we just use the
|
||||||
|
// fixed size as a workaround to make this API work for compatibility.
|
||||||
|
// We should retire HmacSha256GetContextSize() in future, and use HmacSha256New()
|
||||||
|
// and HmacSha256Free() for context allocation and release.
|
||||||
|
//
|
||||||
|
return (UINTN)HMAC_SHA256_CTX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use.
|
||||||
|
|
||||||
|
@return Pointer to the HMAC_CTX context that has been initialized.
|
||||||
|
If the allocations fails, HmacSha256New() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Allocates & Initializes HMAC_CTX Context by OpenSSL HMAC_CTX_new()
|
||||||
|
//
|
||||||
|
return (VOID *) HMAC_CTX_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
@param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Free (
|
||||||
|
IN VOID *HmacSha256Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free OpenSSL HMAC_CTX Context
|
||||||
|
//
|
||||||
|
HMAC_CTX_free ((HMAC_CTX *)HmacSha256Ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacSha256Context as HMAC-SHA256 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
If HmacSha256Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] HmacSha256Context Pointer to HMAC-SHA256 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA256 context initialization succeeded.
|
||||||
|
@retval FALSE HMAC-SHA256 context initialization failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Init (
|
||||||
|
OUT VOID *HmacSha256Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha256Context == NULL || KeySize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA256 Context Initialization
|
||||||
|
//
|
||||||
|
memset(HmacSha256Context, 0, HMAC_SHA256_CTX_SIZE);
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacSha256Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_Init_ex ((HMAC_CTX *)HmacSha256Context, Key, (UINT32) KeySize, EVP_sha256(), NULL) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-SHA256 context.
|
||||||
|
|
||||||
|
If HmacSha256Context is NULL, then return FALSE.
|
||||||
|
If NewHmacSha256Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] HmacSha256Context Pointer to HMAC-SHA256 context being copied.
|
||||||
|
@param[out] NewHmacSha256Context Pointer to new HMAC-SHA256 context.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA256 context copy succeeded.
|
||||||
|
@retval FALSE HMAC-SHA256 context copy failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Duplicate (
|
||||||
|
IN CONST VOID *HmacSha256Context,
|
||||||
|
OUT VOID *NewHmacSha256Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha256Context == NULL || NewHmacSha256Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HMAC_CTX_copy ((HMAC_CTX *)NewHmacSha256Context, (HMAC_CTX *)HmacSha256Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-SHA256 context.
|
||||||
|
|
||||||
|
This function performs HMAC-SHA256 digest on a data buffer of the specified size.
|
||||||
|
It can be called multiple times to compute the digest of long or discontinuous data streams.
|
||||||
|
HMAC-SHA256 context should be already correctly initialized by HmacSha256Init(), and should not
|
||||||
|
be finalized by HmacSha256Final(). Behavior with invalid context is undefined.
|
||||||
|
|
||||||
|
If HmacSha256Context is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA256 data digest succeeded.
|
||||||
|
@retval FALSE HMAC-SHA256 data digest failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Update (
|
||||||
|
IN OUT VOID *HmacSha256Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha256Context == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check invalid parameters, in case that only DataLength was checked in OpenSSL
|
||||||
|
//
|
||||||
|
if (Data == NULL && DataSize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA256 digest update
|
||||||
|
//
|
||||||
|
if (HMAC_Update ((HMAC_CTX *)HmacSha256Context, Data, DataSize) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-SHA256 digest value.
|
||||||
|
|
||||||
|
This function completes HMAC-SHA256 hash computation and retrieves the digest value into
|
||||||
|
the specified memory. After this function has been called, the HMAC-SHA256 context cannot
|
||||||
|
be used again.
|
||||||
|
HMAC-SHA256 context should be already correctly initialized by HmacSha256Init(), and should
|
||||||
|
not be finalized by HmacSha256Final(). Behavior with invalid HMAC-SHA256 context is undefined.
|
||||||
|
|
||||||
|
If HmacSha256Context is NULL, then return FALSE.
|
||||||
|
If HmacValue is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest
|
||||||
|
value (32 bytes).
|
||||||
|
|
||||||
|
@retval TRUE HMAC-SHA256 digest computation succeeded.
|
||||||
|
@retval FALSE HMAC-SHA256 digest computation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Final (
|
||||||
|
IN OUT VOID *HmacSha256Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Length;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (HmacSha256Context == NULL || HmacValue == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL HMAC-SHA256 digest finalization
|
||||||
|
//
|
||||||
|
if (HMAC_Final ((HMAC_CTX *)HmacSha256Context, HmacValue, &Length) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (HMAC_CTX_reset ((HMAC_CTX *)HmacSha256Context) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
/** @file
|
||||||
|
HMAC-SHA256 Wrapper Implementation which does not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves the size, in bytes, of the context buffer required for HMAC-SHA256 operations.
|
||||||
|
(NOTE: This API is deprecated.
|
||||||
|
Use HmacSha256New() / HmacSha256Free() for HMAC-SHA256 Context operations.)
|
||||||
|
|
||||||
|
Return zero to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@retval 0 This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256GetContextSize (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use.
|
||||||
|
|
||||||
|
Return NULL to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@return NULL This interface is not supported..
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256New (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified HMAC_CTX context.
|
||||||
|
|
||||||
|
This function will do nothing.
|
||||||
|
|
||||||
|
@param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Free (
|
||||||
|
IN VOID *HmacSha256Ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes user-supplied memory pointed by HmacSha256Context as HMAC-SHA256 context for
|
||||||
|
subsequent use.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] HmacSha256Context Pointer to HMAC-SHA256 context being initialized.
|
||||||
|
@param[in] Key Pointer to the user-supplied key.
|
||||||
|
@param[in] KeySize Key size in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Init (
|
||||||
|
OUT VOID *HmacSha256Context,
|
||||||
|
IN CONST UINT8 *Key,
|
||||||
|
IN UINTN KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Makes a copy of an existing HMAC-SHA256 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] HmacSha256Context Pointer to HMAC-SHA256 context being copied.
|
||||||
|
@param[out] NewHmacSha256Context Pointer to new HMAC-SHA256 context.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Duplicate (
|
||||||
|
IN CONST VOID *HmacSha256Context,
|
||||||
|
OUT VOID *NewHmacSha256Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Digests the input data and updates HMAC-SHA256 context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
|
||||||
|
@param[in] Data Pointer to the buffer containing the data to be digested.
|
||||||
|
@param[in] DataSize Size of Data buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Update (
|
||||||
|
IN OUT VOID *HmacSha256Context,
|
||||||
|
IN CONST VOID *Data,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Completes computation of the HMAC-SHA256 digest value.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
|
||||||
|
@param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest
|
||||||
|
value (32 bytes).
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
HmacSha256Final (
|
||||||
|
IN OUT VOID *HmacSha256Context,
|
||||||
|
OUT UINT8 *HmacValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/** @file
|
||||||
|
Internal include file for BaseCryptLib.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __INTERNAL_CRYPT_LIB_H__
|
||||||
|
#define __INTERNAL_CRYPT_LIB_H__
|
||||||
|
|
||||||
|
#undef _WIN32
|
||||||
|
#undef _WIN64
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/BaseCryptLib.h>
|
||||||
|
|
||||||
|
#include "CrtLibSupport.h"
|
||||||
|
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
#define OBJ_get0_data(o) ((o)->data)
|
||||||
|
#define OBJ_length(o) ((o)->length)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
|
||||||
|
a new structure to wrap P7Data.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input.
|
||||||
|
UEFI Authenticated Variable is external input, so this function will do basic
|
||||||
|
check for PKCS#7 data structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message to verify.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, otherwise
|
||||||
|
return FALSE.
|
||||||
|
@param[out] WrapData If return status of this function is TRUE:
|
||||||
|
1) when WrapFlag is TRUE, pointer to P7Data.
|
||||||
|
2) when WrapFlag is FALSE, pointer to a new ContentInfo
|
||||||
|
structure. It's caller's responsibility to free this
|
||||||
|
buffer.
|
||||||
|
@param[out] WrapDataSize Length of ContentInfo structure in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The operation is finished successfully.
|
||||||
|
@retval FALSE The operation is failed due to lack of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
WrapPkcs7Data (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT BOOLEAN *WrapFlag,
|
||||||
|
OUT UINT8 **WrapData,
|
||||||
|
OUT UINTN *WrapDataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,99 @@
|
|||||||
|
## @file
|
||||||
|
# Cryptographic Library Instance for PEIM.
|
||||||
|
#
|
||||||
|
# Caution: This module requires additional review when modified.
|
||||||
|
# This library will have external input - signature.
|
||||||
|
# This external input must be validated carefully to avoid security issues such as
|
||||||
|
# buffer overflow or integer overflow.
|
||||||
|
#
|
||||||
|
# Note: MD4 Digest functions,
|
||||||
|
# HMAC-MD5 functions, HMAC-SHA1/SHA256 functions, AES/TDES/ARC4 functions, RSA external
|
||||||
|
# functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, X.509
|
||||||
|
# certificate handler functions, authenticode signature verification functions,
|
||||||
|
# PEM handler functions, and pseudorandom number generator functions are not
|
||||||
|
# supported in this instance.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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
|
||||||
|
MODULE_UNI_FILE = PeiCryptLib.uni
|
||||||
|
FILE_GUID = 9a2a4375-194c-4e97-9f67-547ec98d96ca
|
||||||
|
MODULE_TYPE = PEIM
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BaseCryptLib|PEIM PEI_CORE
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
Hash/CryptMd4Null.c
|
||||||
|
Hash/CryptMd5.c
|
||||||
|
Hash/CryptSha1.c
|
||||||
|
Hash/CryptSha256.c
|
||||||
|
Hash/CryptSha512.c
|
||||||
|
Hmac/CryptHmacMd5Null.c
|
||||||
|
Hmac/CryptHmacSha1Null.c
|
||||||
|
Hmac/CryptHmacSha256Null.c
|
||||||
|
Cipher/CryptAesNull.c
|
||||||
|
Cipher/CryptTdesNull.c
|
||||||
|
Cipher/CryptArc4Null.c
|
||||||
|
|
||||||
|
Pk/CryptRsaBasic.c
|
||||||
|
Pk/CryptRsaExtNull.c
|
||||||
|
Pk/CryptPkcs5Pbkdf2Null.c
|
||||||
|
Pk/CryptPkcs7SignNull.c
|
||||||
|
Pk/CryptPkcs7VerifyCommon.c
|
||||||
|
Pk/CryptPkcs7VerifyBase.c
|
||||||
|
|
||||||
|
Pk/CryptDhNull.c
|
||||||
|
Pk/CryptX509Null.c
|
||||||
|
Pk/CryptAuthenticodeNull.c
|
||||||
|
Pk/CryptTsNull.c
|
||||||
|
Pem/CryptPemNull.c
|
||||||
|
|
||||||
|
Rand/CryptRandNull.c
|
||||||
|
|
||||||
|
SysCall/CrtWrapper.c
|
||||||
|
SysCall/ConstantTimeClock.c
|
||||||
|
SysCall/BaseMemAllocation.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
CryptoPkg/CryptoPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
DebugLib
|
||||||
|
OpensslLib
|
||||||
|
IntrinsicLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove these [BuildOptions] after this library is cleaned up
|
||||||
|
#
|
||||||
|
[BuildOptions]
|
||||||
|
#
|
||||||
|
# suppress the following warnings so we do not break the build with warnings-as-errors:
|
||||||
|
# C4090: 'function' : different 'const' qualifiers
|
||||||
|
# C4718: 'function call' : recursive call has no side effects, deleting
|
||||||
|
#
|
||||||
|
MSFT:*_*_*_CC_FLAGS = /wd4090 /wd4718
|
||||||
|
|
||||||
|
# -JCryptoPkg/Include : To disable the use of the system includes provided by RVCT
|
||||||
|
# --diag_remark=1 : Reduce severity of "#1-D: last line of file ends without a newline"
|
||||||
|
RVCT:*_*_ARM_CC_FLAGS = -JCryptoPkg/Include --diag_remark=1
|
@ -0,0 +1,31 @@
|
|||||||
|
// /** @file
|
||||||
|
// Cryptographic Library Instance for PEIM.
|
||||||
|
//
|
||||||
|
// Caution: This module requires additional review when modified.
|
||||||
|
// This library will have external input - signature.
|
||||||
|
// This external input must be validated carefully to avoid security issues such as
|
||||||
|
// buffer overflow or integer overflow.
|
||||||
|
//
|
||||||
|
// Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/
|
||||||
|
// TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions,
|
||||||
|
// Diffie-Hellman functions, X.509 certificate handler functions, authenticode
|
||||||
|
// signature verification functions, PEM handler functions, and pseudorandom number
|
||||||
|
// generator functions are not supported in this instance.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "Cryptographic Library Instance for PEIM"
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "Caution: This module requires additional review when modified. This library will have external input - signature. This external input must be validated carefully to avoid security issues such as buffer overflow or integer overflow. Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/ TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, X.509 certificate handler functions, authenticode signature verification functions, PEM handler functions, and pseudorandom number generator functions are not supported in this instance."
|
||||||
|
|
@ -0,0 +1,135 @@
|
|||||||
|
/** @file
|
||||||
|
PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Callback function for password phrase conversion used for retrieving the encrypted PEM.
|
||||||
|
|
||||||
|
@param[out] Buf Pointer to the buffer to write the passphrase to.
|
||||||
|
@param[in] Size Maximum length of the passphrase (i.e. the size of Buf).
|
||||||
|
@param[in] Flag A flag which is set to 0 when reading and 1 when writing.
|
||||||
|
@param[in] Key Key data to be passed to the callback routine.
|
||||||
|
|
||||||
|
@retval The number of characters in the passphrase or 0 if an error occurred.
|
||||||
|
|
||||||
|
**/
|
||||||
|
INTN
|
||||||
|
PasswordCallback (
|
||||||
|
OUT CHAR8 *Buf,
|
||||||
|
IN INTN Size,
|
||||||
|
IN INTN Flag,
|
||||||
|
IN VOID *Key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTN KeyLength;
|
||||||
|
|
||||||
|
ZeroMem ((VOID *) Buf, (UINTN) Size);
|
||||||
|
if (Key != NULL) {
|
||||||
|
//
|
||||||
|
// Duplicate key phrase directly.
|
||||||
|
//
|
||||||
|
KeyLength = (INTN) AsciiStrLen ((CHAR8 *)Key);
|
||||||
|
KeyLength = (KeyLength > Size ) ? Size : KeyLength;
|
||||||
|
CopyMem (Buf, Key, (UINTN) KeyLength);
|
||||||
|
return KeyLength;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the RSA Private Key from the password-protected PEM key data.
|
||||||
|
|
||||||
|
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
|
||||||
|
@param[in] PemSize Size of the PEM key data in bytes.
|
||||||
|
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
|
||||||
|
@param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved
|
||||||
|
RSA private key component. Use RsaFree() function to free the
|
||||||
|
resource.
|
||||||
|
|
||||||
|
If PemData is NULL, then return FALSE.
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@retval TRUE RSA Private Key was retrieved successfully.
|
||||||
|
@retval FALSE Invalid PEM key data or incorrect password.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetPrivateKeyFromPem (
|
||||||
|
IN CONST UINT8 *PemData,
|
||||||
|
IN UINTN PemSize,
|
||||||
|
IN CONST CHAR8 *Password,
|
||||||
|
OUT VOID **RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
BIO *PemBio;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (PemData == NULL || RsaContext == NULL || PemSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add possible block-cipher descriptor for PEM data decryption.
|
||||||
|
// NOTE: Only support most popular ciphers (3DES, AES) for the encrypted PEM.
|
||||||
|
//
|
||||||
|
if (EVP_add_cipher (EVP_des_ede3_cbc ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read encrypted PEM Data.
|
||||||
|
//
|
||||||
|
PemBio = BIO_new (BIO_s_mem ());
|
||||||
|
if (PemBio == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BIO_write (PemBio, PemData, (int) PemSize) <= 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve RSA Private Key from encrypted PEM data.
|
||||||
|
//
|
||||||
|
*RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *) &PasswordCallback, (void *) Password);
|
||||||
|
if (*RsaContext != NULL) {
|
||||||
|
Status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
BIO_free (PemBio);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/** @file
|
||||||
|
PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation which does
|
||||||
|
not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the RSA Private Key from the password-protected PEM key data.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
|
||||||
|
@param[in] PemSize Size of the PEM key data in bytes.
|
||||||
|
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
|
||||||
|
@param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved
|
||||||
|
RSA private key component. Use RsaFree() function to free the
|
||||||
|
resource.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetPrivateKeyFromPem (
|
||||||
|
IN CONST UINT8 *PemData,
|
||||||
|
IN UINTN PemSize,
|
||||||
|
IN CONST CHAR8 *Password,
|
||||||
|
OUT VOID **RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,198 @@
|
|||||||
|
/** @file
|
||||||
|
Authenticode Portable Executable Signature Verification over OpenSSL.
|
||||||
|
|
||||||
|
Caution: This module requires additional review when modified.
|
||||||
|
This library will have external input - signature (e.g. PE/COFF Authenticode).
|
||||||
|
This external input must be validated carefully to avoid security issue like
|
||||||
|
buffer overflow, integer overflow.
|
||||||
|
|
||||||
|
AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for
|
||||||
|
data structure.
|
||||||
|
|
||||||
|
Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/pkcs7.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID
|
||||||
|
//
|
||||||
|
UINT8 mSpcIndirectOidValue[] = {
|
||||||
|
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a PE/COFF Authenticode Signature as described in "Windows
|
||||||
|
Authenticode Portable Executable Signature Format".
|
||||||
|
|
||||||
|
If AuthData is NULL, then return FALSE.
|
||||||
|
If ImageHash is NULL, then return FALSE.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input.
|
||||||
|
PE/COFF Authenticode is external input, so this function will do basic check for
|
||||||
|
Authenticode data structure.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
|
||||||
|
PE/COFF image to be verified.
|
||||||
|
@param[in] DataSize Size of the Authenticode Signature in bytes.
|
||||||
|
@param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
|
||||||
|
is used for certificate chain verification.
|
||||||
|
@param[in] CertSize Size of the trusted certificate in bytes.
|
||||||
|
@param[in] ImageHash Pointer to the original image file hash value. The procedure
|
||||||
|
for calculating the image hash value is described in Authenticode
|
||||||
|
specification.
|
||||||
|
@param[in] HashSize Size of Image hash value in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The specified Authenticode Signature is valid.
|
||||||
|
@retval FALSE Invalid Authenticode Signature.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AuthenticodeVerify (
|
||||||
|
IN CONST UINT8 *AuthData,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN CONST UINT8 *TrustedCert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN CONST UINT8 *ImageHash,
|
||||||
|
IN UINTN HashSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
CONST UINT8 *OrigAuthData;
|
||||||
|
UINT8 *SpcIndirectDataContent;
|
||||||
|
UINT8 Asn1Byte;
|
||||||
|
UINTN ContentSize;
|
||||||
|
CONST UINT8 *SpcIndirectDataOid;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if ((AuthData == NULL) || (TrustedCert == NULL) || (ImageHash == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((DataSize > INT_MAX) || (CertSize > INT_MAX) || (HashSize > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
OrigAuthData = AuthData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve & Parse PKCS#7 Data (DER encoding) from Authenticode Signature
|
||||||
|
//
|
||||||
|
Temp = AuthData;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, &Temp, (int)DataSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
|
||||||
|
//
|
||||||
|
if (!PKCS7_type_is_signed (Pkcs7)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// NOTE: OpenSSL PKCS7 Decoder 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.
|
||||||
|
//
|
||||||
|
SpcIndirectDataOid = OBJ_get0_data(Pkcs7->d.sign->contents->type);
|
||||||
|
if (OBJ_length(Pkcs7->d.sign->contents->type) != sizeof(mSpcIndirectOidValue) ||
|
||||||
|
CompareMem (
|
||||||
|
SpcIndirectDataOid,
|
||||||
|
mSpcIndirectOidValue,
|
||||||
|
sizeof (mSpcIndirectOidValue)
|
||||||
|
) != 0) {
|
||||||
|
//
|
||||||
|
// Un-matched SPC_INDIRECT_DATA_OBJID.
|
||||||
|
//
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SpcIndirectDataContent = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the SEQUENCE data size from ASN.1-encoded SpcIndirectDataContent.
|
||||||
|
//
|
||||||
|
Asn1Byte = *(SpcIndirectDataContent + 1);
|
||||||
|
|
||||||
|
if ((Asn1Byte & 0x80) == 0) {
|
||||||
|
//
|
||||||
|
// Short Form of Length Encoding (Length < 128)
|
||||||
|
//
|
||||||
|
ContentSize = (UINTN) (Asn1Byte & 0x7F);
|
||||||
|
//
|
||||||
|
// Skip the SEQUENCE Tag;
|
||||||
|
//
|
||||||
|
SpcIndirectDataContent += 2;
|
||||||
|
|
||||||
|
} else if ((Asn1Byte & 0x81) == 0x81) {
|
||||||
|
//
|
||||||
|
// Long Form of Length Encoding (128 <= Length < 255, Single Octet)
|
||||||
|
//
|
||||||
|
ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));
|
||||||
|
//
|
||||||
|
// Skip the SEQUENCE Tag;
|
||||||
|
//
|
||||||
|
SpcIndirectDataContent += 3;
|
||||||
|
|
||||||
|
} else if ((Asn1Byte & 0x82) == 0x82) {
|
||||||
|
//
|
||||||
|
// Long Form of Length Encoding (Length > 255, Two Octet)
|
||||||
|
//
|
||||||
|
ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));
|
||||||
|
ContentSize = (ContentSize << 8) + (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 3));
|
||||||
|
//
|
||||||
|
// Skip the SEQUENCE Tag;
|
||||||
|
//
|
||||||
|
SpcIndirectDataContent += 4;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare the original file hash value to the digest retrieve from SpcIndirectDataContent
|
||||||
|
// defined in Authenticode
|
||||||
|
// NOTE: Need to double-check HashLength here!
|
||||||
|
//
|
||||||
|
if (CompareMem (SpcIndirectDataContent + ContentSize - HashSize, ImageHash, HashSize) != 0) {
|
||||||
|
//
|
||||||
|
// Un-matched PE/COFF Hash Value
|
||||||
|
//
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verifies the PKCS#7 Signed Data in PE/COFF Authenticode Signature
|
||||||
|
//
|
||||||
|
Status = (BOOLEAN) Pkcs7Verify (OrigAuthData, DataSize, TrustedCert, CertSize, SpcIndirectDataContent, ContentSize);
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/** @file
|
||||||
|
Authenticode Portable Executable Signature Verification which does not provide
|
||||||
|
real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a PE/COFF Authenticode Signature as described in "Windows
|
||||||
|
Authenticode Portable Executable Signature Format".
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
|
||||||
|
PE/COFF image to be verified.
|
||||||
|
@param[in] DataSize Size of the Authenticode Signature in bytes.
|
||||||
|
@param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
|
||||||
|
is used for certificate chain verification.
|
||||||
|
@param[in] CertSize Size of the trusted certificate in bytes.
|
||||||
|
@param[in] ImageHash Pointer to the original image file hash value. The procedure
|
||||||
|
for calculating the image hash value is described in Authenticode
|
||||||
|
specification.
|
||||||
|
@param[in] HashSize Size of Image hash value in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
AuthenticodeVerify (
|
||||||
|
IN CONST UINT8 *AuthData,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN CONST UINT8 *TrustedCert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN CONST UINT8 *ImageHash,
|
||||||
|
IN UINTN HashSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,312 @@
|
|||||||
|
/** @file
|
||||||
|
Diffie-Hellman Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/dh.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and Initializes one Diffie-Hellman Context for subsequent use.
|
||||||
|
|
||||||
|
@return Pointer to the Diffie-Hellman Context that has been initialized.
|
||||||
|
If the allocations fails, DhNew() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
DhNew (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Allocates & Initializes DH Context by OpenSSL DH_new()
|
||||||
|
//
|
||||||
|
return (VOID *) DH_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified DH context.
|
||||||
|
|
||||||
|
If DhContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] DhContext Pointer to the DH context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DhFree (
|
||||||
|
IN VOID *DhContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Free OpenSSL DH Context
|
||||||
|
//
|
||||||
|
DH_free ((DH *) DhContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates DH parameter.
|
||||||
|
|
||||||
|
Given generator g, and length of prime number p in bits, this function generates p,
|
||||||
|
and sets DH context according to value of g and p.
|
||||||
|
|
||||||
|
Before this function can be invoked, pseudorandom number generator must be correctly
|
||||||
|
initialized by RandomSeed().
|
||||||
|
|
||||||
|
If DhContext is NULL, then return FALSE.
|
||||||
|
If Prime is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] Generator Value of generator.
|
||||||
|
@param[in] PrimeLength Length in bits of prime to be generated.
|
||||||
|
@param[out] Prime Pointer to the buffer to receive the generated prime number.
|
||||||
|
|
||||||
|
@retval TRUE DH parameter generation succeeded.
|
||||||
|
@retval FALSE Value of Generator is not supported.
|
||||||
|
@retval FALSE PRNG fails to generate random prime number with PrimeLength.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhGenerateParameter (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN UINTN Generator,
|
||||||
|
IN UINTN PrimeLength,
|
||||||
|
OUT UINT8 *Prime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN RetVal;
|
||||||
|
BIGNUM *BnP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RetVal = (BOOLEAN) DH_generate_parameters_ex (DhContext, (UINT32) PrimeLength, (UINT32) Generator, NULL);
|
||||||
|
if (!RetVal) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DH_get0_pqg (DhContext, (const BIGNUM **)&BnP, NULL, NULL);
|
||||||
|
BN_bn2bin (BnP, Prime);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets generator and prime parameters for DH.
|
||||||
|
|
||||||
|
Given generator g, and prime number p, this function and sets DH
|
||||||
|
context accordingly.
|
||||||
|
|
||||||
|
If DhContext is NULL, then return FALSE.
|
||||||
|
If Prime is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] Generator Value of generator.
|
||||||
|
@param[in] PrimeLength Length in bits of prime to be generated.
|
||||||
|
@param[in] Prime Pointer to the prime number.
|
||||||
|
|
||||||
|
@retval TRUE DH parameter setting succeeded.
|
||||||
|
@retval FALSE Value of Generator is not supported.
|
||||||
|
@retval FALSE Value of Generator is not suitable for the Prime.
|
||||||
|
@retval FALSE Value of Prime is not a prime number.
|
||||||
|
@retval FALSE Value of Prime is not a safe prime number.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhSetParameter (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN UINTN Generator,
|
||||||
|
IN UINTN PrimeLength,
|
||||||
|
IN CONST UINT8 *Prime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DH *Dh;
|
||||||
|
BIGNUM *BnP;
|
||||||
|
BIGNUM *BnG;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the generator and prime parameters for DH object.
|
||||||
|
//
|
||||||
|
Dh = (DH *)DhContext;
|
||||||
|
BnP = BN_bin2bn ((const unsigned char *)Prime, (int)(PrimeLength / 8), NULL);
|
||||||
|
BnG = BN_bin2bn ((const unsigned char *)&Generator, 1, NULL);
|
||||||
|
if ((BnP == NULL) || (BnG == NULL) || !DH_set0_pqg (Dh, BnP, NULL, BnG)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Error:
|
||||||
|
BN_free (BnP);
|
||||||
|
BN_free (BnG);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates DH public key.
|
||||||
|
|
||||||
|
This function generates random secret exponent, and computes the public key, which is
|
||||||
|
returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.
|
||||||
|
If the PublicKey buffer is too small to hold the public key, FALSE is returned and
|
||||||
|
PublicKeySize is set to the required buffer size to obtain the public key.
|
||||||
|
|
||||||
|
If DhContext is NULL, then return FALSE.
|
||||||
|
If PublicKeySize is NULL, then return FALSE.
|
||||||
|
If PublicKeySize is large enough but PublicKey is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[out] PublicKey Pointer to the buffer to receive generated public key.
|
||||||
|
@param[in, out] PublicKeySize On input, the size of PublicKey buffer in bytes.
|
||||||
|
On output, the size of data returned in PublicKey buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE DH public key generation succeeded.
|
||||||
|
@retval FALSE DH public key generation failed.
|
||||||
|
@retval FALSE PublicKeySize is not large enough.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhGenerateKey (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
OUT UINT8 *PublicKey,
|
||||||
|
IN OUT UINTN *PublicKeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN RetVal;
|
||||||
|
DH *Dh;
|
||||||
|
BIGNUM *DhPubKey;
|
||||||
|
INTN Size;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (DhContext == NULL || PublicKeySize == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PublicKey == NULL && *PublicKeySize != 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dh = (DH *) DhContext;
|
||||||
|
|
||||||
|
RetVal = (BOOLEAN) DH_generate_key (DhContext);
|
||||||
|
if (RetVal) {
|
||||||
|
DH_get0_key (Dh, (const BIGNUM **)&DhPubKey, NULL);
|
||||||
|
Size = BN_num_bytes (DhPubKey);
|
||||||
|
if ((Size > 0) && (*PublicKeySize < (UINTN) Size)) {
|
||||||
|
*PublicKeySize = Size;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PublicKey != NULL) {
|
||||||
|
BN_bn2bin (DhPubKey, PublicKey);
|
||||||
|
}
|
||||||
|
*PublicKeySize = Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes exchanged common key.
|
||||||
|
|
||||||
|
Given peer's public key, this function computes the exchanged common key, based on its own
|
||||||
|
context including value of prime modulus and random secret exponent.
|
||||||
|
|
||||||
|
If DhContext is NULL, then return FALSE.
|
||||||
|
If PeerPublicKey is NULL, then return FALSE.
|
||||||
|
If KeySize is NULL, then return FALSE.
|
||||||
|
If Key is NULL, then return FALSE.
|
||||||
|
If KeySize is not large enough, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] PeerPublicKey Pointer to the peer's public key.
|
||||||
|
@param[in] PeerPublicKeySize Size of peer's public key in bytes.
|
||||||
|
@param[out] Key Pointer to the buffer to receive generated key.
|
||||||
|
@param[in, out] KeySize On input, the size of Key buffer in bytes.
|
||||||
|
On output, the size of data returned in Key buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE DH exchanged key generation succeeded.
|
||||||
|
@retval FALSE DH exchanged key generation failed.
|
||||||
|
@retval FALSE KeySize is not large enough.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhComputeKey (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN CONST UINT8 *PeerPublicKey,
|
||||||
|
IN UINTN PeerPublicKeySize,
|
||||||
|
OUT UINT8 *Key,
|
||||||
|
IN OUT UINTN *KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BIGNUM *Bn;
|
||||||
|
INTN Size;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL || Key == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PeerPublicKeySize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);
|
||||||
|
if (Bn == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size = DH_compute_key (Key, Bn, DhContext);
|
||||||
|
if (Size < 0) {
|
||||||
|
BN_free (Bn);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*KeySize < (UINTN) Size) {
|
||||||
|
*KeySize = Size;
|
||||||
|
BN_free (Bn);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*KeySize = Size;
|
||||||
|
BN_free (Bn);
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/** @file
|
||||||
|
Diffie-Hellman Wrapper Implementation which does not provide
|
||||||
|
real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocates and Initializes one Diffie-Hellman Context for subsequent use.
|
||||||
|
|
||||||
|
@return Pointer to the Diffie-Hellman Context that has been initialized.
|
||||||
|
If the interface is not supported, DhNew() returns NULL.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
DhNew (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified DH context.
|
||||||
|
|
||||||
|
If the interface is not supported, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] DhContext Pointer to the DH context to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
DhFree (
|
||||||
|
IN VOID *DhContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates DH parameter.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] Generator Value of generator.
|
||||||
|
@param[in] PrimeLength Length in bits of prime to be generated.
|
||||||
|
@param[out] Prime Pointer to the buffer to receive the generated prime number.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhGenerateParameter (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN UINTN Generator,
|
||||||
|
IN UINTN PrimeLength,
|
||||||
|
OUT UINT8 *Prime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets generator and prime parameters for DH.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] Generator Value of generator.
|
||||||
|
@param[in] PrimeLength Length in bits of prime to be generated.
|
||||||
|
@param[in] Prime Pointer to the prime number.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhSetParameter (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN UINTN Generator,
|
||||||
|
IN UINTN PrimeLength,
|
||||||
|
IN CONST UINT8 *Prime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates DH public key.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[out] PublicKey Pointer to the buffer to receive generated public key.
|
||||||
|
@param[in, out] PublicKeySize On input, the size of PublicKey buffer in bytes.
|
||||||
|
On output, the size of data returned in PublicKey buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhGenerateKey (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
OUT UINT8 *PublicKey,
|
||||||
|
IN OUT UINTN *PublicKeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Computes exchanged common key.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] DhContext Pointer to the DH context.
|
||||||
|
@param[in] PeerPublicKey Pointer to the peer's public key.
|
||||||
|
@param[in] PeerPublicKeySize Size of peer's public key in bytes.
|
||||||
|
@param[out] Key Pointer to the buffer to receive generated key.
|
||||||
|
@param[in, out] KeySize On input, the size of Key buffer in bytes.
|
||||||
|
On output, the size of data returned in Key buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
DhComputeKey (
|
||||||
|
IN OUT VOID *DhContext,
|
||||||
|
IN CONST UINT8 *PeerPublicKey,
|
||||||
|
IN UINTN PeerPublicKeySize,
|
||||||
|
OUT UINT8 *Key,
|
||||||
|
IN OUT UINTN *KeySize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
/** @file
|
||||||
|
PBKDF2 Key Derivation Function Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
|
||||||
|
password based encryption key derivation function PBKDF2, as specified in RFC 2898.
|
||||||
|
|
||||||
|
If Password or Salt or OutKey is NULL, then return FALSE.
|
||||||
|
If the hash algorithm could not be determined, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] PasswordLength Length of input password in bytes.
|
||||||
|
@param[in] Password Pointer to the array for the password.
|
||||||
|
@param[in] SaltLength Size of the Salt in bytes.
|
||||||
|
@param[in] Salt Pointer to the Salt.
|
||||||
|
@param[in] IterationCount Number of iterations to perform. Its value should be
|
||||||
|
greater than or equal to 1.
|
||||||
|
@param[in] DigestSize Size of the message digest to be used (eg. SHA256_DIGEST_SIZE).
|
||||||
|
NOTE: DigestSize will be used to determine the hash algorithm.
|
||||||
|
Only SHA1_DIGEST_SIZE or SHA256_DIGEST_SIZE is supported.
|
||||||
|
@param[in] KeyLength Size of the derived key buffer in bytes.
|
||||||
|
@param[out] OutKey Pointer to the output derived key buffer.
|
||||||
|
|
||||||
|
@retval TRUE A key was derived successfully.
|
||||||
|
@retval FALSE One of the pointers was NULL or one of the sizes was too large.
|
||||||
|
@retval FALSE The hash algorithm could not be determined from the digest size.
|
||||||
|
@retval FALSE The key derivation operation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs5HashPassword (
|
||||||
|
IN UINTN PasswordLength,
|
||||||
|
IN CONST CHAR8 *Password,
|
||||||
|
IN UINTN SaltLength,
|
||||||
|
IN CONST UINT8 *Salt,
|
||||||
|
IN UINTN IterationCount,
|
||||||
|
IN UINTN DigestSize,
|
||||||
|
IN UINTN KeyLength,
|
||||||
|
OUT UINT8 *OutKey
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CONST EVP_MD *HashAlg;
|
||||||
|
|
||||||
|
HashAlg = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parameter Checking.
|
||||||
|
//
|
||||||
|
if ((Password == NULL) || (Salt == NULL) || (OutKey == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ((PasswordLength == 0) || (PasswordLength > INT_MAX) ||
|
||||||
|
(SaltLength == 0) || (SaltLength > INT_MAX) ||
|
||||||
|
(KeyLength == 0) || (KeyLength > INT_MAX) ||
|
||||||
|
(IterationCount < 1) || (IterationCount > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure the digest algorithm is supported.
|
||||||
|
//
|
||||||
|
switch (DigestSize) {
|
||||||
|
case SHA1_DIGEST_SIZE:
|
||||||
|
HashAlg = EVP_sha1();
|
||||||
|
break;
|
||||||
|
case SHA256_DIGEST_SIZE:
|
||||||
|
HashAlg = EVP_sha256();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Perform password-based key derivation routines.
|
||||||
|
//
|
||||||
|
return (BOOLEAN)PKCS5_PBKDF2_HMAC (
|
||||||
|
(const char *)Password,
|
||||||
|
(int)PasswordLength,
|
||||||
|
(const unsigned char *)Salt,
|
||||||
|
(int)SaltLength,
|
||||||
|
(int)IterationCount,
|
||||||
|
HashAlg,
|
||||||
|
(int)KeyLength,
|
||||||
|
(unsigned char *)OutKey
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/** @file
|
||||||
|
PBKDF2 Key Derivation Function Wrapper Implementation which does not provide real
|
||||||
|
capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
|
||||||
|
password based encryption key derivation function PBKDF2, as specified in RFC 2898.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] PasswordLength Length of input password in bytes.
|
||||||
|
@param[in] Password Pointer to the array for the password.
|
||||||
|
@param[in] SaltLength Size of the Salt in bytes.
|
||||||
|
@param[in] Salt Pointer to the Salt.
|
||||||
|
@param[in] IterationCount Number of iterations to perform. Its value should be
|
||||||
|
greater than or equal to 1.
|
||||||
|
@param[in] DigestSize Size of the message digest to be used (eg. SHA256_DIGEST_SIZE).
|
||||||
|
NOTE: DigestSize will be used to determine the hash algorithm.
|
||||||
|
Only SHA1_DIGEST_SIZE or SHA256_DIGEST_SIZE is supported.
|
||||||
|
@param[in] KeyLength Size of the derived key buffer in bytes.
|
||||||
|
@param[out] OutKey Pointer to the output derived key buffer.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs5HashPassword (
|
||||||
|
IN UINTN PasswordLength,
|
||||||
|
IN CONST CHAR8 *Password,
|
||||||
|
IN UINTN SaltLength,
|
||||||
|
IN CONST UINT8 *Salt,
|
||||||
|
IN UINTN IterationCount,
|
||||||
|
IN UINTN DigestSize,
|
||||||
|
IN UINTN KeyLength,
|
||||||
|
OUT UINT8 *OutKey
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,200 @@
|
|||||||
|
/** @file
|
||||||
|
PKCS#7 SignedData Sign Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/pkcs7.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
|
||||||
|
Syntax Standard, version 1.5". This interface is only intended to be used for
|
||||||
|
application to perform PKCS#7 functionality validation.
|
||||||
|
|
||||||
|
@param[in] PrivateKey Pointer to the PEM-formatted private key data for
|
||||||
|
data signing.
|
||||||
|
@param[in] PrivateKeySize Size of the PEM private key data in bytes.
|
||||||
|
@param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM
|
||||||
|
key data.
|
||||||
|
@param[in] InData Pointer to the content to be signed.
|
||||||
|
@param[in] InDataSize Size of InData in bytes.
|
||||||
|
@param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.
|
||||||
|
@param[in] OtherCerts Pointer to an optional additional set of certificates to
|
||||||
|
include in the PKCS#7 signedData (e.g. any intermediate
|
||||||
|
CAs in the chain).
|
||||||
|
@param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's
|
||||||
|
responsibility to free the buffer with FreePool().
|
||||||
|
@param[out] SignedDataSize Size of SignedData in bytes.
|
||||||
|
|
||||||
|
@retval TRUE PKCS#7 data signing succeeded.
|
||||||
|
@retval FALSE PKCS#7 data signing failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7Sign (
|
||||||
|
IN CONST UINT8 *PrivateKey,
|
||||||
|
IN UINTN PrivateKeySize,
|
||||||
|
IN CONST UINT8 *KeyPassword,
|
||||||
|
IN UINT8 *InData,
|
||||||
|
IN UINTN InDataSize,
|
||||||
|
IN UINT8 *SignCert,
|
||||||
|
IN UINT8 *OtherCerts OPTIONAL,
|
||||||
|
OUT UINT8 **SignedData,
|
||||||
|
OUT UINTN *SignedDataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
EVP_PKEY *Key;
|
||||||
|
BIO *DataBio;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
UINT8 *RsaContext;
|
||||||
|
UINT8 *P7Data;
|
||||||
|
UINTN P7DataSize;
|
||||||
|
UINT8 *Tmp;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (PrivateKey == NULL || KeyPassword == NULL || InData == NULL ||
|
||||||
|
SignCert == NULL || SignedData == NULL || SignedDataSize == NULL || InDataSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsaContext = NULL;
|
||||||
|
Key = NULL;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
DataBio = NULL;
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve RSA private key from PEM data.
|
||||||
|
//
|
||||||
|
Status = RsaGetPrivateKeyFromPem (
|
||||||
|
PrivateKey,
|
||||||
|
PrivateKeySize,
|
||||||
|
(CONST CHAR8 *) KeyPassword,
|
||||||
|
(VOID **) &RsaContext
|
||||||
|
);
|
||||||
|
if (!Status) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register & Initialize necessary digest algorithms and PRNG for PKCS#7 Handling
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_md5 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha256 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomSeed (NULL, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct OpenSSL EVP_PKEY for private key.
|
||||||
|
//
|
||||||
|
Key = EVP_PKEY_new ();
|
||||||
|
if (Key == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (EVP_PKEY_assign_RSA (Key, (RSA *) RsaContext) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert the data to be signed to BIO format.
|
||||||
|
//
|
||||||
|
DataBio = BIO_new (BIO_s_mem ());
|
||||||
|
if (DataBio == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BIO_write (DataBio, InData, (int) InDataSize) <= 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the PKCS#7 signedData structure.
|
||||||
|
//
|
||||||
|
Pkcs7 = PKCS7_sign (
|
||||||
|
(X509 *) SignCert,
|
||||||
|
Key,
|
||||||
|
(STACK_OF(X509) *) OtherCerts,
|
||||||
|
DataBio,
|
||||||
|
PKCS7_BINARY | PKCS7_NOATTR | PKCS7_DETACHED
|
||||||
|
);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert PKCS#7 signedData structure into DER-encoded buffer.
|
||||||
|
//
|
||||||
|
P7DataSize = i2d_PKCS7 (Pkcs7, NULL);
|
||||||
|
if (P7DataSize <= 19) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
P7Data = malloc (P7DataSize);
|
||||||
|
if (P7Data == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tmp = P7Data;
|
||||||
|
P7DataSize = i2d_PKCS7 (Pkcs7, (unsigned char **) &Tmp);
|
||||||
|
ASSERT (P7DataSize > 19);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Strip ContentInfo to content only for signeddata. The data be trimmed off
|
||||||
|
// is totally 19 bytes.
|
||||||
|
//
|
||||||
|
*SignedDataSize = P7DataSize - 19;
|
||||||
|
*SignedData = AllocatePool (*SignedDataSize);
|
||||||
|
if (*SignedData == NULL) {
|
||||||
|
OPENSSL_free (P7Data);
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (*SignedData, P7Data + 19, *SignedDataSize);
|
||||||
|
|
||||||
|
OPENSSL_free (P7Data);
|
||||||
|
|
||||||
|
Status = TRUE;
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
if (Key != NULL) {
|
||||||
|
EVP_PKEY_free (Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataBio != NULL) {
|
||||||
|
BIO_free (DataBio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pkcs7 != NULL) {
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/** @file
|
||||||
|
PKCS#7 SignedData Sign Wrapper Implementation which does not provide real
|
||||||
|
capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
|
||||||
|
Syntax Standard, version 1.5". This interface is only intended to be used for
|
||||||
|
application to perform PKCS#7 functionality validation.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] PrivateKey Pointer to the PEM-formatted private key data for
|
||||||
|
data signing.
|
||||||
|
@param[in] PrivateKeySize Size of the PEM private key data in bytes.
|
||||||
|
@param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM
|
||||||
|
key data.
|
||||||
|
@param[in] InData Pointer to the content to be signed.
|
||||||
|
@param[in] InDataSize Size of InData in bytes.
|
||||||
|
@param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.
|
||||||
|
@param[in] OtherCerts Pointer to an optional additional set of certificates to
|
||||||
|
include in the PKCS#7 signedData (e.g. any intermediate
|
||||||
|
CAs in the chain).
|
||||||
|
@param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's
|
||||||
|
responsibility to free the buffer with FreePool().
|
||||||
|
@param[out] SignedDataSize Size of SignedData in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7Sign (
|
||||||
|
IN CONST UINT8 *PrivateKey,
|
||||||
|
IN UINTN PrivateKeySize,
|
||||||
|
IN CONST UINT8 *KeyPassword,
|
||||||
|
IN UINT8 *InData,
|
||||||
|
IN UINTN InDataSize,
|
||||||
|
IN UINT8 *SignCert,
|
||||||
|
IN UINT8 *OtherCerts OPTIONAL,
|
||||||
|
OUT UINT8 **SignedData,
|
||||||
|
OUT UINTN *SignedDataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
|||||||
|
/** @file
|
||||||
|
Non-runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
|
||||||
|
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/pkcs7.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
|
||||||
|
data could be wrapped in a ContentInfo structure.
|
||||||
|
|
||||||
|
If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,
|
||||||
|
then return FALSE. If the P7Data is not correctly formatted, then return FALSE.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input. So this function will do
|
||||||
|
basic check for PKCS#7 data structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
|
||||||
|
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
|
||||||
|
It's caller's responsibility to free the buffer with FreePool().
|
||||||
|
@param[out] ContentSize The size of the extracted content in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The P7Data was correctly formatted for processing.
|
||||||
|
@retval FALSE The P7Data was not correctly formatted for processing.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetAttachedContent (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT VOID **Content,
|
||||||
|
OUT UINTN *ContentSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
UINT8 *SignedData;
|
||||||
|
UINTN SignedDataSize;
|
||||||
|
BOOLEAN Wrapped;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
ASN1_OCTET_STRING *OctStr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameter.
|
||||||
|
//
|
||||||
|
if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Content = NULL;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
SignedData = NULL;
|
||||||
|
OctStr = NULL;
|
||||||
|
|
||||||
|
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
|
||||||
|
if (!Status || (SignedDataSize > INT_MAX)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Decoding PKCS#7 SignedData
|
||||||
|
//
|
||||||
|
Temp = SignedData;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The type of Pkcs7 must be signedData
|
||||||
|
//
|
||||||
|
if (!PKCS7_type_is_signed (Pkcs7)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check for detached or attached content
|
||||||
|
//
|
||||||
|
if (PKCS7_get_detached (Pkcs7)) {
|
||||||
|
//
|
||||||
|
// No Content supplied for PKCS7 detached signedData
|
||||||
|
//
|
||||||
|
*Content = NULL;
|
||||||
|
*ContentSize = 0;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Retrieve the attached content in PKCS7 signedData
|
||||||
|
//
|
||||||
|
OctStr = Pkcs7->d.sign->contents->d.data;
|
||||||
|
if ((OctStr->length > 0) && (OctStr->data != NULL)) {
|
||||||
|
*ContentSize = OctStr->length;
|
||||||
|
*Content = AllocatePool (*ContentSize);
|
||||||
|
if (*Content == NULL) {
|
||||||
|
*ContentSize = 0;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
CopyMem (*Content, OctStr->data, *ContentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Status = TRUE;
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
|
||||||
|
if (!Wrapped) {
|
||||||
|
OPENSSL_free (SignedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -0,0 +1,916 @@
|
|||||||
|
/** @file
|
||||||
|
PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Caution: This module requires additional review when modified.
|
||||||
|
This library will have external input - signature (e.g. UEFI Authenticated
|
||||||
|
Variable). It may by input in SMM mode.
|
||||||
|
This external input must be validated carefully to avoid security issue like
|
||||||
|
buffer overflow, integer overflow.
|
||||||
|
|
||||||
|
WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated
|
||||||
|
Variable and will do basic check for data structure.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/pkcs7.h>
|
||||||
|
|
||||||
|
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
|
||||||
|
a new structure to wrap P7Data.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input.
|
||||||
|
UEFI Authenticated Variable is external input, so this function will do basic
|
||||||
|
check for PKCS#7 data structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message to verify.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, otherwise
|
||||||
|
return FALSE.
|
||||||
|
@param[out] WrapData If return status of this function is TRUE:
|
||||||
|
1) when WrapFlag is TRUE, pointer to P7Data.
|
||||||
|
2) when WrapFlag is FALSE, pointer to a new ContentInfo
|
||||||
|
structure. It's caller's responsibility to free this
|
||||||
|
buffer.
|
||||||
|
@param[out] WrapDataSize Length of ContentInfo structure in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The operation is finished successfully.
|
||||||
|
@retval FALSE The operation is failed due to lack of resources.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
WrapPkcs7Data (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT BOOLEAN *WrapFlag,
|
||||||
|
OUT UINT8 **WrapData,
|
||||||
|
OUT UINTN *WrapDataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Wrapped;
|
||||||
|
UINT8 *SignedData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether input P7Data is a wrapped ContentInfo structure or not.
|
||||||
|
//
|
||||||
|
Wrapped = FALSE;
|
||||||
|
if ((P7Data[4] == 0x06) && (P7Data[5] == 0x09)) {
|
||||||
|
if (CompareMem (P7Data + 6, mOidValue, sizeof (mOidValue)) == 0) {
|
||||||
|
if ((P7Data[15] == 0xA0) && (P7Data[16] == 0x82)) {
|
||||||
|
Wrapped = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Wrapped) {
|
||||||
|
*WrapData = (UINT8 *) P7Data;
|
||||||
|
*WrapDataSize = P7Length;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Wrap PKCS#7 signeddata to a ContentInfo structure - add a header in 19 bytes.
|
||||||
|
//
|
||||||
|
*WrapDataSize = P7Length + 19;
|
||||||
|
*WrapData = malloc (*WrapDataSize);
|
||||||
|
if (*WrapData == NULL) {
|
||||||
|
*WrapFlag = Wrapped;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignedData = *WrapData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part1: 0x30, 0x82.
|
||||||
|
//
|
||||||
|
SignedData[0] = 0x30;
|
||||||
|
SignedData[1] = 0x82;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part2: Length1 = P7Length + 19 - 4, in big endian.
|
||||||
|
//
|
||||||
|
SignedData[2] = (UINT8) (((UINT16) (*WrapDataSize - 4)) >> 8);
|
||||||
|
SignedData[3] = (UINT8) (((UINT16) (*WrapDataSize - 4)) & 0xff);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part3: 0x06, 0x09.
|
||||||
|
//
|
||||||
|
SignedData[4] = 0x06;
|
||||||
|
SignedData[5] = 0x09;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part4: OID value -- 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x07 0x02.
|
||||||
|
//
|
||||||
|
CopyMem (SignedData + 6, mOidValue, sizeof (mOidValue));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part5: 0xA0, 0x82.
|
||||||
|
//
|
||||||
|
SignedData[15] = 0xA0;
|
||||||
|
SignedData[16] = 0x82;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part6: Length2 = P7Length, in big endian.
|
||||||
|
//
|
||||||
|
SignedData[17] = (UINT8) (((UINT16) P7Length) >> 8);
|
||||||
|
SignedData[18] = (UINT8) (((UINT16) P7Length) & 0xff);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Part7: P7Data.
|
||||||
|
//
|
||||||
|
CopyMem (SignedData + 19, P7Data, P7Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
*WrapFlag = Wrapped;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Pop single certificate from STACK_OF(X509).
|
||||||
|
|
||||||
|
If X509Stack, Cert, or CertSize is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] X509Stack Pointer to a X509 stack object.
|
||||||
|
@param[out] Cert Pointer to a X509 certificate.
|
||||||
|
@param[out] CertSize Length of output X509 certificate in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The X509 stack pop succeeded.
|
||||||
|
@retval FALSE The pop operation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
X509PopCertificate (
|
||||||
|
IN VOID *X509Stack,
|
||||||
|
OUT UINT8 **Cert,
|
||||||
|
OUT UINTN *CertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BIO *CertBio;
|
||||||
|
X509 *X509Cert;
|
||||||
|
STACK_OF(X509) *CertStack;
|
||||||
|
BOOLEAN Status;
|
||||||
|
INT32 Result;
|
||||||
|
BUF_MEM *Ptr;
|
||||||
|
INT32 Length;
|
||||||
|
VOID *Buffer;
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
CertStack = (STACK_OF(X509) *) X509Stack;
|
||||||
|
|
||||||
|
X509Cert = sk_X509_pop (CertStack);
|
||||||
|
|
||||||
|
if (X509Cert == NULL) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = NULL;
|
||||||
|
|
||||||
|
CertBio = BIO_new (BIO_s_mem ());
|
||||||
|
if (CertBio == NULL) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = i2d_X509_bio (CertBio, X509Cert);
|
||||||
|
if (Result == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_get_mem_ptr (CertBio, &Ptr);
|
||||||
|
Length = (INT32)(Ptr->length);
|
||||||
|
if (Length <= 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = malloc (Length);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = BIO_read (CertBio, Buffer, Length);
|
||||||
|
if (Result != Length) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Cert = Buffer;
|
||||||
|
*CertSize = Length;
|
||||||
|
|
||||||
|
Status = TRUE;
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
|
||||||
|
BIO_free (CertBio);
|
||||||
|
|
||||||
|
if (!Status && (Buffer != NULL)) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard". The input signed data could be wrapped
|
||||||
|
in a ContentInfo structure.
|
||||||
|
|
||||||
|
If P7Data, CertStack, StackLength, TrustedCert or CertLength is NULL, then
|
||||||
|
return FALSE. If P7Length overflow, then return FALSE.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input.
|
||||||
|
UEFI Authenticated Variable is external input, so this function will do basic
|
||||||
|
check for PKCS#7 data structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message to verify.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] CertStack Pointer to Signer's certificates retrieved from P7Data.
|
||||||
|
It's caller's responsibility to free the buffer with
|
||||||
|
Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] StackLength Length of signer's certificates in bytes.
|
||||||
|
@param[out] TrustedCert Pointer to a trusted certificate from Signer's certificates.
|
||||||
|
It's caller's responsibility to free the buffer with
|
||||||
|
Pkcs7FreeSigners().
|
||||||
|
@param[out] CertLength Length of the trusted certificate in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The operation is finished successfully.
|
||||||
|
@retval FALSE Error occurs during the operation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetSigners (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT UINT8 **CertStack,
|
||||||
|
OUT UINTN *StackLength,
|
||||||
|
OUT UINT8 **TrustedCert,
|
||||||
|
OUT UINTN *CertLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
BOOLEAN Status;
|
||||||
|
UINT8 *SignedData;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
UINTN SignedDataSize;
|
||||||
|
BOOLEAN Wrapped;
|
||||||
|
STACK_OF(X509) *Stack;
|
||||||
|
UINT8 Index;
|
||||||
|
UINT8 *CertBuf;
|
||||||
|
UINT8 *OldBuf;
|
||||||
|
UINTN BufferSize;
|
||||||
|
UINTN OldSize;
|
||||||
|
UINT8 *SingleCert;
|
||||||
|
UINTN SingleCertSize;
|
||||||
|
|
||||||
|
if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
|
||||||
|
(TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
|
||||||
|
if (!Status) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
Stack = NULL;
|
||||||
|
CertBuf = NULL;
|
||||||
|
OldBuf = NULL;
|
||||||
|
SingleCert = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve PKCS#7 Data (DER encoding)
|
||||||
|
//
|
||||||
|
if (SignedDataSize > INT_MAX) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Temp = SignedData;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) SignedDataSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
|
||||||
|
//
|
||||||
|
if (!PKCS7_type_is_signed (Pkcs7)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack = PKCS7_get0_signers(Pkcs7, NULL, PKCS7_BINARY);
|
||||||
|
if (Stack == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert CertStack to buffer in following format:
|
||||||
|
// UINT8 CertNumber;
|
||||||
|
// UINT32 Cert1Length;
|
||||||
|
// UINT8 Cert1[];
|
||||||
|
// UINT32 Cert2Length;
|
||||||
|
// UINT8 Cert2[];
|
||||||
|
// ...
|
||||||
|
// UINT32 CertnLength;
|
||||||
|
// UINT8 Certn[];
|
||||||
|
//
|
||||||
|
BufferSize = sizeof (UINT8);
|
||||||
|
OldSize = BufferSize;
|
||||||
|
|
||||||
|
for (Index = 0; ; Index++) {
|
||||||
|
Status = X509PopCertificate (Stack, &SingleCert, &SingleCertSize);
|
||||||
|
if (!Status) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldSize = BufferSize;
|
||||||
|
OldBuf = CertBuf;
|
||||||
|
BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
|
||||||
|
CertBuf = malloc (BufferSize);
|
||||||
|
|
||||||
|
if (CertBuf == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldBuf != NULL) {
|
||||||
|
CopyMem (CertBuf, OldBuf, OldSize);
|
||||||
|
free (OldBuf);
|
||||||
|
OldBuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) SingleCertSize);
|
||||||
|
CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
|
||||||
|
|
||||||
|
free (SingleCert);
|
||||||
|
SingleCert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CertBuf != NULL) {
|
||||||
|
//
|
||||||
|
// Update CertNumber.
|
||||||
|
//
|
||||||
|
CertBuf[0] = Index;
|
||||||
|
|
||||||
|
*CertLength = BufferSize - OldSize - sizeof (UINT32);
|
||||||
|
*TrustedCert = malloc (*CertLength);
|
||||||
|
if (*TrustedCert == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
|
||||||
|
*CertStack = CertBuf;
|
||||||
|
*StackLength = BufferSize;
|
||||||
|
Status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
if (!Wrapped) {
|
||||||
|
free (SignedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pkcs7 != NULL) {
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Stack != NULL) {
|
||||||
|
sk_X509_pop_free(Stack, X509_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SingleCert != NULL) {
|
||||||
|
free (SingleCert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Status && (CertBuf != NULL)) {
|
||||||
|
free (CertBuf);
|
||||||
|
*CertStack = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldBuf != NULL) {
|
||||||
|
free (OldBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wrap function to use free() to free allocated memory for certificates.
|
||||||
|
|
||||||
|
@param[in] Certs Pointer to the certificates to be freed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7FreeSigners (
|
||||||
|
IN UINT8 *Certs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Certs == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (Certs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard", and outputs two certificate lists chained and
|
||||||
|
unchained to the signer's certificates.
|
||||||
|
The input signed data could be wrapped in a ContentInfo structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] SignerChainCerts Pointer to the certificates list chained to signer's
|
||||||
|
certificate. It's caller's responsibility to free the buffer
|
||||||
|
with Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] ChainLength Length of the chained certificates list buffer in bytes.
|
||||||
|
@param[out] UnchainCerts Pointer to the unchained certificates lists. It's caller's
|
||||||
|
responsibility to free the buffer with Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] UnchainLength Length of the unchained certificates list buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The operation is finished successfully.
|
||||||
|
@retval FALSE Error occurs during the operation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetCertificatesList (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT UINT8 **SignerChainCerts,
|
||||||
|
OUT UINTN *ChainLength,
|
||||||
|
OUT UINT8 **UnchainCerts,
|
||||||
|
OUT UINTN *UnchainLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
UINT8 *NewP7Data;
|
||||||
|
UINTN NewP7Length;
|
||||||
|
BOOLEAN Wrapped;
|
||||||
|
UINT8 Index;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
X509_STORE_CTX *CertCtx;
|
||||||
|
STACK_OF(X509) *CtxChain;
|
||||||
|
STACK_OF(X509) *CtxUntrusted;
|
||||||
|
X509 *CtxCert;
|
||||||
|
STACK_OF(X509) *Signers;
|
||||||
|
X509 *Signer;
|
||||||
|
X509 *Cert;
|
||||||
|
X509 *Issuer;
|
||||||
|
X509_NAME *IssuerName;
|
||||||
|
UINT8 *CertBuf;
|
||||||
|
UINT8 *OldBuf;
|
||||||
|
UINTN BufferSize;
|
||||||
|
UINTN OldSize;
|
||||||
|
UINT8 *SingleCert;
|
||||||
|
UINTN CertSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializations
|
||||||
|
//
|
||||||
|
Status = FALSE;
|
||||||
|
NewP7Data = NULL;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
CertCtx = NULL;
|
||||||
|
CtxChain = NULL;
|
||||||
|
CtxCert = NULL;
|
||||||
|
CtxUntrusted = NULL;
|
||||||
|
Cert = NULL;
|
||||||
|
SingleCert = NULL;
|
||||||
|
CertBuf = NULL;
|
||||||
|
OldBuf = NULL;
|
||||||
|
Signers = NULL;
|
||||||
|
|
||||||
|
ZeroMem (&CertCtx, sizeof (CertCtx));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parameter Checking
|
||||||
|
//
|
||||||
|
if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||
|
||||||
|
(UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*SignerChainCerts = NULL;
|
||||||
|
*ChainLength = 0;
|
||||||
|
*UnchainCerts = NULL;
|
||||||
|
*UnchainLength = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct a new PKCS#7 data wrapping with ContentInfo structure if needed.
|
||||||
|
//
|
||||||
|
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &NewP7Data, &NewP7Length);
|
||||||
|
if (!Status || (NewP7Length > INT_MAX)) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Decodes PKCS#7 SignedData
|
||||||
|
//
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &NewP7Data, (int) NewP7Length);
|
||||||
|
if ((Pkcs7 == NULL) || (!PKCS7_type_is_signed (Pkcs7))) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Obtains Signer's Certificate from PKCS#7 data
|
||||||
|
// NOTE: Only one signer case will be handled in this function, which means SignerInfos
|
||||||
|
// should include only one signer's certificate.
|
||||||
|
//
|
||||||
|
Signers = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);
|
||||||
|
if ((Signers == NULL) || (sk_X509_num (Signers) != 1)) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
Signer = sk_X509_value (Signers, 0);
|
||||||
|
|
||||||
|
CertCtx = X509_STORE_CTX_new ();
|
||||||
|
if (CertCtx == NULL) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
if (!X509_STORE_CTX_init (CertCtx, NULL, Signer, Pkcs7->d.sign->cert)) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize Chained & Untrusted stack
|
||||||
|
//
|
||||||
|
CtxChain = X509_STORE_CTX_get0_chain (CertCtx);
|
||||||
|
CtxCert = X509_STORE_CTX_get0_cert (CertCtx);
|
||||||
|
if (CtxChain == NULL) {
|
||||||
|
if (((CtxChain = sk_X509_new_null ()) == NULL) ||
|
||||||
|
(!sk_X509_push (CtxChain, CtxCert))) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CtxUntrusted = X509_STORE_CTX_get0_untrusted (CertCtx);
|
||||||
|
if (CtxUntrusted != NULL) {
|
||||||
|
(VOID)sk_X509_delete_ptr (CtxUntrusted, Signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build certificates stack chained from Signer's certificate.
|
||||||
|
//
|
||||||
|
Cert = Signer;
|
||||||
|
for (; ;) {
|
||||||
|
//
|
||||||
|
// Self-Issue checking
|
||||||
|
//
|
||||||
|
Issuer = NULL;
|
||||||
|
if (X509_STORE_CTX_get1_issuer (&Issuer, CertCtx, Cert) == 1) {
|
||||||
|
if (X509_cmp (Issuer, Cert) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Found the issuer of the current certificate
|
||||||
|
//
|
||||||
|
if (CtxUntrusted != NULL) {
|
||||||
|
Issuer = NULL;
|
||||||
|
IssuerName = X509_get_issuer_name (Cert);
|
||||||
|
Issuer = X509_find_by_subject (CtxUntrusted, IssuerName);
|
||||||
|
if (Issuer != NULL) {
|
||||||
|
if (!sk_X509_push (CtxChain, Issuer)) {
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
(VOID)sk_X509_delete_ptr (CtxUntrusted, Issuer);
|
||||||
|
|
||||||
|
Cert = Issuer;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Converts Chained and Untrusted Certificate to Certificate Buffer in following format:
|
||||||
|
// UINT8 CertNumber;
|
||||||
|
// UINT32 Cert1Length;
|
||||||
|
// UINT8 Cert1[];
|
||||||
|
// UINT32 Cert2Length;
|
||||||
|
// UINT8 Cert2[];
|
||||||
|
// ...
|
||||||
|
// UINT32 CertnLength;
|
||||||
|
// UINT8 Certn[];
|
||||||
|
//
|
||||||
|
|
||||||
|
if (CtxChain != NULL) {
|
||||||
|
BufferSize = sizeof (UINT8);
|
||||||
|
CertBuf = NULL;
|
||||||
|
|
||||||
|
for (Index = 0; ; Index++) {
|
||||||
|
Status = X509PopCertificate (CtxChain, &SingleCert, &CertSize);
|
||||||
|
if (!Status) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldSize = BufferSize;
|
||||||
|
OldBuf = CertBuf;
|
||||||
|
BufferSize = OldSize + CertSize + sizeof (UINT32);
|
||||||
|
CertBuf = malloc (BufferSize);
|
||||||
|
|
||||||
|
if (CertBuf == NULL) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
if (OldBuf != NULL) {
|
||||||
|
CopyMem (CertBuf, OldBuf, OldSize);
|
||||||
|
free (OldBuf);
|
||||||
|
OldBuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) CertSize);
|
||||||
|
CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);
|
||||||
|
|
||||||
|
free (SingleCert);
|
||||||
|
SingleCert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CertBuf != NULL) {
|
||||||
|
//
|
||||||
|
// Update CertNumber.
|
||||||
|
//
|
||||||
|
CertBuf[0] = Index;
|
||||||
|
|
||||||
|
*SignerChainCerts = CertBuf;
|
||||||
|
*ChainLength = BufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CtxUntrusted != NULL) {
|
||||||
|
BufferSize = sizeof (UINT8);
|
||||||
|
CertBuf = NULL;
|
||||||
|
|
||||||
|
for (Index = 0; ; Index++) {
|
||||||
|
Status = X509PopCertificate (CtxUntrusted, &SingleCert, &CertSize);
|
||||||
|
if (!Status) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldSize = BufferSize;
|
||||||
|
OldBuf = CertBuf;
|
||||||
|
BufferSize = OldSize + CertSize + sizeof (UINT32);
|
||||||
|
CertBuf = malloc (BufferSize);
|
||||||
|
|
||||||
|
if (CertBuf == NULL) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Error;
|
||||||
|
}
|
||||||
|
if (OldBuf != NULL) {
|
||||||
|
CopyMem (CertBuf, OldBuf, OldSize);
|
||||||
|
free (OldBuf);
|
||||||
|
OldBuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) CertSize);
|
||||||
|
CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);
|
||||||
|
|
||||||
|
free (SingleCert);
|
||||||
|
SingleCert = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CertBuf != NULL) {
|
||||||
|
//
|
||||||
|
// Update CertNumber.
|
||||||
|
//
|
||||||
|
CertBuf[0] = Index;
|
||||||
|
|
||||||
|
*UnchainCerts = CertBuf;
|
||||||
|
*UnchainLength = BufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TRUE;
|
||||||
|
|
||||||
|
_Error:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
if (!Wrapped && (NewP7Data != NULL)) {
|
||||||
|
free (NewP7Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pkcs7 != NULL) {
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
}
|
||||||
|
sk_X509_free (Signers);
|
||||||
|
|
||||||
|
if (CertCtx != NULL) {
|
||||||
|
X509_STORE_CTX_cleanup (CertCtx);
|
||||||
|
X509_STORE_CTX_free (CertCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SingleCert != NULL) {
|
||||||
|
free (SingleCert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldBuf != NULL) {
|
||||||
|
free (OldBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Status && (CertBuf != NULL)) {
|
||||||
|
free (CertBuf);
|
||||||
|
*SignerChainCerts = NULL;
|
||||||
|
*UnchainCerts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard". The input signed data could be wrapped
|
||||||
|
in a ContentInfo structure.
|
||||||
|
|
||||||
|
If P7Data, TrustedCert or InData is NULL, then return FALSE.
|
||||||
|
If P7Length, CertLength or DataLength overflow, then return FALSE.
|
||||||
|
|
||||||
|
Caution: This function may receive untrusted input.
|
||||||
|
UEFI Authenticated Variable is external input, so this function will do basic
|
||||||
|
check for PKCS#7 data structure.
|
||||||
|
|
||||||
|
@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.
|
||||||
|
|
||||||
|
@retval TRUE The specified PKCS#7 signed data is valid.
|
||||||
|
@retval 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;
|
||||||
|
BIO *DataBio;
|
||||||
|
BOOLEAN Status;
|
||||||
|
X509 *Cert;
|
||||||
|
X509_STORE *CertStore;
|
||||||
|
UINT8 *SignedData;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
UINTN SignedDataSize;
|
||||||
|
BOOLEAN Wrapped;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (P7Data == NULL || TrustedCert == NULL || InData == NULL ||
|
||||||
|
P7Length > INT_MAX || CertLength > INT_MAX || DataLength > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
DataBio = NULL;
|
||||||
|
Cert = NULL;
|
||||||
|
CertStore = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register & Initialize necessary digest algorithms for PKCS#7 Handling
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_md5 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha256 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha384 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha512 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
|
||||||
|
if (!Status) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve PKCS#7 Data (DER encoding)
|
||||||
|
//
|
||||||
|
if (SignedDataSize > INT_MAX) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Temp = SignedData;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) SignedDataSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
|
||||||
|
//
|
||||||
|
if (!PKCS7_type_is_signed (Pkcs7)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded root certificate and Construct X509 Certificate
|
||||||
|
//
|
||||||
|
Temp = TrustedCert;
|
||||||
|
Cert = d2i_X509 (NULL, &Temp, (long) CertLength);
|
||||||
|
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 ());
|
||||||
|
if (DataBio == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BIO_write (DataBio, InData, (int) DataLength) <= 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allow partial certificate chains, terminated by a non-self-signed but
|
||||||
|
// still trusted intermediate certificate. Also disable time checks.
|
||||||
|
//
|
||||||
|
X509_STORE_set_flags (CertStore,
|
||||||
|
X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and
|
||||||
|
// doesn't support the extended key usage for Authenticode Code Signing.
|
||||||
|
// Bypass the certificate purpose checking by enabling any purposes setting.
|
||||||
|
//
|
||||||
|
X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verifies the PKCS#7 signedData structure
|
||||||
|
//
|
||||||
|
Status = (BOOLEAN) PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, PKCS7_BINARY);
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
BIO_free (DataBio);
|
||||||
|
X509_free (Cert);
|
||||||
|
X509_STORE_free (CertStore);
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
|
||||||
|
if (!Wrapped) {
|
||||||
|
OPENSSL_free (SignedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,169 @@
|
|||||||
|
/** @file
|
||||||
|
PKCS#7 SignedData Verification Wrapper Implementation which does not provide
|
||||||
|
real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard". The input signed data could be wrapped
|
||||||
|
in a ContentInfo structure.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message to verify.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] CertStack Pointer to Signer's certificates retrieved from P7Data.
|
||||||
|
It's caller's responsibility to free the buffer with
|
||||||
|
Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] StackLength Length of signer's certificates in bytes.
|
||||||
|
@param[out] TrustedCert Pointer to a trusted certificate from Signer's certificates.
|
||||||
|
It's caller's responsibility to free the buffer with
|
||||||
|
Pkcs7FreeSigners().
|
||||||
|
@param[out] CertLength Length of the trusted certificate in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetSigners (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT UINT8 **CertStack,
|
||||||
|
OUT UINTN *StackLength,
|
||||||
|
OUT UINT8 **TrustedCert,
|
||||||
|
OUT UINTN *CertLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wrap function to use free() to free allocated memory for certificates.
|
||||||
|
|
||||||
|
If the interface is not supported, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] Certs Pointer to the certificates to be freed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7FreeSigners (
|
||||||
|
IN UINT8 *Certs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard", and outputs two certificate lists chained and
|
||||||
|
unchained to the signer's certificates.
|
||||||
|
The input signed data could be wrapped in a ContentInfo structure.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 message.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 message in bytes.
|
||||||
|
@param[out] SignerChainCerts Pointer to the certificates list chained to signer's
|
||||||
|
certificate. It's caller's responsibility to free the buffer
|
||||||
|
with Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] ChainLength Length of the chained certificates list buffer in bytes.
|
||||||
|
@param[out] UnchainCerts Pointer to the unchained certificates lists. It's caller's
|
||||||
|
responsibility to free the buffer with Pkcs7FreeSigners().
|
||||||
|
This data structure is EFI_CERT_STACK type.
|
||||||
|
@param[out] UnchainLength Length of the unchained certificates list buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The operation is finished successfully.
|
||||||
|
@retval FALSE Error occurs during the operation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetCertificatesList (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT UINT8 **SignerChainCerts,
|
||||||
|
OUT UINTN *ChainLength,
|
||||||
|
OUT UINT8 **UnchainCerts,
|
||||||
|
OUT UINTN *UnchainLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a PKCS#7 signed data as described in "PKCS #7:
|
||||||
|
Cryptographic Message Syntax Standard". The input signed data could be wrapped
|
||||||
|
in a ContentInfo structure.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@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.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7Verify (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
IN CONST UINT8 *TrustedCert,
|
||||||
|
IN UINTN CertLength,
|
||||||
|
IN CONST UINT8 *InData,
|
||||||
|
IN UINTN DataLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
|
||||||
|
data could be wrapped in a ContentInfo structure.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
|
||||||
|
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
|
||||||
|
It's caller's responsibility to free the buffer with FreePool().
|
||||||
|
@param[out] ContentSize The size of the extracted content in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The P7Data was correctly formatted for processing.
|
||||||
|
@retval FALSE The P7Data was not correctly formatted for processing.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetAttachedContent (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT VOID **Content,
|
||||||
|
OUT UINTN *ContentSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/** @file
|
||||||
|
Runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
|
||||||
|
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
|
||||||
|
data could be wrapped in a ContentInfo structure.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
|
||||||
|
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
|
||||||
|
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
|
||||||
|
It's caller's responsibility to free the buffer with FreePool().
|
||||||
|
@param[out] ContentSize The size of the extracted content in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The P7Data was correctly formatted for processing.
|
||||||
|
@retval FALSE The P7Data was not correctly formatted for processing.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
Pkcs7GetAttachedContent (
|
||||||
|
IN CONST UINT8 *P7Data,
|
||||||
|
IN UINTN P7Length,
|
||||||
|
OUT VOID **Content,
|
||||||
|
OUT UINTN *ContentSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,325 @@
|
|||||||
|
/** @file
|
||||||
|
RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
This file implements following APIs which provide basic capabilities for RSA:
|
||||||
|
1) RsaNew
|
||||||
|
2) RsaFree
|
||||||
|
3) RsaSetKey
|
||||||
|
4) RsaPkcs1Verify
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 key component into the established RSA context.
|
||||||
|
|
||||||
|
This function sets the tag-designated RSA key component into the established
|
||||||
|
RSA context from the user-specified non-negative integer (octet string format
|
||||||
|
represented in RSA PKCS#1).
|
||||||
|
If BigNumber is NULL, then the specified key component in RSA context is cleared.
|
||||||
|
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@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.
|
||||||
|
If NULL, then the specified key component in RSA
|
||||||
|
context is cleared.
|
||||||
|
@param[in] BnSize Size of big number buffer in bytes.
|
||||||
|
If BigNumber is NULL, then it is ignored.
|
||||||
|
|
||||||
|
@retval TRUE RSA key component was set successfully.
|
||||||
|
@retval FALSE Invalid RSA key component tag.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaSetKey (
|
||||||
|
IN OUT VOID *RsaContext,
|
||||||
|
IN RSA_KEY_TAG KeyTag,
|
||||||
|
IN CONST UINT8 *BigNumber,
|
||||||
|
IN UINTN BnSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RSA *RsaKey;
|
||||||
|
BIGNUM *BnN;
|
||||||
|
BIGNUM *BnE;
|
||||||
|
BIGNUM *BnD;
|
||||||
|
BIGNUM *BnP;
|
||||||
|
BIGNUM *BnQ;
|
||||||
|
BIGNUM *BnDp;
|
||||||
|
BIGNUM *BnDq;
|
||||||
|
BIGNUM *BnQInv;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL || BnSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BnN = NULL;
|
||||||
|
BnE = NULL;
|
||||||
|
BnD = NULL;
|
||||||
|
BnP = NULL;
|
||||||
|
BnQ = NULL;
|
||||||
|
BnDp = NULL;
|
||||||
|
BnDq = NULL;
|
||||||
|
BnQInv = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the components from RSA object.
|
||||||
|
//
|
||||||
|
RsaKey = (RSA *) RsaContext;
|
||||||
|
RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD);
|
||||||
|
RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ);
|
||||||
|
RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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), Public Exponent (e) and Private Exponent (d)
|
||||||
|
//
|
||||||
|
case RsaKeyN:
|
||||||
|
case RsaKeyE:
|
||||||
|
case RsaKeyD:
|
||||||
|
if (BnN == NULL) {
|
||||||
|
BnN = BN_new ();
|
||||||
|
}
|
||||||
|
if (BnE == NULL) {
|
||||||
|
BnE = BN_new ();
|
||||||
|
}
|
||||||
|
if (BnD == NULL) {
|
||||||
|
BnD = BN_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (KeyTag) {
|
||||||
|
case RsaKeyN:
|
||||||
|
BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN);
|
||||||
|
break;
|
||||||
|
case RsaKeyE:
|
||||||
|
BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE);
|
||||||
|
break;
|
||||||
|
case RsaKeyD:
|
||||||
|
BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (RSA_set0_key (RsaKey, BN_dup(BnN), BN_dup(BnE), BN_dup(BnD)) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Secret Prime Factor of Modulus (p and q)
|
||||||
|
//
|
||||||
|
case RsaKeyP:
|
||||||
|
case RsaKeyQ:
|
||||||
|
if (BnP == NULL) {
|
||||||
|
BnP = BN_new ();
|
||||||
|
}
|
||||||
|
if (BnQ == NULL) {
|
||||||
|
BnQ = BN_new ();
|
||||||
|
}
|
||||||
|
if ((BnP == NULL) || (BnQ == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (KeyTag) {
|
||||||
|
case RsaKeyP:
|
||||||
|
BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP);
|
||||||
|
break;
|
||||||
|
case RsaKeyQ:
|
||||||
|
BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (RSA_set0_factors (RsaKey, BN_dup(BnP), BN_dup(BnQ)) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// p's CRT Exponent (== d mod (p - 1)), q's CRT Exponent (== d mod (q - 1)),
|
||||||
|
// and CRT Coefficient (== 1/q mod p)
|
||||||
|
//
|
||||||
|
case RsaKeyDp:
|
||||||
|
case RsaKeyDq:
|
||||||
|
case RsaKeyQInv:
|
||||||
|
if (BnDp == NULL) {
|
||||||
|
BnDp = BN_new ();
|
||||||
|
}
|
||||||
|
if (BnDq == NULL) {
|
||||||
|
BnDq = BN_new ();
|
||||||
|
}
|
||||||
|
if (BnQInv == NULL) {
|
||||||
|
BnQInv = BN_new ();
|
||||||
|
}
|
||||||
|
if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (KeyTag) {
|
||||||
|
case RsaKeyDp:
|
||||||
|
BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp);
|
||||||
|
break;
|
||||||
|
case RsaKeyDq:
|
||||||
|
BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq);
|
||||||
|
break;
|
||||||
|
case RsaKeyQInv:
|
||||||
|
BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (RSA_set0_crt_params (RsaKey, BN_dup(BnDp), BN_dup(BnDq), BN_dup(BnQInv)) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 return FALSE.
|
||||||
|
If MessageHash is NULL, then return FALSE.
|
||||||
|
If Signature is NULL, then return FALSE.
|
||||||
|
If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] RsaContext Pointer to RSA context for signature verification.
|
||||||
|
@param[in] MessageHash Pointer to octet message hash to be checked.
|
||||||
|
@param[in] HashSize Size of the message hash in bytes.
|
||||||
|
@param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified.
|
||||||
|
@param[in] SigSize Size of signature in bytes.
|
||||||
|
|
||||||
|
@retval TRUE Valid signature encoded in PKCS1-v1_5.
|
||||||
|
@retval FALSE Invalid signature or invalid RSA context.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaPkcs1Verify (
|
||||||
|
IN VOID *RsaContext,
|
||||||
|
IN CONST UINT8 *MessageHash,
|
||||||
|
IN UINTN HashSize,
|
||||||
|
IN CONST UINT8 *Signature,
|
||||||
|
IN UINTN SigSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INT32 DigestType;
|
||||||
|
UINT8 *SigBuf;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SigSize > INT_MAX || SigSize == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the message digest algorithm according to digest size.
|
||||||
|
// Only MD5, SHA-1 or SHA-256 algorithm is supported.
|
||||||
|
//
|
||||||
|
switch (HashSize) {
|
||||||
|
case MD5_DIGEST_SIZE:
|
||||||
|
DigestType = NID_md5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA1_DIGEST_SIZE:
|
||||||
|
DigestType = NID_sha1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA256_DIGEST_SIZE:
|
||||||
|
DigestType = NID_sha256;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigBuf = (UINT8 *) Signature;
|
||||||
|
return (BOOLEAN) RSA_verify (
|
||||||
|
DigestType,
|
||||||
|
MessageHash,
|
||||||
|
(UINT32) HashSize,
|
||||||
|
SigBuf,
|
||||||
|
(UINT32) SigSize,
|
||||||
|
(RSA *) RsaContext
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,362 @@
|
|||||||
|
/** @file
|
||||||
|
RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
This file implements following APIs which provide more capabilities for RSA:
|
||||||
|
1) RsaGetKey
|
||||||
|
2) RsaGenerateKey
|
||||||
|
3) RsaCheckKey
|
||||||
|
4) RsaPkcs1Sign
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the tag-designated RSA key component from the established RSA context.
|
||||||
|
|
||||||
|
This function retrieves the tag-designated RSA key component from the
|
||||||
|
established RSA context as a non-negative integer (octet string format
|
||||||
|
represented in RSA PKCS#1).
|
||||||
|
If specified key component has not been set or has been cleared, then returned
|
||||||
|
BnSize is set to 0.
|
||||||
|
If the BigNumber buffer is too small to hold the contents of the key, FALSE
|
||||||
|
is returned and BnSize is set to the required buffer size to obtain the key.
|
||||||
|
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
If BnSize is NULL, then return FALSE.
|
||||||
|
If BnSize is large enough but BigNumber is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] RsaContext Pointer to RSA context being set.
|
||||||
|
@param[in] KeyTag Tag of RSA key component being set.
|
||||||
|
@param[out] BigNumber Pointer to octet integer buffer.
|
||||||
|
@param[in, out] BnSize On input, the size of big number buffer in bytes.
|
||||||
|
On output, the size of data returned in big number buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE RSA key component was retrieved successfully.
|
||||||
|
@retval FALSE Invalid RSA key component tag.
|
||||||
|
@retval FALSE BnSize is too small.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetKey (
|
||||||
|
IN OUT VOID *RsaContext,
|
||||||
|
IN RSA_KEY_TAG KeyTag,
|
||||||
|
OUT UINT8 *BigNumber,
|
||||||
|
IN OUT UINTN *BnSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RSA *RsaKey;
|
||||||
|
BIGNUM *BnKey;
|
||||||
|
UINTN Size;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL || BnSize == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsaKey = (RSA *) RsaContext;
|
||||||
|
Size = *BnSize;
|
||||||
|
*BnSize = 0;
|
||||||
|
BnKey = NULL;
|
||||||
|
|
||||||
|
switch (KeyTag) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Public Modulus (N)
|
||||||
|
//
|
||||||
|
case RsaKeyN:
|
||||||
|
RSA_get0_key (RsaKey, (const BIGNUM **)&BnKey, NULL, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Public Exponent (e)
|
||||||
|
//
|
||||||
|
case RsaKeyE:
|
||||||
|
RSA_get0_key (RsaKey, NULL, (const BIGNUM **)&BnKey, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Private Exponent (d)
|
||||||
|
//
|
||||||
|
case RsaKeyD:
|
||||||
|
RSA_get0_key (RsaKey, NULL, NULL, (const BIGNUM **)&BnKey);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Secret Prime Factor of Modulus (p)
|
||||||
|
//
|
||||||
|
case RsaKeyP:
|
||||||
|
RSA_get0_factors (RsaKey, (const BIGNUM **)&BnKey, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSA Secret Prime Factor of Modules (q)
|
||||||
|
//
|
||||||
|
case RsaKeyQ:
|
||||||
|
RSA_get0_factors (RsaKey, NULL, (const BIGNUM **)&BnKey);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// p's CRT Exponent (== d mod (p - 1))
|
||||||
|
//
|
||||||
|
case RsaKeyDp:
|
||||||
|
RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnKey, NULL, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// q's CRT Exponent (== d mod (q - 1))
|
||||||
|
//
|
||||||
|
case RsaKeyDq:
|
||||||
|
RSA_get0_crt_params (RsaKey, NULL, (const BIGNUM **)&BnKey, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The CRT Coefficient (== 1/q mod p)
|
||||||
|
//
|
||||||
|
case RsaKeyQInv:
|
||||||
|
RSA_get0_crt_params (RsaKey, NULL, NULL, (const BIGNUM **)&BnKey);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BnKey == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*BnSize = Size;
|
||||||
|
Size = BN_num_bytes (BnKey);
|
||||||
|
|
||||||
|
if (*BnSize < Size) {
|
||||||
|
*BnSize = Size;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BigNumber == NULL) {
|
||||||
|
*BnSize = Size;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
*BnSize = BN_bn2bin (BnKey, BigNumber) ;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates RSA key components.
|
||||||
|
|
||||||
|
This function generates RSA key components. It takes RSA public exponent E and
|
||||||
|
length in bits of RSA modulus N as input, and generates all key components.
|
||||||
|
If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.
|
||||||
|
|
||||||
|
Before this function can be invoked, pseudorandom number generator must be correctly
|
||||||
|
initialized by RandomSeed().
|
||||||
|
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] RsaContext Pointer to RSA context being set.
|
||||||
|
@param[in] ModulusLength Length of RSA modulus N in bits.
|
||||||
|
@param[in] PublicExponent Pointer to RSA public exponent.
|
||||||
|
@param[in] PublicExponentSize Size of RSA public exponent buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE RSA key component was generated successfully.
|
||||||
|
@retval FALSE Invalid RSA key component tag.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGenerateKey (
|
||||||
|
IN OUT VOID *RsaContext,
|
||||||
|
IN UINTN ModulusLength,
|
||||||
|
IN CONST UINT8 *PublicExponent,
|
||||||
|
IN UINTN PublicExponentSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BIGNUM *KeyE;
|
||||||
|
BOOLEAN RetVal;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL || ModulusLength > INT_MAX || PublicExponentSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyE = BN_new ();
|
||||||
|
if (KeyE == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RetVal = FALSE;
|
||||||
|
|
||||||
|
if (PublicExponent == NULL) {
|
||||||
|
if (BN_set_word (KeyE, 0x10001) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE) == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) {
|
||||||
|
RetVal = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
BN_free (KeyE);
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Validates key components of RSA context.
|
||||||
|
NOTE: This function performs integrity checks on all the RSA key material, so
|
||||||
|
the RSA key structure must contain all the private key data.
|
||||||
|
|
||||||
|
This function validates key components of RSA context in following aspects:
|
||||||
|
- Whether p is a prime
|
||||||
|
- Whether q is a prime
|
||||||
|
- Whether n = p * q
|
||||||
|
- Whether d*e = 1 mod lcm(p-1,q-1)
|
||||||
|
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] RsaContext Pointer to RSA context to check.
|
||||||
|
|
||||||
|
@retval TRUE RSA key components are valid.
|
||||||
|
@retval FALSE RSA key components are not valid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaCheckKey (
|
||||||
|
IN VOID *RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Reason;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RSA_check_key ((RSA *) RsaContext) != 1) {
|
||||||
|
Reason = ERR_GET_REASON (ERR_peek_last_error ());
|
||||||
|
if (Reason == RSA_R_P_NOT_PRIME ||
|
||||||
|
Reason == RSA_R_Q_NOT_PRIME ||
|
||||||
|
Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q ||
|
||||||
|
Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
|
||||||
|
|
||||||
|
This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in
|
||||||
|
RSA PKCS#1.
|
||||||
|
If the Signature buffer is too small to hold the contents of signature, FALSE
|
||||||
|
is returned and SigSize is set to the required buffer size to obtain the signature.
|
||||||
|
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
If MessageHash is NULL, then return FALSE.
|
||||||
|
If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.
|
||||||
|
If SigSize is large enough but Signature is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] RsaContext Pointer to RSA context for signature generation.
|
||||||
|
@param[in] MessageHash Pointer to octet message hash to be signed.
|
||||||
|
@param[in] HashSize Size of the message hash in bytes.
|
||||||
|
@param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature.
|
||||||
|
@param[in, out] SigSize On input, the size of Signature buffer in bytes.
|
||||||
|
On output, the size of data returned in Signature buffer in bytes.
|
||||||
|
|
||||||
|
@retval TRUE Signature successfully generated in PKCS1-v1_5.
|
||||||
|
@retval FALSE Signature generation failed.
|
||||||
|
@retval FALSE SigSize is too small.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaPkcs1Sign (
|
||||||
|
IN VOID *RsaContext,
|
||||||
|
IN CONST UINT8 *MessageHash,
|
||||||
|
IN UINTN HashSize,
|
||||||
|
OUT UINT8 *Signature,
|
||||||
|
IN OUT UINTN *SigSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RSA *Rsa;
|
||||||
|
UINTN Size;
|
||||||
|
INT32 DigestType;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (RsaContext == NULL || MessageHash == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rsa = (RSA *) RsaContext;
|
||||||
|
Size = RSA_size (Rsa);
|
||||||
|
|
||||||
|
if (*SigSize < Size) {
|
||||||
|
*SigSize = Size;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Signature == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the message digest algorithm according to digest size.
|
||||||
|
// Only MD5, SHA-1 or SHA-256 algorithm is supported.
|
||||||
|
//
|
||||||
|
switch (HashSize) {
|
||||||
|
case MD5_DIGEST_SIZE:
|
||||||
|
DigestType = NID_md5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA1_DIGEST_SIZE:
|
||||||
|
DigestType = NID_sha1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHA256_DIGEST_SIZE:
|
||||||
|
DigestType = NID_sha256;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (BOOLEAN) RSA_sign (
|
||||||
|
DigestType,
|
||||||
|
MessageHash,
|
||||||
|
(UINT32) HashSize,
|
||||||
|
Signature,
|
||||||
|
(UINT32 *) SigSize,
|
||||||
|
(RSA *) RsaContext
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
/** @file
|
||||||
|
RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
This file does not provide real capabilities for following APIs in RSA handling:
|
||||||
|
1) RsaGetKey
|
||||||
|
2) RsaGenerateKey
|
||||||
|
3) RsaCheckKey
|
||||||
|
4) RsaPkcs1Sign
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the tag-designated RSA key component from the established RSA context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] RsaContext Pointer to RSA context being set.
|
||||||
|
@param[in] KeyTag Tag of RSA key component being set.
|
||||||
|
@param[out] BigNumber Pointer to octet integer buffer.
|
||||||
|
@param[in, out] BnSize On input, the size of big number buffer in bytes.
|
||||||
|
On output, the size of data returned in big number buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetKey (
|
||||||
|
IN OUT VOID *RsaContext,
|
||||||
|
IN RSA_KEY_TAG KeyTag,
|
||||||
|
OUT UINT8 *BigNumber,
|
||||||
|
IN OUT UINTN *BnSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates RSA key components.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] RsaContext Pointer to RSA context being set.
|
||||||
|
@param[in] ModulusLength Length of RSA modulus N in bits.
|
||||||
|
@param[in] PublicExponent Pointer to RSA public exponent.
|
||||||
|
@param[in] PublicExponentSize Size of RSA public exponent buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGenerateKey (
|
||||||
|
IN OUT VOID *RsaContext,
|
||||||
|
IN UINTN ModulusLength,
|
||||||
|
IN CONST UINT8 *PublicExponent,
|
||||||
|
IN UINTN PublicExponentSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Validates key components of RSA context.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] RsaContext Pointer to RSA context to check.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaCheckKey (
|
||||||
|
IN VOID *RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] RsaContext Pointer to RSA context for signature generation.
|
||||||
|
@param[in] MessageHash Pointer to octet message hash to be signed.
|
||||||
|
@param[in] HashSize Size of the message hash in bytes.
|
||||||
|
@param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature.
|
||||||
|
@param[in, out] SigSize On input, the size of Signature buffer in bytes.
|
||||||
|
On output, the size of data returned in Signature buffer in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaPkcs1Sign (
|
||||||
|
IN VOID *RsaContext,
|
||||||
|
IN CONST UINT8 *MessageHash,
|
||||||
|
IN UINTN HashSize,
|
||||||
|
OUT UINT8 *Signature,
|
||||||
|
IN OUT UINTN *SigSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,665 @@
|
|||||||
|
/** @file
|
||||||
|
RFC3161 Timestamp Countersignature Verification over OpenSSL.
|
||||||
|
The timestamp is generated by a TimeStamping Authority (TSA) and asserts that a
|
||||||
|
publisher's signature existed before the specified time. The timestamp extends
|
||||||
|
the lifetime of the signature when a signing certificate expires or is later
|
||||||
|
revoked.
|
||||||
|
|
||||||
|
Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
#include <openssl/asn1.h>
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/pkcs7.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// OID ASN.1 Value for SPC_RFC3161_OBJID ("1.3.6.1.4.1.311.3.3.1")
|
||||||
|
//
|
||||||
|
UINT8 mSpcRFC3161OidValue[] = {
|
||||||
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The messageImprint field SHOULD contain the hash of the datum to be
|
||||||
|
/// time-stamped. The hash is represented as an OCTET STRING. Its
|
||||||
|
/// length MUST match the length of the hash value for that algorithm
|
||||||
|
/// (e.g., 20 bytes for SHA-1 or 16 bytes for MD5).
|
||||||
|
///
|
||||||
|
/// MessageImprint ::= SEQUENCE {
|
||||||
|
/// hashAlgorithm AlgorithmIdentifier,
|
||||||
|
/// hashedMessage OCTET STRING }
|
||||||
|
///
|
||||||
|
typedef struct {
|
||||||
|
X509_ALGOR *HashAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *HashedMessage;
|
||||||
|
} TS_MESSAGE_IMPRINT;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASN.1 Functions for TS_MESSAGE_IMPRINT
|
||||||
|
//
|
||||||
|
DECLARE_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)
|
||||||
|
ASN1_SEQUENCE (TS_MESSAGE_IMPRINT) = {
|
||||||
|
ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashedMessage, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END (TS_MESSAGE_IMPRINT)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Accuracy represents the time deviation around the UTC time contained
|
||||||
|
/// in GeneralizedTime of time-stamp token.
|
||||||
|
///
|
||||||
|
/// Accuracy ::= SEQUENCE {
|
||||||
|
/// seconds INTEGER OPTIONAL,
|
||||||
|
/// millis [0] INTEGER (1..999) OPTIONAL,
|
||||||
|
/// micros [1] INTEGER (1..999) OPTIONAL }
|
||||||
|
///
|
||||||
|
typedef struct {
|
||||||
|
ASN1_INTEGER *Seconds;
|
||||||
|
ASN1_INTEGER *Millis;
|
||||||
|
ASN1_INTEGER *Micros;
|
||||||
|
} TS_ACCURACY;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASN.1 Functions for TS_ACCURACY
|
||||||
|
//
|
||||||
|
DECLARE_ASN1_FUNCTIONS (TS_ACCURACY)
|
||||||
|
ASN1_SEQUENCE (TS_ACCURACY) = {
|
||||||
|
ASN1_OPT (TS_ACCURACY, Seconds, ASN1_INTEGER),
|
||||||
|
ASN1_IMP_OPT (TS_ACCURACY, Millis, ASN1_INTEGER, 0),
|
||||||
|
ASN1_IMP_OPT (TS_ACCURACY, Micros, ASN1_INTEGER, 1)
|
||||||
|
} ASN1_SEQUENCE_END (TS_ACCURACY)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS (TS_ACCURACY)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The timestamp token info resulting from a successful timestamp request,
|
||||||
|
/// as defined in RFC 3161.
|
||||||
|
///
|
||||||
|
/// TSTInfo ::= SEQUENCE {
|
||||||
|
/// version INTEGER { v1(1) },
|
||||||
|
/// policy TSAPolicyId,
|
||||||
|
/// messageImprint MessageImprint,
|
||||||
|
/// -- MUST have the same value as the similar field in
|
||||||
|
/// -- TimeStampReq
|
||||||
|
/// serialNumber INTEGER,
|
||||||
|
/// -- Time-Stamping users MUST be ready to accommodate integers
|
||||||
|
/// -- up to 160 bits.
|
||||||
|
/// genTime GeneralizedTime,
|
||||||
|
/// accuracy Accuracy OPTIONAL,
|
||||||
|
/// ordering BOOLEAN DEFAULT FALSE,
|
||||||
|
/// nonce INTEGER OPTIONAL,
|
||||||
|
/// -- MUST be present if the similar field was present
|
||||||
|
/// -- in TimeStampReq. In that case it MUST have the same value.
|
||||||
|
/// tsa [0] GeneralName OPTIONAL,
|
||||||
|
/// extensions [1] IMPLICIT Extensions OPTIONAL }
|
||||||
|
///
|
||||||
|
typedef struct {
|
||||||
|
ASN1_INTEGER *Version;
|
||||||
|
ASN1_OBJECT *Policy;
|
||||||
|
TS_MESSAGE_IMPRINT *MessageImprint;
|
||||||
|
ASN1_INTEGER *SerialNumber;
|
||||||
|
ASN1_GENERALIZEDTIME *GenTime;
|
||||||
|
TS_ACCURACY *Accuracy;
|
||||||
|
ASN1_BOOLEAN Ordering;
|
||||||
|
ASN1_INTEGER *Nonce;
|
||||||
|
GENERAL_NAME *Tsa;
|
||||||
|
STACK_OF(X509_EXTENSION) *Extensions;
|
||||||
|
} TS_TST_INFO;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASN.1 Functions for TS_TST_INFO
|
||||||
|
//
|
||||||
|
DECLARE_ASN1_FUNCTIONS (TS_TST_INFO)
|
||||||
|
ASN1_SEQUENCE (TS_TST_INFO) = {
|
||||||
|
ASN1_SIMPLE (TS_TST_INFO, Version, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE (TS_TST_INFO, Policy, ASN1_OBJECT),
|
||||||
|
ASN1_SIMPLE (TS_TST_INFO, MessageImprint, TS_MESSAGE_IMPRINT),
|
||||||
|
ASN1_SIMPLE (TS_TST_INFO, SerialNumber, ASN1_INTEGER),
|
||||||
|
ASN1_SIMPLE (TS_TST_INFO, GenTime, ASN1_GENERALIZEDTIME),
|
||||||
|
ASN1_OPT (TS_TST_INFO, Accuracy, TS_ACCURACY),
|
||||||
|
ASN1_OPT (TS_TST_INFO, Ordering, ASN1_FBOOLEAN),
|
||||||
|
ASN1_OPT (TS_TST_INFO, Nonce, ASN1_INTEGER),
|
||||||
|
ASN1_EXP_OPT(TS_TST_INFO, Tsa, GENERAL_NAME, 0),
|
||||||
|
ASN1_IMP_SEQUENCE_OF_OPT (TS_TST_INFO, Extensions, X509_EXTENSION, 1)
|
||||||
|
} ASN1_SEQUENCE_END (TS_TST_INFO)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS (TS_TST_INFO)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert ASN.1 GeneralizedTime to EFI Time.
|
||||||
|
|
||||||
|
@param[in] Asn1Time Pointer to the ASN.1 GeneralizedTime to be converted.
|
||||||
|
@param[out] SigningTime Return the corresponding EFI Time.
|
||||||
|
|
||||||
|
@retval TRUE The time conversion succeeds.
|
||||||
|
@retval FALSE Invalid parameters.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ConvertAsn1TimeToEfiTime (
|
||||||
|
IN ASN1_TIME *Asn1Time,
|
||||||
|
OUT EFI_TIME *EfiTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CONST CHAR8 *Str;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if ((Asn1Time == NULL) || (EfiTime == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str = (CONST CHAR8*)Asn1Time->data;
|
||||||
|
SetMem (EfiTime, 0, sizeof (EFI_TIME));
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
if (Asn1Time->type == V_ASN1_UTCTIME) { /* two digit year */
|
||||||
|
EfiTime->Year = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Year += (Str[Index++] - '0');
|
||||||
|
if (EfiTime->Year < 70) {
|
||||||
|
EfiTime->Year += 100;
|
||||||
|
}
|
||||||
|
} else if (Asn1Time->type == V_ASN1_GENERALIZEDTIME) { /* four digit year */
|
||||||
|
EfiTime->Year = (Str[Index++] - '0') * 1000;
|
||||||
|
EfiTime->Year += (Str[Index++] - '0') * 100;
|
||||||
|
EfiTime->Year += (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Year += (Str[Index++] - '0');
|
||||||
|
if ((EfiTime->Year < 1900) || (EfiTime->Year > 9999)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiTime->Month = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Month += (Str[Index++] - '0');
|
||||||
|
if ((EfiTime->Month < 1) || (EfiTime->Month > 12)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiTime->Day = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Day += (Str[Index++] - '0');
|
||||||
|
if ((EfiTime->Day < 1) || (EfiTime->Day > 31)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiTime->Hour = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Hour += (Str[Index++] - '0');
|
||||||
|
if (EfiTime->Hour > 23) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiTime->Minute = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Minute += (Str[Index++] - '0');
|
||||||
|
if (EfiTime->Minute > 59) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiTime->Second = (Str[Index++] - '0') * 10;
|
||||||
|
EfiTime->Second += (Str[Index++] - '0');
|
||||||
|
if (EfiTime->Second > 59) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: we did not adjust the time based on time zone information */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
Check the validity of TimeStamp Token Information.
|
||||||
|
|
||||||
|
@param[in] TstInfo Pointer to the TS_TST_INFO structure.
|
||||||
|
@param[in] TimestampedData Pointer to the data to be time-stamped.
|
||||||
|
@param[in] DataSize Size of timestamped data in bytes.
|
||||||
|
|
||||||
|
@retval TRUE The TimeStamp Token Information is valid.
|
||||||
|
@retval FALSE Invalid TimeStamp Token Information.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
CheckTSTInfo (
|
||||||
|
IN CONST TS_TST_INFO *TstInfo,
|
||||||
|
IN CONST UINT8 *TimestampedData,
|
||||||
|
IN UINTN DataSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
TS_MESSAGE_IMPRINT *Imprint;
|
||||||
|
X509_ALGOR *HashAlgo;
|
||||||
|
CONST EVP_MD *Md;
|
||||||
|
EVP_MD_CTX *MdCtx;
|
||||||
|
UINTN MdSize;
|
||||||
|
UINT8 *HashedMsg;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization
|
||||||
|
//
|
||||||
|
Status = FALSE;
|
||||||
|
HashAlgo = NULL;
|
||||||
|
HashedMsg = NULL;
|
||||||
|
MdCtx = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- Check version number of Timestamp:
|
||||||
|
// The version field (currently v1) describes the version of the time-stamp token.
|
||||||
|
// Conforming time-stamping servers MUST be able to provide version 1 time-stamp tokens.
|
||||||
|
//
|
||||||
|
if ((ASN1_INTEGER_get (TstInfo->Version)) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- Check Policies
|
||||||
|
// The policy field MUST indicate the TSA's policy under which the response was produced.
|
||||||
|
//
|
||||||
|
if (TstInfo->Policy == NULL) {
|
||||||
|
/// NOTE: Need to check if the requested and returned policies.
|
||||||
|
/// We have no information about the Requested TSA Policy.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- Compute & Check Message Imprint
|
||||||
|
//
|
||||||
|
Imprint = TstInfo->MessageImprint;
|
||||||
|
HashAlgo = X509_ALGOR_dup (Imprint->HashAlgorithm);
|
||||||
|
|
||||||
|
Md = EVP_get_digestbyobj (HashAlgo->algorithm);
|
||||||
|
if (Md == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MdSize = EVP_MD_size (Md);
|
||||||
|
HashedMsg = AllocateZeroPool (MdSize);
|
||||||
|
if (HashedMsg == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
MdCtx = EVP_MD_CTX_new ();
|
||||||
|
if (MdCtx == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if ((EVP_DigestInit_ex (MdCtx, Md, NULL) != 1) ||
|
||||||
|
(EVP_DigestUpdate (MdCtx, TimestampedData, DataSize) != 1) ||
|
||||||
|
(EVP_DigestFinal (MdCtx, HashedMsg, NULL) != 1)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if ((MdSize == (UINTN)ASN1_STRING_length (Imprint->HashedMessage)) &&
|
||||||
|
(CompareMem (HashedMsg, ASN1_STRING_get0_data (Imprint->HashedMessage), MdSize) != 0)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- Check Nonces
|
||||||
|
//
|
||||||
|
if (TstInfo->Nonce != NULL) {
|
||||||
|
//
|
||||||
|
// Nonces is optional, No error if no nonce is returned;
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- Check if the TSA name and signer certificate is matched.
|
||||||
|
//
|
||||||
|
if (TstInfo->Tsa != NULL) {
|
||||||
|
//
|
||||||
|
// Ignored the optional Tsa field checking.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = TRUE;
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
X509_ALGOR_free (HashAlgo);
|
||||||
|
EVP_MD_CTX_free (MdCtx);
|
||||||
|
if (HashedMsg != NULL) {
|
||||||
|
FreePool (HashedMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a TimeStamp Token as described in RFC 3161 ("Internet
|
||||||
|
X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)").
|
||||||
|
|
||||||
|
If TSToken is NULL, then return FALSE.
|
||||||
|
If TimestampedData is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] TSToken Pointer to the RFC3161 TimeStamp Token, which is generated
|
||||||
|
by a TSA and located in the software publisher's SignerInfo
|
||||||
|
structure.
|
||||||
|
@param[in] TokenSize Size of the TimeStamp Token in bytes.
|
||||||
|
@param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER.
|
||||||
|
@param[in] CertSize Size of the trusted TSA certificate in bytes.
|
||||||
|
@param[in] TimestampedData Pointer to the data to be time-stamped.
|
||||||
|
@param[in] DataSize Size of timestamped data in bytes.
|
||||||
|
@param[out] SigningTime Return the time of timestamp generation time if the timestamp
|
||||||
|
signature is valid.
|
||||||
|
|
||||||
|
@retval TRUE The specified timestamp token is valid.
|
||||||
|
@retval FALSE Invalid timestamp token.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
TimestampTokenVerify (
|
||||||
|
IN CONST UINT8 *TSToken,
|
||||||
|
IN UINTN TokenSize,
|
||||||
|
IN CONST UINT8 *TsaCert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN CONST UINT8 *TimestampedData,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
OUT EFI_TIME *SigningTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
CONST UINT8 *TokenTemp;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
X509 *Cert;
|
||||||
|
CONST UINT8 *CertTemp;
|
||||||
|
X509_STORE *CertStore;
|
||||||
|
BIO *OutBio;
|
||||||
|
UINT8 *TstData;
|
||||||
|
UINTN TstSize;
|
||||||
|
CONST UINT8 *TstTemp;
|
||||||
|
TS_TST_INFO *TstInfo;
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters
|
||||||
|
//
|
||||||
|
if ((TSToken == NULL) || (TsaCert == NULL) || (TimestampedData == NULL) ||
|
||||||
|
(TokenSize > INT_MAX) || (CertSize > INT_MAX) || (DataSize > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializations
|
||||||
|
//
|
||||||
|
if (SigningTime != NULL) {
|
||||||
|
SetMem (SigningTime, sizeof (EFI_TIME), 0);
|
||||||
|
}
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
Cert = NULL;
|
||||||
|
CertStore = NULL;
|
||||||
|
OutBio = NULL;
|
||||||
|
TstData = NULL;
|
||||||
|
TstInfo = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TimeStamp Token should contain one valid DER-encoded ASN.1 PKCS#7 structure.
|
||||||
|
//
|
||||||
|
TokenTemp = TSToken;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &TokenTemp, (int) TokenSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The timestamp signature (TSA's response) will be one PKCS#7 signed data.
|
||||||
|
//
|
||||||
|
if (!PKCS7_type_is_signed (Pkcs7)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the trusted TSA certificate (DER-encoded), and Construct X509 Certificate.
|
||||||
|
//
|
||||||
|
CertTemp = TsaCert;
|
||||||
|
Cert = d2i_X509 (NULL, &CertTemp, (long) CertSize);
|
||||||
|
if (Cert == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup X509 Store for trusted certificate.
|
||||||
|
//
|
||||||
|
CertStore = X509_STORE_new ();
|
||||||
|
if ((CertStore == NULL) || !(X509_STORE_add_cert (CertStore, Cert))) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allow partial certificate chains, terminated by a non-self-signed but
|
||||||
|
// still trusted intermediate certificate. Also disable time checks.
|
||||||
|
//
|
||||||
|
X509_STORE_set_flags (CertStore,
|
||||||
|
X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);
|
||||||
|
|
||||||
|
X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verifies the PKCS#7 signedData structure, and output the signed contents.
|
||||||
|
//
|
||||||
|
OutBio = BIO_new (BIO_s_mem ());
|
||||||
|
if (OutBio == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (!PKCS7_verify (Pkcs7, NULL, CertStore, NULL, OutBio, PKCS7_BINARY)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the signed contents detached in timestamp signature.
|
||||||
|
//
|
||||||
|
TstData = AllocateZeroPool (2048);
|
||||||
|
if (TstData == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
TstSize = BIO_read (OutBio, (void *) TstData, 2048);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct TS_TST_INFO structure from the signed contents.
|
||||||
|
//
|
||||||
|
TstTemp = TstData;
|
||||||
|
TstInfo = d2i_TS_TST_INFO (NULL, (const unsigned char **) &TstTemp,
|
||||||
|
(int)TstSize);
|
||||||
|
if (TstInfo == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check TS_TST_INFO structure.
|
||||||
|
//
|
||||||
|
Status = CheckTSTInfo (TstInfo, TimestampedData, DataSize);
|
||||||
|
if (!Status) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the signing time from TS_TST_INFO structure.
|
||||||
|
//
|
||||||
|
if (SigningTime != NULL) {
|
||||||
|
SetMem (SigningTime, sizeof (EFI_TIME), 0);
|
||||||
|
Status = ConvertAsn1TimeToEfiTime (TstInfo->GenTime, SigningTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
X509_free (Cert);
|
||||||
|
X509_STORE_free (CertStore);
|
||||||
|
BIO_free (OutBio);
|
||||||
|
TS_TST_INFO_free (TstInfo);
|
||||||
|
|
||||||
|
if (TstData != NULL) {
|
||||||
|
FreePool (TstData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode
|
||||||
|
signature.
|
||||||
|
|
||||||
|
If AuthData is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
|
||||||
|
PE/COFF image to be verified.
|
||||||
|
@param[in] DataSize Size of the Authenticode Signature in bytes.
|
||||||
|
@param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER, which
|
||||||
|
is used for TSA certificate chain verification.
|
||||||
|
@param[in] CertSize Size of the trusted certificate in bytes.
|
||||||
|
@param[out] SigningTime Return the time of timestamp generation time if the timestamp
|
||||||
|
signature is valid.
|
||||||
|
|
||||||
|
@retval TRUE The specified Authenticode includes a valid RFC3161 Timestamp CounterSignature.
|
||||||
|
@retval FALSE No valid RFC3161 Timestamp CounterSignature in the specified Authenticode data.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ImageTimestampVerify (
|
||||||
|
IN CONST UINT8 *AuthData,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN CONST UINT8 *TsaCert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT EFI_TIME *SigningTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
PKCS7 *Pkcs7;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
STACK_OF(PKCS7_SIGNER_INFO) *SignerInfos;
|
||||||
|
PKCS7_SIGNER_INFO *SignInfo;
|
||||||
|
UINTN Index;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *Sk;
|
||||||
|
X509_ATTRIBUTE *Xa;
|
||||||
|
ASN1_OBJECT *XaObj;
|
||||||
|
ASN1_TYPE *Asn1Type;
|
||||||
|
ASN1_OCTET_STRING *EncDigest;
|
||||||
|
UINT8 *TSToken;
|
||||||
|
UINTN TokenSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input Parameters Checking.
|
||||||
|
//
|
||||||
|
if ((AuthData == NULL) || (TsaCert == NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register & Initialize necessary digest algorithms for PKCS#7 Handling.
|
||||||
|
//
|
||||||
|
if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
|
||||||
|
(EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization.
|
||||||
|
//
|
||||||
|
Status = FALSE;
|
||||||
|
Pkcs7 = NULL;
|
||||||
|
SignInfo = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Decode ASN.1-encoded Authenticode data into PKCS7 structure.
|
||||||
|
//
|
||||||
|
Temp = AuthData;
|
||||||
|
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) DataSize);
|
||||||
|
if (Pkcs7 == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if there is one and only one signer.
|
||||||
|
//
|
||||||
|
SignerInfos = PKCS7_get_signer_info (Pkcs7);
|
||||||
|
if (!SignerInfos || (sk_PKCS7_SIGNER_INFO_num (SignerInfos) != 1)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate the TimeStamp CounterSignature.
|
||||||
|
//
|
||||||
|
SignInfo = sk_PKCS7_SIGNER_INFO_value (SignerInfos, 0);
|
||||||
|
if (SignInfo == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate Message Digest which will be the data to be time-stamped.
|
||||||
|
//
|
||||||
|
EncDigest = SignInfo->enc_digest;
|
||||||
|
if (EncDigest == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The RFC3161 timestamp counterSignature is contained in unauthenticatedAttributes field
|
||||||
|
// of SignerInfo.
|
||||||
|
//
|
||||||
|
Sk = SignInfo->unauth_attr;
|
||||||
|
if (Sk == NULL) { // No timestamp counterSignature.
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Asn1Type = NULL;
|
||||||
|
for (Index = 0; Index < (UINTN) sk_X509_ATTRIBUTE_num (Sk); Index++) {
|
||||||
|
//
|
||||||
|
// Search valid RFC3161 timestamp counterSignature based on OBJID.
|
||||||
|
//
|
||||||
|
Xa = sk_X509_ATTRIBUTE_value (Sk, (int)Index);
|
||||||
|
if (Xa == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XaObj = X509_ATTRIBUTE_get0_object(Xa);
|
||||||
|
if (XaObj == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((OBJ_length(XaObj) != sizeof (mSpcRFC3161OidValue)) ||
|
||||||
|
(CompareMem (OBJ_get0_data(XaObj), mSpcRFC3161OidValue, sizeof (mSpcRFC3161OidValue)) != 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Asn1Type = X509_ATTRIBUTE_get0_type(Xa, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Asn1Type == NULL) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
TSToken = Asn1Type->value.octet_string->data;
|
||||||
|
TokenSize = Asn1Type->value.octet_string->length;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TimeStamp counterSignature (Token) verification.
|
||||||
|
//
|
||||||
|
Status = TimestampTokenVerify (
|
||||||
|
TSToken,
|
||||||
|
TokenSize,
|
||||||
|
TsaCert,
|
||||||
|
CertSize,
|
||||||
|
EncDigest->data,
|
||||||
|
EncDigest->length,
|
||||||
|
SigningTime
|
||||||
|
);
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources
|
||||||
|
//
|
||||||
|
PKCS7_free (Pkcs7);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/** @file
|
||||||
|
RFC3161 Timestamp Countersignature Verification Wrapper Implementation which does
|
||||||
|
not provide real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verifies the validity of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode
|
||||||
|
signature.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
|
||||||
|
PE/COFF image to be verified.
|
||||||
|
@param[in] DataSize Size of the Authenticode Signature in bytes.
|
||||||
|
@param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER, which
|
||||||
|
is used for TSA certificate chain verification.
|
||||||
|
@param[in] CertSize Size of the trusted certificate in bytes.
|
||||||
|
@param[out] SigningTime Return the time of timestamp generation time if the timestamp
|
||||||
|
signature is valid.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ImageTimestampVerify (
|
||||||
|
IN CONST UINT8 *AuthData,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN CONST UINT8 *TsaCert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT EFI_TIME *SigningTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,730 @@
|
|||||||
|
/** @file
|
||||||
|
X.509 Certificate Handler Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Construct a X509 object from DER-encoded certificate data.
|
||||||
|
|
||||||
|
If Cert is NULL, then return FALSE.
|
||||||
|
If SingleX509Cert is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded certificate data.
|
||||||
|
@param[in] CertSize The size of certificate data in bytes.
|
||||||
|
@param[out] SingleX509Cert The generated X509 object.
|
||||||
|
|
||||||
|
@retval TRUE The X509 object generation succeeded.
|
||||||
|
@retval FALSE The operation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509ConstructCertificate (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 **SingleX509Cert
|
||||||
|
)
|
||||||
|
{
|
||||||
|
X509 *X509Cert;
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Cert == NULL || SingleX509Cert == NULL || CertSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded X509 Certificate and Construct X509 object.
|
||||||
|
//
|
||||||
|
Temp = Cert;
|
||||||
|
X509Cert = d2i_X509 (NULL, &Temp, (long) CertSize);
|
||||||
|
if (X509Cert == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*SingleX509Cert = (UINT8 *) X509Cert;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Construct a X509 stack object from a list of DER-encoded certificate data.
|
||||||
|
|
||||||
|
If X509Stack is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in, out] X509Stack On input, pointer to an existing or NULL X509 stack object.
|
||||||
|
On output, pointer to the X509 stack object with new
|
||||||
|
inserted X509 certificate.
|
||||||
|
@param ... A list of DER-encoded single certificate data followed
|
||||||
|
by certificate size. A NULL terminates the list. The
|
||||||
|
pairs are the arguments to X509ConstructCertificate().
|
||||||
|
|
||||||
|
@retval TRUE The X509 stack construction succeeded.
|
||||||
|
@retval FALSE The construction operation failed.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509ConstructCertificateStack (
|
||||||
|
IN OUT UINT8 **X509Stack,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 *Cert;
|
||||||
|
UINTN CertSize;
|
||||||
|
X509 *X509Cert;
|
||||||
|
STACK_OF(X509) *CertStack;
|
||||||
|
BOOLEAN Status;
|
||||||
|
VA_LIST Args;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (X509Stack == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize X509 stack object.
|
||||||
|
//
|
||||||
|
CertStack = (STACK_OF(X509) *) (*X509Stack);
|
||||||
|
if (CertStack == NULL) {
|
||||||
|
CertStack = sk_X509_new_null ();
|
||||||
|
if (CertStack == NULL) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VA_START (Args, X509Stack);
|
||||||
|
|
||||||
|
for (Index = 0; ; Index++) {
|
||||||
|
//
|
||||||
|
// If Cert is NULL, then it is the end of the list.
|
||||||
|
//
|
||||||
|
Cert = VA_ARG (Args, UINT8 *);
|
||||||
|
if (Cert == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CertSize = VA_ARG (Args, UINTN);
|
||||||
|
if (CertSize == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct X509 Object from the given DER-encoded certificate data.
|
||||||
|
//
|
||||||
|
X509Cert = NULL;
|
||||||
|
Status = X509ConstructCertificate (
|
||||||
|
(CONST UINT8 *) Cert,
|
||||||
|
CertSize,
|
||||||
|
(UINT8 **) &X509Cert
|
||||||
|
);
|
||||||
|
if (!Status) {
|
||||||
|
if (X509Cert != NULL) {
|
||||||
|
X509_free (X509Cert);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert the new X509 object into X509 stack object.
|
||||||
|
//
|
||||||
|
sk_X509_push (CertStack, X509Cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
VA_END (Args);
|
||||||
|
|
||||||
|
if (!Status) {
|
||||||
|
sk_X509_pop_free (CertStack, X509_free);
|
||||||
|
} else {
|
||||||
|
*X509Stack = (UINT8 *) CertStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified X509 object.
|
||||||
|
|
||||||
|
If X509Cert is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] X509Cert Pointer to the X509 object to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
X509Free (
|
||||||
|
IN VOID *X509Cert
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (X509Cert == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free OpenSSL X509 object.
|
||||||
|
//
|
||||||
|
X509_free ((X509 *) X509Cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified X509 stack object.
|
||||||
|
|
||||||
|
If X509Stack is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[in] X509Stack Pointer to the X509 stack object to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
X509StackFree (
|
||||||
|
IN VOID *X509Stack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (X509Stack == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free OpenSSL X509 stack object.
|
||||||
|
//
|
||||||
|
sk_X509_pop_free ((STACK_OF(X509) *) X509Stack, X509_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the subject bytes from one X.509 certificate.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] CertSubject Pointer to the retrieved certificate subject bytes.
|
||||||
|
@param[in, out] SubjectSize The size in bytes of the CertSubject buffer on input,
|
||||||
|
and the size of buffer returned CertSubject on output.
|
||||||
|
|
||||||
|
If Cert is NULL, then return FALSE.
|
||||||
|
If SubjectSize is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@retval TRUE The certificate subject retrieved successfully.
|
||||||
|
@retval FALSE Invalid certificate, or the SubjectSize is too small for the result.
|
||||||
|
The SubjectSize will be updated with the required size.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509GetSubjectName (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 *CertSubject,
|
||||||
|
IN OUT UINTN *SubjectSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
X509 *X509Cert;
|
||||||
|
X509_NAME *X509Name;
|
||||||
|
UINTN X509NameSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Cert == NULL || SubjectSize == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509Cert = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded X509 Certificate and Construct X509 object.
|
||||||
|
//
|
||||||
|
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||||
|
if ((X509Cert == NULL) || (!Status)) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve subject name from certificate object.
|
||||||
|
//
|
||||||
|
X509Name = X509_get_subject_name (X509Cert);
|
||||||
|
if (X509Name == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509NameSize = i2d_X509_NAME(X509Name, NULL);
|
||||||
|
if (*SubjectSize < X509NameSize) {
|
||||||
|
*SubjectSize = X509NameSize;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
*SubjectSize = X509NameSize;
|
||||||
|
if (CertSubject != NULL) {
|
||||||
|
i2d_X509_NAME(X509Name, &CertSubject);
|
||||||
|
Status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
if (X509Cert != NULL) {
|
||||||
|
X509_free (X509Cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the common name (CN) string from one X.509 certificate.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] CommonName Buffer to contain the retrieved certificate common
|
||||||
|
name string (UTF8). At most CommonNameSize bytes will be
|
||||||
|
written and the string will be null terminated. May be
|
||||||
|
NULL in order to determine the size buffer needed.
|
||||||
|
@param[in,out] CommonNameSize The size in bytes of the CommonName buffer on input,
|
||||||
|
and the size of buffer returned CommonName on output.
|
||||||
|
If CommonName is NULL then the amount of space needed
|
||||||
|
in buffer (including the final null) is returned.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS The certificate CommonName retrieved successfully.
|
||||||
|
@retval RETURN_INVALID_PARAMETER If Cert is NULL.
|
||||||
|
If CommonNameSize is NULL.
|
||||||
|
If CommonName is not NULL and *CommonNameSize is 0.
|
||||||
|
If Certificate is invalid.
|
||||||
|
@retval RETURN_NOT_FOUND If no CommonName entry exists.
|
||||||
|
@retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required buffer size
|
||||||
|
(including the final null) is returned in the
|
||||||
|
CommonNameSize parameter.
|
||||||
|
@retval RETURN_UNSUPPORTED The operation is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
X509GetCommonName (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT CHAR8 *CommonName, OPTIONAL
|
||||||
|
IN OUT UINTN *CommonNameSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS ReturnStatus;
|
||||||
|
BOOLEAN Status;
|
||||||
|
X509 *X509Cert;
|
||||||
|
X509_NAME *X509Name;
|
||||||
|
INT32 Index;
|
||||||
|
INTN Length;
|
||||||
|
X509_NAME_ENTRY *Entry;
|
||||||
|
ASN1_STRING *EntryData;
|
||||||
|
UINT8 *UTF8Name;
|
||||||
|
|
||||||
|
ReturnStatus = RETURN_INVALID_PARAMETER;
|
||||||
|
UTF8Name = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if ((Cert == NULL) || (CertSize > INT_MAX) || (CommonNameSize == NULL)) {
|
||||||
|
return ReturnStatus;
|
||||||
|
}
|
||||||
|
if ((CommonName != NULL) && (*CommonNameSize == 0)) {
|
||||||
|
return ReturnStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509Cert = NULL;
|
||||||
|
//
|
||||||
|
// Read DER-encoded X509 Certificate and Construct X509 object.
|
||||||
|
//
|
||||||
|
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||||
|
if ((X509Cert == NULL) || (!Status)) {
|
||||||
|
//
|
||||||
|
// Invalid X.509 Certificate
|
||||||
|
//
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve subject name from certificate object.
|
||||||
|
//
|
||||||
|
X509Name = X509_get_subject_name (X509Cert);
|
||||||
|
if (X509Name == NULL) {
|
||||||
|
//
|
||||||
|
// Fail to retrieve subject name content
|
||||||
|
//
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the CommonName information from X.509 Subject
|
||||||
|
//
|
||||||
|
Index = X509_NAME_get_index_by_NID (X509Name, NID_commonName, -1);
|
||||||
|
if (Index < 0) {
|
||||||
|
//
|
||||||
|
// No CommonName entry exists in X509_NAME object
|
||||||
|
//
|
||||||
|
*CommonNameSize = 0;
|
||||||
|
ReturnStatus = RETURN_NOT_FOUND;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = X509_NAME_get_entry (X509Name, Index);
|
||||||
|
if (Entry == NULL) {
|
||||||
|
//
|
||||||
|
// Fail to retrieve name entry data
|
||||||
|
//
|
||||||
|
*CommonNameSize = 0;
|
||||||
|
ReturnStatus = RETURN_NOT_FOUND;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryData = X509_NAME_ENTRY_get_data (Entry);
|
||||||
|
|
||||||
|
Length = ASN1_STRING_to_UTF8 (&UTF8Name, EntryData);
|
||||||
|
if (Length < 0) {
|
||||||
|
//
|
||||||
|
// Fail to convert the commonName string
|
||||||
|
//
|
||||||
|
*CommonNameSize = 0;
|
||||||
|
ReturnStatus = RETURN_INVALID_PARAMETER;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommonName == NULL) {
|
||||||
|
*CommonNameSize = Length + 1;
|
||||||
|
ReturnStatus = RETURN_BUFFER_TOO_SMALL;
|
||||||
|
} else {
|
||||||
|
*CommonNameSize = MIN ((UINTN)Length, *CommonNameSize - 1) + 1;
|
||||||
|
CopyMem (CommonName, UTF8Name, *CommonNameSize - 1);
|
||||||
|
CommonName[*CommonNameSize - 1] = '\0';
|
||||||
|
ReturnStatus = RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
if (X509Cert != NULL) {
|
||||||
|
X509_free (X509Cert);
|
||||||
|
}
|
||||||
|
if (UTF8Name != NULL) {
|
||||||
|
OPENSSL_free (UTF8Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReturnStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the RSA Public Key from one DER-encoded X509 certificate.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved
|
||||||
|
RSA public key component. Use RsaFree() function to free the
|
||||||
|
resource.
|
||||||
|
|
||||||
|
If Cert is NULL, then return FALSE.
|
||||||
|
If RsaContext is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@retval TRUE RSA Public Key was retrieved successfully.
|
||||||
|
@retval FALSE Fail to retrieve RSA public key from X509 certificate.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetPublicKeyFromX509 (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT VOID **RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
EVP_PKEY *Pkey;
|
||||||
|
X509 *X509Cert;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Cert == NULL || RsaContext == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pkey = NULL;
|
||||||
|
X509Cert = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded X509 Certificate and Construct X509 object.
|
||||||
|
//
|
||||||
|
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||||
|
if ((X509Cert == NULL) || (!Status)) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve and check EVP_PKEY data from X509 Certificate.
|
||||||
|
//
|
||||||
|
Pkey = X509_get_pubkey (X509Cert);
|
||||||
|
if ((Pkey == NULL) || (EVP_PKEY_id (Pkey) != EVP_PKEY_RSA)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Duplicate RSA Context from the retrieved EVP_PKEY.
|
||||||
|
//
|
||||||
|
if ((*RsaContext = RSAPublicKey_dup (EVP_PKEY_get0_RSA (Pkey))) != NULL) {
|
||||||
|
Status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
if (X509Cert != NULL) {
|
||||||
|
X509_free (X509Cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pkey != NULL) {
|
||||||
|
EVP_PKEY_free (Pkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verify one X509 certificate was issued by the trusted CA.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate to be verified.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[in] CACert Pointer to the DER-encoded trusted CA certificate.
|
||||||
|
@param[in] CACertSize Size of the CA Certificate in bytes.
|
||||||
|
|
||||||
|
If Cert is NULL, then return FALSE.
|
||||||
|
If CACert is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@retval TRUE The certificate was issued by the trusted CA.
|
||||||
|
@retval FALSE Invalid certificate or the certificate was not issued by the given
|
||||||
|
trusted CA.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509VerifyCert (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN CONST UINT8 *CACert,
|
||||||
|
IN UINTN CACertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Status;
|
||||||
|
X509 *X509Cert;
|
||||||
|
X509 *X509CACert;
|
||||||
|
X509_STORE *CertStore;
|
||||||
|
X509_STORE_CTX *CertCtx;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Cert == NULL || CACert == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
X509Cert = NULL;
|
||||||
|
X509CACert = NULL;
|
||||||
|
CertStore = NULL;
|
||||||
|
CertCtx = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register & Initialize necessary digest algorithms for certificate verification.
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_md5 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (EVP_add_digest (EVP_sha256 ()) == 0) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded certificate to be verified and Construct X509 object.
|
||||||
|
//
|
||||||
|
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||||
|
if ((X509Cert == NULL) || (!Status)) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read DER-encoded root certificate and Construct X509 object.
|
||||||
|
//
|
||||||
|
Status = X509ConstructCertificate (CACert, CACertSize, (UINT8 **) &X509CACert);
|
||||||
|
if ((X509CACert == NULL) || (!Status)) {
|
||||||
|
Status = FALSE;
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up X509 Store for trusted certificate.
|
||||||
|
//
|
||||||
|
CertStore = X509_STORE_new ();
|
||||||
|
if (CertStore == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (!(X509_STORE_add_cert (CertStore, X509CACert))) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allow partial certificate chains, terminated by a non-self-signed but
|
||||||
|
// still trusted intermediate certificate. Also disable time checks.
|
||||||
|
//
|
||||||
|
X509_STORE_set_flags (CertStore,
|
||||||
|
X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up X509_STORE_CTX for the subsequent verification operation.
|
||||||
|
//
|
||||||
|
CertCtx = X509_STORE_CTX_new ();
|
||||||
|
if (CertCtx == NULL) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
if (!X509_STORE_CTX_init (CertCtx, CertStore, X509Cert, NULL)) {
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// X509 Certificate Verification.
|
||||||
|
//
|
||||||
|
Status = (BOOLEAN) X509_verify_cert (CertCtx);
|
||||||
|
X509_STORE_CTX_cleanup (CertCtx);
|
||||||
|
|
||||||
|
_Exit:
|
||||||
|
//
|
||||||
|
// Release Resources.
|
||||||
|
//
|
||||||
|
if (X509Cert != NULL) {
|
||||||
|
X509_free (X509Cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X509CACert != NULL) {
|
||||||
|
X509_free (X509CACert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CertStore != NULL) {
|
||||||
|
X509_STORE_free (CertStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_STORE_CTX_free (CertCtx);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the TBSCertificate from one given X.509 certificate.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the given DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] TBSCert DER-Encoded To-Be-Signed certificate.
|
||||||
|
@param[out] TBSCertSize Size of the TBS certificate in bytes.
|
||||||
|
|
||||||
|
If Cert is NULL, then return FALSE.
|
||||||
|
If TBSCert is NULL, then return FALSE.
|
||||||
|
If TBSCertSize is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@retval TRUE The TBSCertificate was retrieved successfully.
|
||||||
|
@retval FALSE Invalid X.509 certificate.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509GetTBSCert (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 **TBSCert,
|
||||||
|
OUT UINTN *TBSCertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CONST UINT8 *Temp;
|
||||||
|
UINT32 Asn1Tag;
|
||||||
|
UINT32 ObjClass;
|
||||||
|
UINTN Length;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if ((Cert == NULL) || (TBSCert == NULL) ||
|
||||||
|
(TBSCertSize == NULL) || (CertSize > INT_MAX)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// An X.509 Certificate is: (defined in RFC3280)
|
||||||
|
// Certificate ::= SEQUENCE {
|
||||||
|
// tbsCertificate TBSCertificate,
|
||||||
|
// signatureAlgorithm AlgorithmIdentifier,
|
||||||
|
// signature BIT STRING }
|
||||||
|
//
|
||||||
|
// and
|
||||||
|
//
|
||||||
|
// TBSCertificate ::= SEQUENCE {
|
||||||
|
// version [0] Version DEFAULT v1,
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// So we can just ASN1-parse the x.509 DER-encoded data. If we strip
|
||||||
|
// the first SEQUENCE, the second SEQUENCE is the TBSCertificate.
|
||||||
|
//
|
||||||
|
Temp = Cert;
|
||||||
|
Length = 0;
|
||||||
|
ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);
|
||||||
|
|
||||||
|
if (Asn1Tag != V_ASN1_SEQUENCE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*TBSCert = (UINT8 *)Temp;
|
||||||
|
|
||||||
|
ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
|
||||||
|
//
|
||||||
|
// Verify the parsed TBSCertificate is one correct SEQUENCE data.
|
||||||
|
//
|
||||||
|
if (Asn1Tag != V_ASN1_SEQUENCE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*TBSCertSize = Length + (Temp - *TBSCert);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,238 @@
|
|||||||
|
/** @file
|
||||||
|
X.509 Certificate Handler Wrapper Implementation which does not provide
|
||||||
|
real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Construct a X509 object from DER-encoded certificate data.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded certificate data.
|
||||||
|
@param[in] CertSize The size of certificate data in bytes.
|
||||||
|
@param[out] SingleX509Cert The generated X509 object.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509ConstructCertificate (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 **SingleX509Cert
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Construct a X509 stack object from a list of DER-encoded certificate data.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in, out] X509Stack On input, pointer to an existing or NULL X509 stack object.
|
||||||
|
On output, pointer to the X509 stack object with new
|
||||||
|
inserted X509 certificate.
|
||||||
|
@param ... A list of DER-encoded single certificate data followed
|
||||||
|
by certificate size. A NULL terminates the list. The
|
||||||
|
pairs are the arguments to X509ConstructCertificate().
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509ConstructCertificateStack (
|
||||||
|
IN OUT UINT8 **X509Stack,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified X509 object.
|
||||||
|
|
||||||
|
If the interface is not supported, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] X509Cert Pointer to the X509 object to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
X509Free (
|
||||||
|
IN VOID *X509Cert
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release the specified X509 stack object.
|
||||||
|
|
||||||
|
If the interface is not supported, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] X509Stack Pointer to the X509 stack object to be released.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
X509StackFree (
|
||||||
|
IN VOID *X509Stack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the subject bytes from one X.509 certificate.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] CertSubject Pointer to the retrieved certificate subject bytes.
|
||||||
|
@param[in, out] SubjectSize The size in bytes of the CertSubject buffer on input,
|
||||||
|
and the size of buffer returned CertSubject on output.
|
||||||
|
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509GetSubjectName (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 *CertSubject,
|
||||||
|
IN OUT UINTN *SubjectSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the common name (CN) string from one X.509 certificate.
|
||||||
|
|
||||||
|
Return RETURN_UNSUPPORTED to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] CommonName Buffer to contain the retrieved certificate common
|
||||||
|
name string (UTF8). At most CommonNameSize bytes will be
|
||||||
|
written and the string will be null terminated. May be
|
||||||
|
NULL in order to determine the size buffer needed.
|
||||||
|
@param[in,out] CommonNameSize The size in bytes of the CommonName buffer on input,
|
||||||
|
and the size of buffer returned CommonName on output.
|
||||||
|
If CommonName is NULL then the amount of space needed
|
||||||
|
in buffer (including the final null) is returned.
|
||||||
|
|
||||||
|
@retval RETURN_UNSUPPORTED The operation is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
X509GetCommonName (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT CHAR8 *CommonName, OPTIONAL
|
||||||
|
IN OUT UINTN *CommonNameSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the RSA Public Key from one DER-encoded X509 certificate.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved
|
||||||
|
RSA public key component. Use RsaFree() function to free the
|
||||||
|
resource.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RsaGetPublicKeyFromX509 (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT VOID **RsaContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verify one X509 certificate was issued by the trusted CA.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the DER-encoded X509 certificate to be verified.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[in] CACert Pointer to the DER-encoded trusted CA certificate.
|
||||||
|
@param[in] CACertSize Size of the CA Certificate in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509VerifyCert (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
IN CONST UINT8 *CACert,
|
||||||
|
IN UINTN CACertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the TBSCertificate from one given X.509 certificate.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Cert Pointer to the given DER-encoded X509 certificate.
|
||||||
|
@param[in] CertSize Size of the X509 certificate in bytes.
|
||||||
|
@param[out] TBSCert DER-Encoded To-Be-Signed certificate.
|
||||||
|
@param[out] TBSCertSize Size of the TBS certificate in bytes.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
X509GetTBSCert (
|
||||||
|
IN CONST UINT8 *Cert,
|
||||||
|
IN UINTN CertSize,
|
||||||
|
OUT UINT8 **TBSCert,
|
||||||
|
OUT UINTN *TBSCertSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
/** @file
|
||||||
|
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default seed for UEFI Crypto Library
|
||||||
|
//
|
||||||
|
CONST UINT8 DefaultSeed[] = "UEFI Crypto Library default seed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets up the seed value for the pseudorandom number generator.
|
||||||
|
|
||||||
|
This function sets up the seed value for the pseudorandom number generator.
|
||||||
|
If Seed is not NULL, then the seed passed in is used.
|
||||||
|
If Seed is NULL, then default seed is used.
|
||||||
|
|
||||||
|
@param[in] Seed Pointer to seed value.
|
||||||
|
If NULL, default seed is used.
|
||||||
|
@param[in] SeedSize Size of seed value.
|
||||||
|
If Seed is NULL, this parameter is ignored.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom number generator has enough entropy for random generation.
|
||||||
|
@retval FALSE Pseudorandom number generator does not have enough entropy for random generation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomSeed (
|
||||||
|
IN CONST UINT8 *Seed OPTIONAL,
|
||||||
|
IN UINTN SeedSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (SeedSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The software PRNG implementation built in OpenSSL depends on message digest algorithm.
|
||||||
|
// Make sure SHA-1 digest algorithm is available here.
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Seed the pseudorandom number generator with user-supplied value.
|
||||||
|
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
|
||||||
|
//
|
||||||
|
if (Seed != NULL) {
|
||||||
|
RAND_seed (Seed, (UINT32) SeedSize);
|
||||||
|
} else {
|
||||||
|
RAND_seed (DefaultSeed, sizeof (DefaultSeed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RAND_status () == 1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates a pseudorandom byte stream of the specified size.
|
||||||
|
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Output Pointer to buffer to receive random value.
|
||||||
|
@param[in] Size Size of random bytes to generate.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom byte stream generated successfully.
|
||||||
|
@retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomBytes (
|
||||||
|
OUT UINT8 *Output,
|
||||||
|
IN UINTN Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Output == NULL || Size > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate random data.
|
||||||
|
//
|
||||||
|
if (RAND_bytes (Output, (UINT32) Size) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
/** @file
|
||||||
|
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets up the seed value for the pseudorandom number generator.
|
||||||
|
|
||||||
|
This function sets up the seed value for the pseudorandom number generator.
|
||||||
|
If Seed is not NULL, then the seed passed in is used.
|
||||||
|
If Seed is NULL, then default seed is used.
|
||||||
|
|
||||||
|
@param[in] Seed Pointer to seed value.
|
||||||
|
If NULL, default seed is used.
|
||||||
|
@param[in] SeedSize Size of seed value.
|
||||||
|
If Seed is NULL, this parameter is ignored.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom number generator has enough entropy for random generation.
|
||||||
|
@retval FALSE Pseudorandom number generator does not have enough entropy for random generation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomSeed (
|
||||||
|
IN CONST UINT8 *Seed OPTIONAL,
|
||||||
|
IN UINTN SeedSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHAR8 DefaultSeed[128];
|
||||||
|
|
||||||
|
if (SeedSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The software PRNG implementation built in OpenSSL depends on message digest algorithm.
|
||||||
|
// Make sure SHA-1 digest algorithm is available here.
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Seed the pseudorandom number generator with user-supplied value.
|
||||||
|
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
|
||||||
|
//
|
||||||
|
if (Seed != NULL) {
|
||||||
|
RAND_seed (Seed, (UINT32) SeedSize);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Retrieve current time.
|
||||||
|
//
|
||||||
|
AsciiSPrint (
|
||||||
|
DefaultSeed,
|
||||||
|
sizeof (DefaultSeed),
|
||||||
|
"UEFI Crypto Library default seed (%ld)",
|
||||||
|
AsmReadItc ()
|
||||||
|
);
|
||||||
|
|
||||||
|
RAND_seed (DefaultSeed, sizeof (DefaultSeed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RAND_status () == 1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates a pseudorandom byte stream of the specified size.
|
||||||
|
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Output Pointer to buffer to receive random value.
|
||||||
|
@param[in] Size Size of random bytes to generate.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom byte stream generated successfully.
|
||||||
|
@retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomBytes (
|
||||||
|
OUT UINT8 *Output,
|
||||||
|
IN UINTN Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Output == NULL || Size > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate random data.
|
||||||
|
//
|
||||||
|
if (RAND_bytes (Output, (UINT32) Size) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/** @file
|
||||||
|
Pseudorandom Number Generator Wrapper Implementation which does not provide
|
||||||
|
real capabilities.
|
||||||
|
|
||||||
|
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets up the seed value for the pseudorandom number generator.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[in] Seed Pointer to seed value.
|
||||||
|
If NULL, default seed is used.
|
||||||
|
@param[in] SeedSize Size of seed value.
|
||||||
|
If Seed is NULL, this parameter is ignored.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomSeed (
|
||||||
|
IN CONST UINT8 *Seed OPTIONAL,
|
||||||
|
IN UINTN SeedSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates a pseudorandom byte stream of the specified size.
|
||||||
|
|
||||||
|
Return FALSE to indicate this interface is not supported.
|
||||||
|
|
||||||
|
@param[out] Output Pointer to buffer to receive random value.
|
||||||
|
@param[in] Size Size of random bytes to generate.
|
||||||
|
|
||||||
|
@retval FALSE This interface is not supported.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomBytes (
|
||||||
|
OUT UINT8 *Output,
|
||||||
|
IN UINTN Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
/** @file
|
||||||
|
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
|
||||||
|
|
||||||
|
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 "InternalCryptLib.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets up the seed value for the pseudorandom number generator.
|
||||||
|
|
||||||
|
This function sets up the seed value for the pseudorandom number generator.
|
||||||
|
If Seed is not NULL, then the seed passed in is used.
|
||||||
|
If Seed is NULL, then default seed is used.
|
||||||
|
|
||||||
|
@param[in] Seed Pointer to seed value.
|
||||||
|
If NULL, default seed is used.
|
||||||
|
@param[in] SeedSize Size of seed value.
|
||||||
|
If Seed is NULL, this parameter is ignored.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom number generator has enough entropy for random generation.
|
||||||
|
@retval FALSE Pseudorandom number generator does not have enough entropy for random generation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomSeed (
|
||||||
|
IN CONST UINT8 *Seed OPTIONAL,
|
||||||
|
IN UINTN SeedSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHAR8 DefaultSeed[128];
|
||||||
|
|
||||||
|
if (SeedSize > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The software PRNG implementation built in OpenSSL depends on message digest algorithm.
|
||||||
|
// Make sure SHA-1 digest algorithm is available here.
|
||||||
|
//
|
||||||
|
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Seed the pseudorandom number generator with user-supplied value.
|
||||||
|
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
|
||||||
|
//
|
||||||
|
if (Seed != NULL) {
|
||||||
|
RAND_seed (Seed, (UINT32) SeedSize);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Retrieve current time.
|
||||||
|
//
|
||||||
|
AsciiSPrint (
|
||||||
|
DefaultSeed,
|
||||||
|
sizeof (DefaultSeed),
|
||||||
|
"UEFI Crypto Library default seed (%ld)",
|
||||||
|
AsmReadTsc ()
|
||||||
|
);
|
||||||
|
|
||||||
|
RAND_seed (DefaultSeed, sizeof (DefaultSeed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RAND_status () == 1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Generates a pseudorandom byte stream of the specified size.
|
||||||
|
|
||||||
|
If Output is NULL, then return FALSE.
|
||||||
|
|
||||||
|
@param[out] Output Pointer to buffer to receive random value.
|
||||||
|
@param[in] Size Size of random bytes to generate.
|
||||||
|
|
||||||
|
@retval TRUE Pseudorandom byte stream generated successfully.
|
||||||
|
@retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
RandomBytes (
|
||||||
|
OUT UINT8 *Output,
|
||||||
|
IN UINTN Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check input parameters.
|
||||||
|
//
|
||||||
|
if (Output == NULL || Size > INT_MAX) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate random data.
|
||||||
|
//
|
||||||
|
if (RAND_bytes (Output, (UINT32) Size) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
## @file
|
||||||
|
# Cryptographic Library Instance for DXE_RUNTIME_DRIVER.
|
||||||
|
#
|
||||||
|
# Caution: This module requires additional review when modified.
|
||||||
|
# This library will have external input - signature.
|
||||||
|
# This external input must be validated carefully to avoid security issues such as
|
||||||
|
# buffer overflow or integer overflow.
|
||||||
|
#
|
||||||
|
# Note: MD4 Digest functions, SHA-384 Digest functions, SHA-512 Digest functions,
|
||||||
|
# HMAC-MD5 functions, HMAC-SHA1/SHA256 functions, AES/TDES/ARC4 functions, RSA external
|
||||||
|
# functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and
|
||||||
|
# authenticode signature verification functions are not supported in this instance.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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
|
||||||
|
MODULE_UNI_FILE = RuntimeCryptLib.uni
|
||||||
|
FILE_GUID = 78189cc0-727d-46a4-84ea-f7dd860de64a
|
||||||
|
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BaseCryptLib|DXE_RUNTIME_DRIVER
|
||||||
|
CONSTRUCTOR = RuntimeCryptLibConstructor
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
Hash/CryptMd4Null.c
|
||||||
|
Hash/CryptMd5.c
|
||||||
|
Hash/CryptSha1.c
|
||||||
|
Hash/CryptSha256.c
|
||||||
|
Hash/CryptSha512Null.c
|
||||||
|
Hmac/CryptHmacMd5Null.c
|
||||||
|
Hmac/CryptHmacSha1Null.c
|
||||||
|
Hmac/CryptHmacSha256Null.c
|
||||||
|
Cipher/CryptAesNull.c
|
||||||
|
Cipher/CryptTdesNull.c
|
||||||
|
Cipher/CryptArc4Null.c
|
||||||
|
Pk/CryptRsaBasic.c
|
||||||
|
Pk/CryptRsaExtNull.c
|
||||||
|
Pk/CryptPkcs5Pbkdf2Null.c
|
||||||
|
Pk/CryptPkcs7SignNull.c
|
||||||
|
Pk/CryptPkcs7VerifyCommon.c
|
||||||
|
Pk/CryptPkcs7VerifyRuntime.c
|
||||||
|
Pk/CryptDhNull.c
|
||||||
|
Pk/CryptX509.c
|
||||||
|
Pk/CryptAuthenticodeNull.c
|
||||||
|
Pk/CryptTsNull.c
|
||||||
|
Pem/CryptPem.c
|
||||||
|
|
||||||
|
SysCall/CrtWrapper.c
|
||||||
|
SysCall/TimerWrapper.c
|
||||||
|
SysCall/RuntimeMemAllocation.c
|
||||||
|
|
||||||
|
[Sources.Ia32]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.ARM]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
CryptoPkg/CryptoPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
BaseMemoryLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
DebugLib
|
||||||
|
OpensslLib
|
||||||
|
IntrinsicLib
|
||||||
|
PrintLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove these [BuildOptions] after this library is cleaned up
|
||||||
|
#
|
||||||
|
[BuildOptions]
|
||||||
|
#
|
||||||
|
# suppress the following warnings so we do not break the build with warnings-as-errors:
|
||||||
|
# C4090: 'function' : different 'const' qualifiers
|
||||||
|
#
|
||||||
|
MSFT:*_*_*_CC_FLAGS = /wd4090
|
||||||
|
|
||||||
|
# -JCryptoPkg/Include : To disable the use of the system includes provided by RVCT
|
||||||
|
# --diag_remark=1 : Reduce severity of "#1-D: last line of file ends without a newline"
|
||||||
|
RVCT:*_*_ARM_CC_FLAGS = -JCryptoPkg/Include --diag_remark=1
|
@ -0,0 +1,30 @@
|
|||||||
|
// /** @file
|
||||||
|
// Cryptographic Library Instance for DXE_RUNTIME_DRIVER.
|
||||||
|
//
|
||||||
|
// Caution: This module requires additional review when modified.
|
||||||
|
// This library will have external input - signature.
|
||||||
|
// This external input must be validated carefully to avoid security issues such as
|
||||||
|
// buffer overflow or integer overflow.
|
||||||
|
//
|
||||||
|
// Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/
|
||||||
|
// TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions,
|
||||||
|
// Diffie-Hellman functions, and authenticode signature verification functions are
|
||||||
|
// not supported in this instance.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "Cryptographic Library Instance for DXE_RUNTIME_DRIVER"
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "Caution: This module requires additional review when modified. This library will have external input - signature. This external input must be validated carefully to avoid security issues such as buffer overflow or integer overflow. Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/ TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and authenticode signature verification functions are not supported in this instance."
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
## @file
|
||||||
|
# Cryptographic Library Instance for SMM driver.
|
||||||
|
#
|
||||||
|
# Caution: This module requires additional review when modified.
|
||||||
|
# This library will have external input - signature.
|
||||||
|
# This external input must be validated carefully to avoid security issues such as
|
||||||
|
# buffer overflow or integer overflow.
|
||||||
|
#
|
||||||
|
# Note: MD4 Digest functions, SHA-384 Digest functions, SHA-512 Digest functions,
|
||||||
|
# HMAC-MD5 functions, HMAC-SHA1 functions, TDES/ARC4 functions, RSA external
|
||||||
|
# functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and
|
||||||
|
# authenticode signature verification functions are not supported in this instance.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# 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 = SmmCryptLib
|
||||||
|
MODULE_UNI_FILE = SmmCryptLib.uni
|
||||||
|
FILE_GUID = 028080a3-8958-4a62-a1a8-0fa1da162007
|
||||||
|
MODULE_TYPE = DXE_SMM_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
PI_SPECIFICATION_VERSION = 0x0001000A
|
||||||
|
LIBRARY_CLASS = BaseCryptLib|DXE_SMM_DRIVER SMM_CORE MM_STANDALONE
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
Hash/CryptMd4Null.c
|
||||||
|
Hash/CryptMd5.c
|
||||||
|
Hash/CryptSha1.c
|
||||||
|
Hash/CryptSha256.c
|
||||||
|
Hash/CryptSha512Null.c
|
||||||
|
Hmac/CryptHmacMd5Null.c
|
||||||
|
Hmac/CryptHmacSha1Null.c
|
||||||
|
Hmac/CryptHmacSha256.c
|
||||||
|
Cipher/CryptAes.c
|
||||||
|
Cipher/CryptTdesNull.c
|
||||||
|
Cipher/CryptArc4Null.c
|
||||||
|
Pk/CryptRsaBasic.c
|
||||||
|
Pk/CryptRsaExtNull.c
|
||||||
|
Pk/CryptPkcs5Pbkdf2.c
|
||||||
|
Pk/CryptPkcs7SignNull.c
|
||||||
|
Pk/CryptPkcs7VerifyCommon.c
|
||||||
|
Pk/CryptPkcs7VerifyBase.c
|
||||||
|
Pk/CryptDhNull.c
|
||||||
|
Pk/CryptX509.c
|
||||||
|
Pk/CryptAuthenticodeNull.c
|
||||||
|
Pk/CryptTsNull.c
|
||||||
|
Pem/CryptPem.c
|
||||||
|
|
||||||
|
SysCall/CrtWrapper.c
|
||||||
|
SysCall/ConstantTimeClock.c
|
||||||
|
SysCall/BaseMemAllocation.c
|
||||||
|
|
||||||
|
[Sources.Ia32]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
Rand/CryptRandTsc.c
|
||||||
|
|
||||||
|
[Sources.ARM]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
Rand/CryptRand.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
CryptoPkg/CryptoPkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
IoLib
|
||||||
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
OpensslLib
|
||||||
|
IntrinsicLib
|
||||||
|
PrintLib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove these [BuildOptions] after this library is cleaned up
|
||||||
|
#
|
||||||
|
[BuildOptions]
|
||||||
|
#
|
||||||
|
# suppress the following warnings so we do not break the build with warnings-as-errors:
|
||||||
|
# C4090: 'function' : different 'const' qualifiers
|
||||||
|
#
|
||||||
|
MSFT:*_*_*_CC_FLAGS = /wd4090
|
||||||
|
|
||||||
|
XCODE:*_*_*_CC_FLAGS = -mmmx -msse
|
@ -0,0 +1,30 @@
|
|||||||
|
// /** @file
|
||||||
|
// Cryptographic Library Instance for SMM driver.
|
||||||
|
//
|
||||||
|
// Caution: This module requires additional review when modified.
|
||||||
|
// This library will have external input - signature.
|
||||||
|
// This external input must be validated carefully to avoid security issues such as
|
||||||
|
// buffer overflow or integer overflow.
|
||||||
|
//
|
||||||
|
// Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/
|
||||||
|
// TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions,
|
||||||
|
// Diffie-Hellman functions, and authenticode signature verification functions are
|
||||||
|
// not supported in this instance.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// **/
|
||||||
|
|
||||||
|
|
||||||
|
#string STR_MODULE_ABSTRACT #language en-US "Cryptographic Library Instance for SMM driver"
|
||||||
|
|
||||||
|
#string STR_MODULE_DESCRIPTION #language en-US "Caution: This module requires additional review when modified. This library will have external input - signature. This external input must be validated carefully to avoid security issues such as buffer overflow or integer overflow. Note: MD4 Digest functions, HMAC-MD5 functions, HMAC-SHA1 functions, AES/ TDES/ARC4 functions, RSA external functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and authenticode signature verification functions are not supported in this instance."
|
||||||
|
|
@ -0,0 +1,118 @@
|
|||||||
|
/** @file
|
||||||
|
Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL
|
||||||
|
during PEI & DXE phases.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/** @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.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- 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;
|
||||||
|
}
|
@ -0,0 +1,474 @@
|
|||||||
|
/** @file
|
||||||
|
C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based
|
||||||
|
Cryptographic Library.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
||||||
|
|
||||||
|
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 --
|
||||||
|
//
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// <digit> ::= [0-9]
|
||||||
|
//
|
||||||
|
return (('0' <= (c)) && ((c) <= '9'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine if an integer represents character that is a hex digit */
|
||||||
|
int isxdigit (int c)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// <hexdigit> ::= [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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// <space> ::= [ ]
|
||||||
|
//
|
||||||
|
return ((c) == ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine if a particular character is an alphanumeric character */
|
||||||
|
int isalnum (int c)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// <alnum> ::= [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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// <uppercase letter> := [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;
|
||||||
|
}
|
@ -0,0 +1,461 @@
|
|||||||
|
/** @file
|
||||||
|
Light-weight Memory Management Routines for OpenSSL-based Crypto
|
||||||
|
Library at Runtime Phase.
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Guid/EventGroup.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
/** @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.<BR>
|
||||||
|
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 <Uefi.h>
|
||||||
|
#include <CrtLibSupport.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// -- 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;
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
/** @file
|
||||||
|
Root include file of C runtime library to support building the third-party
|
||||||
|
cryptographic library.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __CRT_LIB_SUPPORT_H__
|
||||||
|
#define __CRT_LIB_SUPPORT_H__
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
|
||||||
|
#define OPENSSLDIR ""
|
||||||
|
#define ENGINESDIR ""
|
||||||
|
|
||||||
|
#define MAX_STRING_SIZE 0x1000
|
||||||
|
|
||||||
|
//
|
||||||
|
// OpenSSL relies on explicit configuration for word size in crypto/bn,
|
||||||
|
// but we want it to be automatically inferred from the target. So we
|
||||||
|
// bypass what's in <openssl/opensslconf.h> for OPENSSL_SYS_UEFI, and
|
||||||
|
// define our own here.
|
||||||
|
//
|
||||||
|
#ifdef CONFIG_HEADER_BN_H
|
||||||
|
#error CONFIG_HEADER_BN_H already defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_HEADER_BN_H
|
||||||
|
|
||||||
|
#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64)
|
||||||
|
//
|
||||||
|
// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs
|
||||||
|
// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is
|
||||||
|
// 64-bit. Since using 'long long' works fine on GCC too, just do that.
|
||||||
|
//
|
||||||
|
#define SIXTY_FOUR_BIT
|
||||||
|
#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)
|
||||||
|
#define THIRTY_TWO_BIT
|
||||||
|
#else
|
||||||
|
#error Unknown target architecture
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
|
||||||
|
//
|
||||||
|
#if !defined(__CC_ARM) // if va_list is not already defined
|
||||||
|
#define va_list VA_LIST
|
||||||
|
#define va_arg VA_ARG
|
||||||
|
#define va_start VA_START
|
||||||
|
#define va_end VA_END
|
||||||
|
#else // __CC_ARM
|
||||||
|
#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
|
||||||
|
#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
|
||||||
|
#define va_end(Marker) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions for global constants used by CRT library routines
|
||||||
|
//
|
||||||
|
#define EINVAL 22 /* Invalid argument */
|
||||||
|
#define INT_MAX 0x7FFFFFFF /* Maximum (signed) int value */
|
||||||
|
#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
|
||||||
|
#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
|
||||||
|
#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
|
||||||
|
#define CHAR_BIT 8 /* Number of bits in a char */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic types mapping
|
||||||
|
//
|
||||||
|
typedef UINTN size_t;
|
||||||
|
typedef INTN ssize_t;
|
||||||
|
typedef INT32 time_t;
|
||||||
|
typedef UINT8 __uint8_t;
|
||||||
|
typedef UINT8 sa_family_t;
|
||||||
|
typedef UINT32 uid_t;
|
||||||
|
typedef UINT32 gid_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// File operations are not required for EFI building,
|
||||||
|
// so FILE is mapped to VOID * to pass build
|
||||||
|
//
|
||||||
|
typedef VOID *FILE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Structures Definitions
|
||||||
|
//
|
||||||
|
struct tm {
|
||||||
|
int tm_sec; /* seconds after the minute [0-60] */
|
||||||
|
int tm_min; /* minutes after the hour [0-59] */
|
||||||
|
int tm_hour; /* hours since midnight [0-23] */
|
||||||
|
int tm_mday; /* day of the month [1-31] */
|
||||||
|
int tm_mon; /* months since January [0-11] */
|
||||||
|
int tm_year; /* years since 1900 */
|
||||||
|
int tm_wday; /* days since Sunday [0-6] */
|
||||||
|
int tm_yday; /* days since January 1 [0-365] */
|
||||||
|
int tm_isdst; /* Daylight Savings Time flag */
|
||||||
|
long tm_gmtoff; /* offset from CUT in seconds */
|
||||||
|
char *tm_zone; /* timezone abbreviation */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeval {
|
||||||
|
long tv_sec; /* time value, in seconds */
|
||||||
|
long tv_usec; /* time value, in microseconds */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr {
|
||||||
|
__uint8_t sa_len; /* total length */
|
||||||
|
sa_family_t sa_family; /* address family */
|
||||||
|
char sa_data[14]; /* actually longer; address value */
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global variables
|
||||||
|
//
|
||||||
|
extern int errno;
|
||||||
|
extern FILE *stderr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function prototypes of CRT Library routines
|
||||||
|
//
|
||||||
|
void *malloc (size_t);
|
||||||
|
void *realloc (void *, size_t);
|
||||||
|
void free (void *);
|
||||||
|
void *memset (void *, int, size_t);
|
||||||
|
int memcmp (const void *, const void *, size_t);
|
||||||
|
int isdigit (int);
|
||||||
|
int isspace (int);
|
||||||
|
int isxdigit (int);
|
||||||
|
int isalnum (int);
|
||||||
|
int isupper (int);
|
||||||
|
int tolower (int);
|
||||||
|
int strcmp (const char *, const char *);
|
||||||
|
int strncasecmp (const char *, const char *, size_t);
|
||||||
|
char *strrchr (const char *, int);
|
||||||
|
unsigned long strtoul (const char *, char **, int);
|
||||||
|
long strtol (const char *, char **, int);
|
||||||
|
char *strerror (int);
|
||||||
|
size_t strspn (const char *, const char *);
|
||||||
|
size_t strcspn (const char *, const char *);
|
||||||
|
int printf (const char *, ...);
|
||||||
|
int sscanf (const char *, const char *, ...);
|
||||||
|
FILE *fopen (const char *, const char *);
|
||||||
|
size_t fread (void *, size_t, size_t, FILE *);
|
||||||
|
size_t fwrite (const void *, size_t, size_t, FILE *);
|
||||||
|
int fclose (FILE *);
|
||||||
|
int fprintf (FILE *, const char *, ...);
|
||||||
|
time_t time (time_t *);
|
||||||
|
struct tm *gmtime (const time_t *);
|
||||||
|
uid_t getuid (void);
|
||||||
|
uid_t geteuid (void);
|
||||||
|
gid_t getgid (void);
|
||||||
|
gid_t getegid (void);
|
||||||
|
void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
|
||||||
|
char *getenv (const char *);
|
||||||
|
char *secure_getenv (const char *);
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ >= 2)
|
||||||
|
void abort (void) __attribute__((__noreturn__));
|
||||||
|
#else
|
||||||
|
void abort (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
|
||||||
|
//
|
||||||
|
#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count))
|
||||||
|
#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
|
||||||
|
#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch)
|
||||||
|
#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count)))
|
||||||
|
#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count))
|
||||||
|
#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
|
||||||
|
#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,MAX_STRING_SIZE,strSource)
|
||||||
|
#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,MAX_STRING_SIZE,strSource,(UINTN)count)
|
||||||
|
#define strcat(strDest,strSource) AsciiStrCatS(strDest,MAX_STRING_SIZE,strSource)
|
||||||
|
#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
|
||||||
|
#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
|
||||||
|
#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
|
||||||
|
#define sprintf(buf,...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
|
||||||
|
#define localtime(timer) NULL
|
||||||
|
#define assert(expression)
|
||||||
|
#define offsetof(type,member) OFFSET_OF(type,member)
|
||||||
|
#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
|
||||||
|
#define gettimeofday(tvp,tz) do { (tvp)->tv_sec = time(NULL); (tvp)->tv_usec = 0; } while (0)
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,15 @@
|
|||||||
|
/** @file
|
||||||
|
Include file to support building the third-party cryptographic library.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
@ -0,0 +1,15 @@
|
|||||||
|
/** @file
|
||||||
|
Include file to support building the third-party cryptographic library.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
@ -0,0 +1,15 @@
|
|||||||
|
/** @file
|
||||||
|
Include file to support building the third-party cryptographic library.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
@ -0,0 +1,15 @@
|
|||||||
|
/** @file
|
||||||
|
Include file to support building the third-party cryptographic library.
|
||||||
|
|
||||||
|
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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 <CrtLibSupport.h>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue