16#include <Guid/FileInfo.h>
17#include <Protocol/SimpleFileSystem.h>
19#include <Library/BaseLib.h>
20#include <Library/BaseMemoryLib.h>
21#include <Library/DebugLib.h>
22#include <Library/DevicePathLib.h>
23#include <Library/MemoryAllocationLib.h>
27#include <Library/UefiBootServicesTableLib.h>
35typedef PACKED
struct {
37 EFI_DEVICE_PATH_PROTOCOL
End;
40typedef PACKED
struct {
41 VENDOR_DEFINED_DEVICE_PATH
Vendor;
43 EFI_DEVICE_PATH_PROTOCOL
End;
52#define INTERNAL_STORAGE_GUID \
53 { 0x33B5C65A, 0x5B82, 0x403D, {0x87, 0xA5, 0xD4, 0x67, 0x62, 0x50, 0xEC, 0x59} }
55#define INTERNAL_STORAGE_FILE_GUID \
56 { 0x1237EC17, 0xD3CE, 0x401D, {0xA8, 0x41, 0xB1, 0xD8, 0x18, 0xF8, 0xAF, 0x1A} }
63 .Type = HARDWARE_DEVICE_PATH,
64 .SubType = HW_VENDOR_DP,
65 .Length = {
sizeof (VENDOR_DEFINED_DEVICE_PATH), 0 }
70 .Type = END_DEVICE_PATH_TYPE,
71 .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
72 .Length = { END_DEVICE_PATH_LENGTH, 0 }
81 .Type = HARDWARE_DEVICE_PATH,
82 .SubType = HW_VENDOR_DP,
83 .Length = {
sizeof (VENDOR_DEFINED_DEVICE_PATH), 0 }
89 .Type = HARDWARE_DEVICE_PATH,
90 .SubType = HW_VENDOR_DP,
91 .Length = {
sizeof (VENDOR_DEFINED_DEVICE_PATH), 0 }
96 .Type = END_DEVICE_PATH_TYPE,
97 .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
98 .Length = { END_DEVICE_PATH_LENGTH, 0 }
126 IN VOID *Vault OPTIONAL,
130 IN UINT32 SignatureSize OPTIONAL
133 if ((
Signature != NULL) && (Vault == NULL)) {
134 DEBUG ((DEBUG_ERROR,
"OCST: Missing vault with signature\n"));
135 return EFI_SECURITY_VIOLATION;
139 DEBUG ((DEBUG_INFO,
"OCST: Missing vault data, ignoring...\n"));
144 ASSERT (StorageKey != NULL);
147 DEBUG ((DEBUG_ERROR,
"OCST: Invalid vault signature\n"));
148 return EFI_SECURITY_VIOLATION;
152 OC_STORAGE_VAULT_CONSTRUCT (&Context->Vault, sizeof (Context->Vault));
154 OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault));
155 DEBUG ((DEBUG_ERROR,
"OCST: Invalid vault data\n"));
156 return EFI_INVALID_PARAMETER;
160 OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault));
163 "OCST: Unsupported vault data version %u vs %u\n",
164 Context->Vault.Version,
167 return EFI_UNSUPPORTED;
170 Context->HasVault = TRUE;
179 IN CONST CHAR16 *Filename
184 CHAR8 *VaultFilePath;
187 if (!Context->HasVault) {
191 FilenameSize = StrLen (Filename) + 1;
193 for (Index = 0; Index < Context->Vault.Files.Count; ++Index) {
194 if (Context->Vault.Files.Keys[Index]->Size != (UINT32)FilenameSize) {
198 VaultFilePath =
OC_BLOB_GET (Context->Vault.Files.Keys[Index]);
200 for (StrIndex = 0; StrIndex < FilenameSize; ++StrIndex) {
201 if (Filename[StrIndex] != VaultFilePath[StrIndex]) {
206 if (StrIndex == FilenameSize) {
207 return &Context->Vault.Files.Values[Index]->Hash[0];
217 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
218 IN EFI_HANDLE StorageHandle OPTIONAL,
219 IN EFI_DEVICE_PATH_PROTOCOL *StoragePath OPTIONAL,
220 IN CONST CHAR16 *StorageRoot,
225 EFI_FILE_PROTOCOL *RootVolume;
229 UINT32 SignatureSize;
232 ASSERT (FileSystem != NULL);
233 ASSERT (StorageRoot != NULL);
235 ZeroMem (Context,
sizeof (*Context));
237 Context->FileSystem = FileSystem;
239 Status = FileSystem->OpenVolume (FileSystem, &RootVolume);
240 if (EFI_ERROR (Status)) {
241 DEBUG ((DEBUG_INFO,
"OCST: FileSystem volume cannot be opened - %r\n", Status));
248 (CHAR16 *)StorageRoot,
253 RootVolume->Close (RootVolume);
255 if (EFI_ERROR (Status)) {
256 DEBUG ((DEBUG_INFO,
"OCST: Directory %s cannot be opened - %r\n", StorageRoot, Status));
270 DEBUG ((DEBUG_ERROR,
"OCS: Missing vault signature\n"));
272 return EFI_SECURITY_VIOLATION;
287 if (EFI_ERROR (Status)) {
288 DEBUG ((DEBUG_INFO,
"OCST: Vault init failure %p (%u) - %r\n", Vault, DataSize, Status));
291 gBS->InstallProtocolInterface (
292 &Context->DummyStorageHandle,
294 EFI_NATIVE_INTERFACE,
297 Context->StorageHandle = StorageHandle;
298 Context->StoragePath = StoragePath;
299 Context->StorageRoot = StorageRoot;
319 if (Context->DummyStorageHandle != NULL) {
320 gBS->UninstallProtocolInterface (
321 Context->DummyStorageHandle,
325 Context->DummyStorageHandle = NULL;
328 if (Context->Storage != NULL) {
329 Context->Storage->Close (Context->Storage);
330 Context->Storage = NULL;
333 if (Context->HasVault) {
334 OC_STORAGE_VAULT_DESTRUCT (&Context->Vault, sizeof (Context->Vault));
335 Context->HasVault = FALSE;
346 EFI_FILE_PROTOCOL *File;
358 if (VaultDigest != NULL) {
362 if (Context->Storage == NULL) {
374 if (!EFI_ERROR (Status)) {
386 OUT UINT32 *FileSize OPTIONAL
390 EFI_FILE_PROTOCOL *File;
405 if (Context->HasVault && (VaultDigest == NULL)) {
406 DEBUG ((DEBUG_ERROR,
"OCST: Aborting %s file access not present in vault\n",
FilePath));
410 if (Context->Storage == NULL) {
425 if (EFI_ERROR (Status)) {
430 if (EFI_ERROR (Status) || (
Size >= MAX_UINT32 - 1)) {
435 FileBuffer = AllocatePool (
Size + 2);
436 if (FileBuffer == NULL) {
443 if (EFI_ERROR (Status)) {
444 FreePool (FileBuffer);
448 if (VaultDigest != 0) {
451 DEBUG ((DEBUG_ERROR,
"OCST: Aborting corrupted %s file access\n",
FilePath));
452 FreePool (FileBuffer);
457 FileBuffer[
Size] = 0;
458 FileBuffer[
Size + 1] = 0;
460 if (FileSize != NULL) {
471 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL,
472 OUT EFI_HANDLE *StorageHandle OPTIONAL,
473 OUT EFI_DEVICE_PATH_PROTOCOL **StoragePath OPTIONAL,
482 && (Context->StorageHandle != NULL)
483 && (Context->StorageRoot != NULL)
484 && (Context->StoragePath != NULL))
489 *StorageHandle = Context->StorageHandle;
494 RootLength = StrLen (Context->StorageRoot);
496 FullPath = AllocatePool (RootLength *
sizeof (CHAR16) +
sizeof (CHAR16) + FileSize);
498 if (FullPath == NULL) {
499 return EFI_OUT_OF_RESOURCES;
502 CopyMem (&FullPath[0], Context->StorageRoot, RootLength * sizeof (CHAR16));
503 FullPath[RootLength] =
'\\';
510 if (*DevicePath == NULL) {
512 return EFI_OUT_OF_RESOURCES;
518 *StoragePath = FileDevicePath (NULL, FullPath);
519 if (*StoragePath == NULL) {
520 FreePool (*DevicePath);
522 return EFI_OUT_OF_RESOURCES;
528 *StorageHandle = Context->DummyStorageHandle;
530 *DevicePath = DuplicateDevicePath (Context->DummyDevicePath);
531 if (*DevicePath == NULL) {
532 return EFI_OUT_OF_RESOURCES;
535 *StoragePath = DuplicateDevicePath (Context->DummyFilePath);
536 if (*StoragePath == NULL) {
537 FreePool (*DevicePath);
538 return EFI_OUT_OF_RESOURCES;
#define ARRAY_SIZE(Array)
DMG_FILEPATH_DEVICE_PATH FilePath
DMG_SIZE_DEVICE_PATH Size
#define SHA256_DIGEST_SIZE
VOID Sha256(UINT8 *Hash, CONST UINT8 *Data, UINTN Len)
BOOLEAN RsaVerifySigDataFromKeyDynalloc(IN CONST OC_RSA_PUBLIC_KEY *Key, IN CONST UINT8 *Signature, IN UINTN SignatureSize, IN CONST UINT8 *Data, IN UINTN DataSize, IN OC_SIG_HASH_TYPE Algorithm)
EFI_DEVICE_PATH_PROTOCOL * AppendFileNameDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FileName)
EFI_STATUS OcGetFileSize(IN EFI_FILE_PROTOCOL *File, OUT UINT32 *Size)
EFI_STATUS OcGetFileData(IN EFI_FILE_PROTOCOL *File, IN UINT32 Position, IN UINT32 Size, OUT UINT8 *Buffer)
EFI_STATUS OcSafeFileOpen(IN CONST EFI_FILE_PROTOCOL *Directory, OUT EFI_FILE_PROTOCOL **NewHandle, IN CONST CHAR16 *FileName, IN CONST UINT64 OpenMode, IN CONST UINT64 Attributes)
#define OC_SCHEMA_MAP_IN(Name, Type, Field, ChildSchema)
#define OC_SCHEMA_DATAF(Name, Type)
BOOLEAN ParseSerialized(OUT VOID *Serialized, IN OC_SCHEMA_INFO *RootSchema, IN VOID *PlistBuffer, IN UINT32 PlistSize, IN OUT UINT32 *ErrorCount OPTIONAL)
#define OC_SCHEMA_INTEGER_IN(Name, Type, Field)
STATIC EFI_STATUS OcStorageInitializeVault(IN OUT OC_STORAGE_CONTEXT *Context, IN VOID *Vault OPTIONAL, IN UINT32 VaultSize, IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL, IN VOID *Signature OPTIONAL, IN UINT32 SignatureSize OPTIONAL)
BOOLEAN OcStorageExistsFileUnicode(IN OC_STORAGE_CONTEXT *Context, IN CONST CHAR16 *FilePath)
VENDOR_DEFINED_DEVICE_PATH VendorFile
STATIC OC_SCHEMA_INFO mVaultSchema
#define INTERNAL_STORAGE_GUID
PACKED struct @101 DUMMY_BOOT_DEVICE_FILE_PATH
EFI_STATUS OcStorageInitFromFs(OUT OC_STORAGE_CONTEXT *Context, IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN EFI_HANDLE StorageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *StoragePath OPTIONAL, IN CONST CHAR16 *StorageRoot, IN OC_RSA_PUBLIC_KEY *StorageKey OPTIONAL)
PACKED struct @100 DUMMY_BOOT_DEVICE_PATH
VOID * OcStorageReadFileUnicode(IN OC_STORAGE_CONTEXT *Context, IN CONST CHAR16 *FilePath, OUT UINT32 *FileSize OPTIONAL)
#define INTERNAL_STORAGE_FILE_GUID
STATIC UINT8 * OcStorageGetDigest(IN OUT OC_STORAGE_CONTEXT *Context, IN CONST CHAR16 *Filename)
STATIC OC_SCHEMA mVaultNodesSchema[]
STATIC DUMMY_BOOT_DEVICE_PATH mDummyBootDevicePath
EFI_DEVICE_PATH_PROTOCOL End
STATIC OC_SCHEMA mVaultFilesSchema
VOID OcStorageFree(IN OUT OC_STORAGE_CONTEXT *Context)
VENDOR_DEFINED_DEVICE_PATH Vendor
STATIC DUMMY_BOOT_DEVICE_FILE_PATH mDummyBootDeviceFilePath
EFI_STATUS OcStorageGetInfo(IN OC_STORAGE_CONTEXT *Context, IN CONST CHAR16 *FilePath, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, OUT EFI_HANDLE *StorageHandle OPTIONAL, OUT EFI_DEVICE_PATH_PROTOCOL **StoragePath OPTIONAL, IN BOOLEAN RealPath)
#define OC_STORAGE_VAULT_PATH
#define OC_STORAGE_VAULT_VERSION
#define OC_STORAGE_VAULT_SIGNATURE_PATH
#define OC_STRUCTORS(Name, Destructor)
#define OC_MAP_STRUCTORS(Name)
#define OC_BLOB_GET(Blob)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_GUID gEfiDevicePathProtocolGuid