EFI_STATUS simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **entries, int *count) { EFI_FILE *file; EFI_STATUS status; status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ); if (status != EFI_SUCCESS) { Print(L"failed to open file %s: %d\n", name, status); return status; } return simple_dir_read_all_by_handle(image, file, name, entries, count); }
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_STATUS efi_status; EFI_FILE *file; UINTN DataSize; void *buffer; sha256_context ctx; UINT8 hash[SHA256_DIGEST_SIZE]; int i; InitializeLib(image, systab); efi_status = simple_file_open(image, loader, &file, EFI_FILE_MODE_READ); if (efi_status != EFI_SUCCESS) { Print(L"Failed to open %s\n", loader); return efi_status; } efi_status = simple_file_read_all(file, &DataSize, &buffer); if (efi_status != EFI_SUCCESS) { Print(L"Failed to read %s\n", loader); goto out_close_file; } sha256_starts(&ctx); sha256_update(&ctx, buffer, DataSize); sha256_finish(&ctx, hash); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { Print(L"%02x", hash[i]); } Print(L"\n"); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { if (hash[i] != check[i]) { Print(L"Not matched!\n"); } } FreePool(buffer); out_close_file: simple_file_close(file); return efi_status; }
void parse_db(UINT8 *data, UINTN len, EFI_HANDLE image, CHAR16 *name, int save_file) { EFI_SIGNATURE_LIST *CertList = (EFI_SIGNATURE_LIST *)data; EFI_SIGNATURE_DATA *Cert; UINTN count = 0, DataSize = len; EFI_FILE *file; CHAR16 *buf = AllocatePool(StrSize(name) + 4 + 2 + 4 + 8 +100); CHAR16 *ext; EFI_STATUS status; int size; certlist_for_each_certentry(CertList, data, size, DataSize) { int Index = 0; count++; if (CompareGuid(&CertList->SignatureType, &X509_GUID) == 0) { ext = L"X509"; } else if (CompareGuid(&CertList->SignatureType, &RSA2048_GUID) == 0) { ext = L"RSA2048"; } else if (CompareGuid(&CertList->SignatureType, &PKCS7_GUID) == 0) { ext = L"PKCS7"; } else if (CompareGuid(&CertList->SignatureType, &EFI_CERT_SHA256_GUID) == 0) { ext = L"SHA256"; } else { ext = L"Unknown"; } Print(L"%s: List %d, type %s\n", name, count, ext); certentry_for_each_cert(Cert, CertList) { Print(L" Signature %d, size %d, owner %g\n", Index++, CertList->SignatureSize, &Cert->SignatureOwner); if (StrCmp(ext, L"X509") == 0) { CHAR16 buf1[4096]; x509_to_str(Cert->SignatureData, CertList->SignatureSize, X509_OBJ_SUBJECT, buf1, sizeof(buf1)); Print(L" Subject: %s\n", buf1); x509_to_str(Cert->SignatureData, CertList->SignatureSize, X509_OBJ_ISSUER, buf1, sizeof(buf1)); Print(L" Issuer: %s\n", buf1); } else if (StrCmp(ext, L"SHA256") == 0) { CHAR16 buf1[256]; StrCpy(buf1, L"Hash: "); sha256_StrCat_hash(buf1, Cert->SignatureData); Print(L" %s\n", buf1); } if (save_file) { SPrint(buf, 0, L"%s-%d-%d-%s-%g", name, count, Index, ext, &Cert->SignatureOwner); Print(L"Writing to file %s\n", buf); status = simple_file_open(image, buf, &file, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); if (status != EFI_SUCCESS) { Print(L"Failed to open file %s: %d\n", buf, status); continue; } status = simple_file_write_all(file, CertList->SignatureSize-sizeof(EFI_GUID), Cert->SignatureData); simple_file_close(file); if (status != EFI_SUCCESS) { Print(L"Failed to write signature to file %s: %d\n", buf, status); continue; } } }
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_STATUS status; int argc, i, esl_mode = 0, hash_mode = 0; CHAR16 **ARGV, *var, *name, *progname, *owner_guid; EFI_FILE *file; void *buf; UINTN size, options = 0; EFI_GUID *owner; CHAR16 *variables[] = { L"PK", L"KEK", L"db", L"dbx", L"MokList" }; EFI_GUID *owners[] = { &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB, &MOK_OWNER }; InitializeLib(image, systab); status = argsplit(image, &argc, &ARGV); if (status != EFI_SUCCESS) { Print(L"Failed to parse arguments: %d\n", status); return status; } progname = ARGV[0]; while (argc > 1 && ARGV[1][0] == L'-') { if (StrCmp(ARGV[1], L"-a") == 0) { options |= EFI_VARIABLE_APPEND_WRITE; ARGV += 1; argc -= 1; } else if (StrCmp(ARGV[1], L"-g") == 0) { owner_guid = ARGV[2]; ARGV += 2; argc -= 2; } else if (StrCmp(ARGV[1], L"-e") == 0) { esl_mode = 1; ARGV += 1; argc -= 1; } else if (StrCmp(ARGV[1], L"-b") == 0) { esl_mode = 1; hash_mode = 1; ARGV += 1; argc -= 1; } else { /* unrecognised option */ break; } } if (argc != 3 ) { Print(L"Usage: %s: [-g guid] [-a] [-e] [-b] var file\n", progname); return EFI_INVALID_PARAMETER; } var = ARGV[1]; name = ARGV[2]; for(i = 0; i < ARRAY_SIZE(variables); i++) { if (StrCmp(var, variables[i]) == 0) { owner = owners[i]; break; } } if (i == ARRAY_SIZE(variables)) { Print(L"Invalid Variable %s\nVariable must be one of: ", var); for (i = 0; i < ARRAY_SIZE(variables); i++) Print(L"%s ", variables[i]); Print(L"\n"); return EFI_INVALID_PARAMETER; } if (owner == &MOK_OWNER) { if (!esl_mode) { Print(L"MoK variables can only be updated in ESL mode\n"); return EFI_INVALID_PARAMETER; } /* hack: esl goes directly into MoK variables, so we now * pretend we have a direct .auth update */ esl_mode = 0; } else { /* non MoK variables have runtime access and time based * authentication, MoK ones don't */ options |= EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; } status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ); if (status != EFI_SUCCESS) { Print(L"Failed to open file %s\n", name); return status; } status = simple_file_read_all(file, &size, &buf); if (status != EFI_SUCCESS) { Print(L"Failed to read file %s\n", name); return status; } simple_file_close(file); if (hash_mode) { UINT8 hash[SHA256_DIGEST_SIZE]; status = sha256_get_pecoff_digest_mem(buf, size, hash); if (status != EFI_SUCCESS) { Print(L"Failed to get hash of %s\n", name); return status; } status = variable_enroll_hash(var, *owner, hash); } else if (esl_mode) { status = SetSecureVariable(var, buf, size, *owner, options, 0); } else { status = uefi_call_wrapper(RT->SetVariable, 5, var, owner, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | options, size, buf); } if (status != EFI_SUCCESS) { Print(L"Failed to update variable %s: %d\n", var, status); return status; } return EFI_SUCCESS; }