EXTERN_C static NTSTATUS ScvnpGetSha1(_Out_ UCHAR(&Sha1Hash)[20], _In_ void *Data, _In_ ULONG DataSize) { PAGED_CODE(); BCRYPT_HASH_HANDLE hashHandle = nullptr; auto status = BCryptCreateHash(g_ScvnpSha1AlgorithmHandle, &hashHandle, nullptr, 0, nullptr, 0, 0); if (!NT_SUCCESS(status)) { LOG_ERROR_SAFE("BCryptCreateHash failed (%08x)", status); return status; } status = BCryptHashData(hashHandle, static_cast<UCHAR *>(Data), DataSize, 0); if (!NT_SUCCESS(status)) { LOG_ERROR_SAFE("BCryptHashData failed (%08x)", status); goto End; } static_assert(sizeof(Sha1Hash) == 20, "Size check"); status = BCryptFinishHash(hashHandle, Sha1Hash, sizeof(Sha1Hash), 0); if (!NT_SUCCESS(status)) { LOG_ERROR_SAFE("BCryptFinishHash failed (%08x)", status); goto End; } End: if (hashHandle) { BCryptDestroyHash(hashHandle); } return status; }
NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG secretlen, UCHAR *input, ULONG inputlen, UCHAR *output, ULONG outputlen ) { NTSTATUS status; BCRYPT_HASH_HANDLE handle; TRACE( "%p, %p, %u, %p, %u, %p, %u\n", algorithm, secret, secretlen, input, inputlen, output, outputlen ); status = BCryptCreateHash( algorithm, &handle, NULL, 0, secret, secretlen, 0); if (status != STATUS_SUCCESS) { return status; } status = BCryptHashData( handle, input, inputlen, 0 ); if (status != STATUS_SUCCESS) { BCryptDestroyHash( handle ); return status; } status = BCryptFinishHash( handle, output, outputlen, 0 ); if (status != STATUS_SUCCESS) { BCryptDestroyHash( handle ); return status; } return BCryptDestroyHash( handle ); }
int _hashData(const BYTE* data, CC_LONG length) { NTSTATUS status = BCryptHashData(_hHash, const_cast<BYTE*>(data), length, 0); if (SUCCEEDED_NTSTATUS(status)) { return 1; } LOG_NTSTATUS_MSG(status, "BCryptHashData failed\n"); return -1; }
//*** _cpri__UpdateHash() // Add data to a hash or HMAC stack. // void _cpri__UpdateHash( CPRI_HASH_STATE *hashState, // IN: the hash context information UINT32 dataSize, // IN: the size of data to be added to the digest BYTE *data // IN: data to be hashed ) { OSSL_HASH_STATE *state = (OSSL_HASH_STATE *)&hashState->state; BCryptHashData(state->hHash, data, dataSize, 0); }
int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, const unsigned char *data, unsigned long datalen) { int ret; ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
static BOOL sha_check(const WCHAR *file_name) { const unsigned char *file_map; HANDLE file, map; DWORD size, i; BCRYPT_HASH_HANDLE hash = NULL; BCRYPT_ALG_HANDLE alg = NULL; UCHAR sha[32]; char buf[1024]; BOOL ret = FALSE; file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if(file == INVALID_HANDLE_VALUE) { WARN("Could not open file: %u\n", GetLastError()); return FALSE; } size = GetFileSize(file, NULL); map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL); CloseHandle(file); if(!map) return FALSE; file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); CloseHandle(map); if(!file_map) return FALSE; if(BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0)) goto end; if(BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)) goto end; if(BCryptHashData(hash, (UCHAR *)file_map, size, 0)) goto end; if(BCryptFinishHash(hash, sha, sizeof(sha), 0)) goto end; for(i=0; i < sizeof(sha); i++) sprintf(buf + i * 2, "%02x", sha[i]); ret = !strcmp(buf, addon->sha); if(!ret) WARN("Got %s, expected %s\n", buf, addon->sha); end: UnmapViewOfFile(file_map); if(hash) BCryptDestroyHash(hash); if(alg) BCryptCloseAlgorithmProvider(alg, 0); return ret; }
int sha256_hash(uint8_t *hash, uint8_t *data, size_t len) { int res = 0; NTSTATUS status; BCRYPT_ALG_HANDLE sha = NULL; BCRYPT_HASH_HANDLE ctx = NULL; status = BCryptOpenAlgorithmProvider( &sha, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_HASH_REUSABLE_FLAG); status = BCryptCreateHash( sha, &ctx, NULL, 0, NULL, 0, 0); status = BCryptHashData( ctx, (PBYTE)data, len, 0); status = BCryptFinishHash( ctx, hash, 32, 0); cleanup: if (NULL != ctx) { BCryptDestroyHash(ctx); } if( NULL != sha ) { BCryptCloseAlgorithmProvider( sha, 0); } return res; }
HashResult BCryptHashImpl::HashData(const BCryptHashContext& context, PBYTE data, ULONG dataLength) { NTSTATUS status = BCryptHashData(context.m_hashHandle, data, dataLength, 0); if (!NT_SUCCESS(status)) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error computing hash."); return HashResult(); } status = BCryptFinishHash(context.m_hashHandle, m_hashBuffer, m_hashBufferLength, 0); if (!NT_SUCCESS(status)) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error obtaining computed hash"); return HashResult(); } return HashResult(ByteBuffer(m_hashBuffer, m_hashBufferLength)); }
bool BCryptHashImpl::HashStream(Aws::IStream& stream) { BCryptHashContext context(m_algorithmHandle, m_hashObject, m_hashObjectLength); if (!context.IsValid()) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error creating hash handle."); return false; } char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; NTSTATUS status = 0; stream.seekg(0, stream.beg); while(stream.good()) { stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); std::streamsize bytesRead = stream.gcount(); if(bytesRead > 0) { status = BCryptHashData(context.m_hashHandle, (PBYTE)streamBuffer, (ULONG) bytesRead, 0); if (!NT_SUCCESS(status)) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error computing hash."); return false; } } } if(!stream.eof()) { return false; } status = BCryptFinishHash(context.m_hashHandle, m_hashBuffer, m_hashBufferLength, 0); if (!NT_SUCCESS(status)) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error obtaining computed hash"); return false; } return true; }
UINT SfDecryptPayload( LPWSTR lpParameter ) { BOOL cond = FALSE, bSuccess = FALSE; PBYTE cng_object, hashdata, decrypted, enc_data, extracted; ULONG obj_sz, rlen, hdatasz, enc_data_size; BCRYPT_ALG_HANDLE h_alg = NULL; BCRYPT_HASH_HANDLE h_hash = NULL; BCRYPT_KEY_HANDLE h_rc4key = NULL; NTSTATUS status; HANDLE pheap = NULL; PIMAGE_FILE_HEADER fheader; PVOID pdll = NULL; WCHAR InputFile[MAX_PATH + 1], OutputFile[MAX_PATH + 1]; rlen = 0; RtlSecureZeroMemory(InputFile, sizeof(InputFile)); GetCommandLineParam(lpParameter, 1, InputFile, MAX_PATH, &rlen); if (rlen == 0) { SfcuiPrintText(g_ConOut, T_SFDECRYPTUSAGE, g_ConsoleOutput, FALSE); return (UINT)-1; } do { rlen = 0; GetCommandLineParam(lpParameter, 2, OutputFile, MAX_PATH, &rlen); if (rlen == 0) _strcpy(OutputFile, TEXT("out.bin")); pdll = SfuCreateFileMappingNoExec(InputFile); if (pdll == NULL) break; enc_data_size = 0; enc_data = SfuQueryResourceData(2, pdll, &enc_data_size); if (enc_data == NULL) break; fheader = &(RtlImageNtHeader(pdll)->FileHeader); status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_MD5_ALGORITHM, NULL, 0); if (!NT_SUCCESS(status)) break; obj_sz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0); if (!NT_SUCCESS(status)) break; hdatasz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_HASH_LENGTH, (PUCHAR)&hdatasz, sizeof(hdatasz), &rlen, 0); if (!NT_SUCCESS(status)) break; pheap = HeapCreate(0, 0, 0); if (pheap == NULL) break; cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz); if (cng_object == NULL) break; hashdata = HeapAlloc(pheap, HEAP_ZERO_MEMORY, hdatasz); if (hashdata == NULL) break; status = BCryptCreateHash(h_alg, &h_hash, cng_object, obj_sz, NULL, 0, 0); if (!NT_SUCCESS(status)) break; status = BCryptHashData(h_hash, (PUCHAR)fheader, sizeof(IMAGE_FILE_HEADER), 0); if (!NT_SUCCESS(status)) break; status = BCryptFinishHash(h_hash, hashdata, hdatasz, 0); if (!NT_SUCCESS(status)) break; BCryptDestroyHash(h_hash); BCryptCloseAlgorithmProvider(h_alg, 0); HeapFree(pheap, 0, cng_object); h_alg = NULL; h_hash = NULL; status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_RC4_ALGORITHM, NULL, 0); if (!NT_SUCCESS(status)) break; obj_sz = 0; rlen = 0; status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0); if (!NT_SUCCESS(status)) break; cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz); if (cng_object == NULL) break; status = BCryptGenerateSymmetricKey(h_alg, &h_rc4key, cng_object, obj_sz, hashdata, hdatasz, 0); if (!NT_SUCCESS(status)) break; decrypted = HeapAlloc(pheap, HEAP_ZERO_MEMORY, enc_data_size); if (decrypted == NULL) break; rlen = 0; status = BCryptEncrypt(h_rc4key, enc_data, enc_data_size, NULL, NULL, 0, decrypted, enc_data_size, &rlen, 0); if (!NT_SUCCESS(status)) break; bSuccess = FALSE; enc_data_size = rlen; rlen = 0; extracted = SfcabExtractMemory(decrypted, enc_data_size, &rlen); if (extracted) { if (SfuWriteBufferToFile(OutputFile, extracted, rlen, FALSE, FALSE) == rlen) { bSuccess = TRUE; } LocalFree(extracted); } else { //failed to extract, drop cab as is if (SfuWriteBufferToFile(OutputFile, decrypted, enc_data_size, FALSE, FALSE) == enc_data_size) { bSuccess = TRUE; } } if (bSuccess) { SfcuiPrintText(g_ConOut, T_SFDECRYPTED, g_ConsoleOutput, FALSE); SfcuiPrintText(g_ConOut, OutputFile, g_ConsoleOutput, FALSE); } } while (cond); if (bSuccess == FALSE) { SfcuiPrintText(g_ConOut, T_SFDECRYPTFAIL, g_ConsoleOutput, FALSE); } if (h_rc4key != NULL) BCryptDestroyKey(h_rc4key); if (h_hash != NULL) BCryptDestroyHash(h_hash); if (h_alg != NULL) BCryptCloseAlgorithmProvider(h_alg, 0); if (pheap != NULL) HeapDestroy(pheap); if (pdll != 0) NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)pdll); return 0; }
static void __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, size_t data_len) { BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0); }
static void test_sha512(void) { static const char expected[] = "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e" "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], sha512[64]; ULONG size, len; char str[129]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 64); test_alg_name(alg, "SHA512"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 64); test_alg_name(hash, "SHA512"); memset(sha512, 0, sizeof(sha512)); ret = BCryptFinishHash(hash, sha512, sizeof(sha512), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha512, sizeof(sha512), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
static void test_sha384(void) { static const char expected[] = "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], sha384[48]; ULONG size, len; char str[97]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 48); test_alg_name(alg, "SHA384"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 48); test_alg_name(hash, "SHA384"); memset(sha384, 0, sizeof(sha384)); ret = BCryptFinishHash(hash, sha384, sizeof(sha384), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha384, sizeof(sha384), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
static void test_sha256(void) { static const char expected[] = "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], sha256[32]; ULONG size, len; char str[65]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 32); test_alg_name(alg, "SHA256"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 32); test_alg_name(hash, "SHA256"); memset(sha256, 0, sizeof(sha256)); ret = BCryptFinishHash(hash, sha256, sizeof(sha256), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha256, sizeof(sha256), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
static void test_sha1(void) { static const char expected[] = "961fa64958818f767707072755d7018dcd278e94"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], sha1[20]; ULONG size, len; char str[41]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 20); test_alg_name(alg, "SHA1"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 20); test_alg_name(hash, "SHA1"); memset(sha1, 0, sizeof(sha1)); ret = BCryptFinishHash(hash, sha1, sizeof(sha1), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha1, sizeof(sha1), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
static void test_md5(void) { static const char expected[] = "e2a3e68d23ce348b8f68b3079de3d4c9"; static const char expected_hmac[] = "7bda029b93fa8d817fcc9e13d6bdf092"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], buf_hmac[1024], md5[16], md5_hmac[16]; ULONG size, len; char str[65]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 16); test_alg_name(alg, "MD5"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 16); test_alg_name(hash, "MD5"); memset(md5, 0, sizeof(md5)); ret = BCryptFinishHash(hash, md5, sizeof(md5), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( md5, sizeof(md5), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); hash = NULL; len = sizeof(buf_hmac); ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 16); test_alg_name(hash, "MD5"); memset(md5_hmac, 0, sizeof(md5_hmac)); ret = BCryptFinishHash(hash, md5_hmac, sizeof(md5_hmac), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( md5_hmac, sizeof(md5_hmac), str ); ok(!strcmp(str, expected_hmac), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
static void test_sha512(void) { static const char expected[] = "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e" "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca"; static const char expected_hmac[] = "415fb6b10018ca03b38a1b1399c42ac0be5e8aceddb9a73103f5e543bf2d888f2" "eecf91373941f9315dd730a77937fa92444450fbece86f409d9cb5ec48c6513"; BCRYPT_ALG_HANDLE alg; BCRYPT_HASH_HANDLE hash; UCHAR buf[512], buf_hmac[1024], sha512[64], sha512_hmac[64]; ULONG size, len; char str[129]; NTSTATUS ret; alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); len = size = 0xdeadbeef; ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); ok(len == 0xdeadbeef, "got %u\n", len); ok(size == sizeof(len), "got %u\n", size); len = size = 0xdeadbeef; ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(len != 0xdeadbeef, "len not set\n"); ok(size == sizeof(len), "got %u\n", size); test_hash_length(alg, 64); test_alg_name(alg, "SHA512"); hash = NULL; len = sizeof(buf); ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, NULL, 0, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 64); test_alg_name(hash, "SHA512"); memset(sha512, 0, sizeof(sha512)); ret = BCryptFinishHash(hash, sha512, sizeof(sha512), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha512, sizeof(sha512), str ); ok(!strcmp(str, expected), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); alg = NULL; ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(alg != NULL, "alg not set\n"); hash = NULL; len = sizeof(buf_hmac); ret = BCryptCreateHash(alg, &hash, buf_hmac, len, (UCHAR *)"key", sizeof("key"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ok(hash != NULL, "hash not set\n"); ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); test_hash_length(hash, 64); test_alg_name(hash, "SHA512"); memset(sha512_hmac, 0, sizeof(sha512_hmac)); ret = BCryptFinishHash(hash, sha512_hmac, sizeof(sha512_hmac), 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); format_hash( sha512_hmac, sizeof(sha512_hmac), str ); ok(!strcmp(str, expected_hmac), "got %s\n", str); ret = BCryptDestroyHash(hash); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); ret = BCryptCloseAlgorithmProvider(alg, 0); ok(ret == STATUS_SUCCESS, "got %08x\n", ret); }
// // Generate MD5 hash from the given string // std::wstring FlickrUploader::CalculateMD5Hash(const std::wstring& buffer) { #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) // Convert wstring to string std::string byteString(buffer.begin(), buffer.end()); // Open an algorithm handle BCRYPT_ALG_HANDLE algorithm = nullptr; NTSTATUS status = BCryptOpenAlgorithmProvider(&algorithm, BCRYPT_MD5_ALGORITHM, nullptr, 0); // Calculate the size of the buffer to hold the hash object unsigned long dataSize = 0; unsigned long hashObjectSize = 0; if (NT_SUCCESS(status)) { status = BCryptGetProperty(algorithm, BCRYPT_OBJECT_LENGTH, (unsigned char*)&hashObjectSize, sizeof(unsigned long), &dataSize, 0); } // Allocate the hash object on the heap unsigned char* hashObject = nullptr; if (NT_SUCCESS(status)) { hashObject = (unsigned char*) HeapAlloc(GetProcessHeap (), 0, hashObjectSize); if (nullptr == hashObject) { status = STATUS_UNSUCCESSFUL; } } // Calculate the length of the hash unsigned long hashSize = 0; if (NT_SUCCESS(status)) { status = BCryptGetProperty(algorithm, BCRYPT_HASH_LENGTH, (unsigned char*)&hashSize, sizeof(unsigned long), &dataSize, 0); } // Allocate the hash buffer on the heap unsigned char* hash = nullptr; if (NT_SUCCESS(status)) { hash = (unsigned char*)HeapAlloc (GetProcessHeap(), 0, hashSize); if (nullptr == hash) { status = STATUS_UNSUCCESSFUL; } } // Create a hash BCRYPT_HASH_HANDLE cryptHash = nullptr; if (NT_SUCCESS(status)) { status = BCryptCreateHash(algorithm, &cryptHash, hashObject, hashObjectSize, nullptr, 0, 0); } // Hash data if (NT_SUCCESS(status)) { status = BCryptHashData(cryptHash, (unsigned char*)byteString.c_str(), static_cast<unsigned long>(byteString.length()), 0); } // Close the hash and get hash data if (NT_SUCCESS(status)) { status = BCryptFinishHash(cryptHash, hash, hashSize, 0); } std::wstring resultString; // If no issues, then copy the bytes to the output string if (NT_SUCCESS(status)) { std::wostringstream hexString; for (unsigned short i = 0; i < hashSize; i++) { hexString << std::setfill(L'0') << std::setw(2) << std::hex << hash[i]; } resultString = hexString.str(); } // Cleanup if(algorithm) { BCryptCloseAlgorithmProvider(algorithm, 0); } if (cryptHash) { BCryptDestroyHash(cryptHash); } if(hashObject) { HeapFree(GetProcessHeap(), 0, hashObject); } if(hash) { HeapFree(GetProcessHeap(), 0, hash); } return resultString; }
bool _mongoc_crypto_cng_hmac_or_hash (BCRYPT_ALG_HANDLE algorithm, void *key, size_t key_length, void *data, size_t data_length, void *output) { char *hash_object_buffer = 0; ULONG hash_object_length = 0; BCRYPT_HASH_HANDLE hash = 0; ULONG mac_length = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; bool retval = false; ULONG noop = 0; status = BCryptGetProperty (algorithm, BCRYPT_OBJECT_LENGTH, (char *) &hash_object_length, sizeof hash_object_length, &noop, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptGetProperty(): OBJECT_LENGTH %x", status); return false; } status = BCryptGetProperty (algorithm, BCRYPT_HASH_LENGTH, (char *) &mac_length, sizeof mac_length, &noop, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptGetProperty(): HASH_LENGTH %x", status); return false; } hash_object_buffer = bson_malloc (hash_object_length); status = BCryptCreateHash (algorithm, &hash, hash_object_buffer, hash_object_length, key, (ULONG) key_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptCreateHash(): %x", status); goto cleanup; } status = BCryptHashData (hash, data, (ULONG) data_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptHashData(): %x", status); goto cleanup; } status = BCryptFinishHash (hash, output, mac_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptFinishHash(): %x", status); goto cleanup; } retval = true; cleanup: if (hash) { (void) BCryptDestroyHash (hash); } bson_free (hash_object_buffer); return retval; }
static int xmlSecMSCngSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCngSignatureCtxPtr ctx; xmlSecSize inSize; xmlSecSize outSize; NTSTATUS status; DWORD cbData = 0; DWORD cbHashObject = 0; int ret; xmlSecAssert2(xmlSecMSCngSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecMSCngSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pszHashAlgId != NULL, -1); inSize = xmlSecBufferGetSize(&transform->inBuf); outSize = xmlSecBufferGetSize(&transform->outBuf); if(transform->status == xmlSecTransformStatusNone) { xmlSecAssert2(outSize == 0, -1); /* open an algorithm handle */ status = BCryptOpenAlgorithmProvider( &ctx->hHashAlg, ctx->pszHashAlgId, NULL, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptOpenAlgorithmProvider", xmlSecTransformGetName(transform), status); return(-1); } /* calculate the size of the buffer to hold the hash object */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash object on the heap */ ctx->pbHashObject = (PBYTE)xmlMalloc(cbHashObject); if(ctx->pbHashObject == NULL) { xmlSecMallocError(cbHashObject, NULL); return(-1); } /* calculate the length of the hash */ status = BCryptGetProperty( ctx->hHashAlg, BCRYPT_HASH_LENGTH, (PBYTE)&ctx->cbHash, sizeof(DWORD), &cbData, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptGetProperty", xmlSecTransformGetName(transform), status); return(-1); } /* allocate the hash buffer on the heap */ ctx->pbHash = (PBYTE)xmlMalloc(ctx->cbHash); if(ctx->pbHash == NULL) { xmlSecMallocError(ctx->cbHash, NULL); return(-1); } /* create the hash */ status = BCryptCreateHash( ctx->hHashAlg, &ctx->hHash, ctx->pbHashObject, cbHashObject, NULL, 0, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptCreateHash", xmlSecTransformGetName(transform), status); return(-1); } transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking)) { if(inSize > 0) { xmlSecAssert2(outSize == 0, -1); /* hash some data */ status = BCryptHashData( ctx->hHash, (PBYTE)xmlSecBufferGetData(&transform->inBuf), inSize, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptHashData", xmlSecTransformGetName(transform), status); return(-1); } ret = xmlSecBufferRemoveHead(&transform->inBuf, inSize); if(ret < 0) { xmlSecInternalError("xmlSecBufferRemoveHead", xmlSecTransformGetName(transform)); return(-1); } } if(last != 0) { /* close the hash */ status = BCryptFinishHash( ctx->hHash, ctx->pbHash, ctx->cbHash, 0); if(status != STATUS_SUCCESS) { xmlSecMSCngNtError("BCryptFinishHash", xmlSecTransformGetName(transform), status); return(-1); } xmlSecAssert2(ctx->cbHash > 0, -1); if(transform->operation == xmlSecTransformOperationSign) { xmlSecNotImplementedError(NULL); return(-1); } transform->status = xmlSecTransformStatusFinished; } } if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) { xmlSecAssert2(xmlSecBufferGetSize(&transform->inBuf) == 0, -1); } else { xmlSecInvalidTransfromStatusError(transform); return(-1); } return(0); }
NTSTATUS KphHashFile( __in PUNICODE_STRING FileName, __out PVOID *Hash, __out PULONG HashSize ) { NTSTATUS status; BCRYPT_ALG_HANDLE hashAlgHandle = NULL; ULONG querySize; ULONG hashObjectSize; ULONG hashSize; PVOID hashObject = NULL; PVOID hash = NULL; BCRYPT_HASH_HANDLE hashHandle = NULL; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK iosb; HANDLE fileHandle = NULL; FILE_STANDARD_INFORMATION standardInfo; ULONG remainingBytes; ULONG bytesToRead; PVOID buffer = NULL; PAGED_CODE(); // Open the hash algorithm and allocate memory for the hash object. if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, KPH_HASH_ALGORITHM, NULL, 0))) goto CleanupExit; if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0))) { goto CleanupExit; } if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize, sizeof(ULONG), &querySize, 0))) { goto CleanupExit; } if (!(hashObject = ExAllocatePoolWithTag(PagedPool, hashObjectSize, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } if (!(hash = ExAllocatePoolWithTag(PagedPool, hashSize, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize, NULL, 0, 0))) { goto CleanupExit; } // Open the file and compute the hash. InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL); if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0))) { goto CleanupExit; } if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation))) { goto CleanupExit; } if (standardInfo.EndOfFile.QuadPart <= 0) { status = STATUS_UNSUCCESSFUL; goto CleanupExit; } if (standardInfo.EndOfFile.QuadPart > FILE_MAX_SIZE) { status = STATUS_FILE_TOO_LARGE; goto CleanupExit; } if (!(buffer = ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'vhpK'))) { status = STATUS_INSUFFICIENT_RESOURCES; goto CleanupExit; } remainingBytes = (ULONG)standardInfo.EndOfFile.QuadPart; while (remainingBytes != 0) { bytesToRead = FILE_BUFFER_SIZE; if (bytesToRead > remainingBytes) bytesToRead = remainingBytes; if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, bytesToRead, NULL, NULL))) { goto CleanupExit; } if ((ULONG)iosb.Information != bytesToRead) { status = STATUS_INTERNAL_ERROR; goto CleanupExit; } if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, bytesToRead, 0))) goto CleanupExit; remainingBytes -= bytesToRead; } if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0))) goto CleanupExit; if (NT_SUCCESS(status)) { *Hash = hash; *HashSize = hashSize; hash = NULL; // Don't free this in the cleanup section } CleanupExit: if (buffer) ExFreePoolWithTag(buffer, 'vhpK'); if (fileHandle) ZwClose(fileHandle); if (hashHandle) BCryptDestroyHash(hashHandle); if (hash) ExFreePoolWithTag(hash, 'vhpK'); if (hashObject) ExFreePoolWithTag(hashObject, 'vhpK'); if (hashAlgHandle) BCryptCloseAlgorithmProvider(hashAlgHandle, 0); return status; }