static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; DWORD keyObj_len, aes_key_len; PBYTE keyObj; ULONG result; NTSTATUS status; BCRYPT_KEY_LENGTHS_STRUCT key_lengths; ctx->hAlg = NULL; ctx->hKey = NULL; ctx->keyObj = NULL; switch (key_len) { case 16: aes_key_len = 128; break; case 24: aes_key_len = 192; break; case 32: aes_key_len = 256; break; default: return -1; } status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, sizeof(key_lengths), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } if (key_lengths.dwMinLength > aes_key_len || key_lengths.dwMaxLength < aes_key_len) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, sizeof(keyObj_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); if (keyObj == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } status = BCryptGenerateSymmetricKey(hAlg, &hKey, keyObj, keyObj_len, (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } ctx->hAlg = hAlg; ctx->hKey = hKey; ctx->keyObj = keyObj; ctx->keyObj_len = keyObj_len; ctx->encr_pos = AES_BLOCK_SIZE; return 0; }
//** Hash Functions //*** _cpri__HashStartup() // Function that is called to initialize the hash service. In this implementation, // this function does nothing but it is called by the CryptUtilStartup() function // and must be present. BOOL _cpri__HashStartup( void ) { #pragma warning (disable:4127) #pragma warning (disable:6237) if ((ALG_SHA1 == YES) && (BCryptOpenAlgorithmProvider(&g_hAlg[0], BCRYPT_SHA1_ALGORITHM, NULL, 0 )) != 0) { return FALSE; } if ((ALG_SHA256 == YES) && (BCryptOpenAlgorithmProvider(&g_hAlg[1], BCRYPT_SHA256_ALGORITHM, NULL, 0)) != 0) { return FALSE; } if ((ALG_SHA384 == YES) && (BCryptOpenAlgorithmProvider(&g_hAlg[2], BCRYPT_SHA384_ALGORITHM, NULL, 0 )) != 0) { return FALSE; } if ((ALG_SHA512 == YES) && (BCryptOpenAlgorithmProvider(&g_hAlg[3], BCRYPT_SHA512_ALGORITHM, NULL, 0)) != 0) { return FALSE; } #pragma warning (default:4127) #pragma warning (default:6237) return TRUE; }
void _libssh2_wincng_init(void) { int ret; (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, BCRYPT_RNG_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, BCRYPT_MD5_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, BCRYPT_SHA1_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, BCRYPT_MD5_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, BCRYPT_RSA_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, BCRYPT_DSA_ALGORITHM, NULL, 0); ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, BCRYPT_AES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, BCRYPT_RC4_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_NA, sizeof(BCRYPT_CHAIN_MODE_NA), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, BCRYPT_3DES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); } } }
BOOL _cpri__RngStartup( void ) { return (BCryptOpenAlgorithmProvider(&g_hRngAlg, BCRYPT_RNG_ALGORITHM, NULL, 0) == ERROR_SUCCESS); }
MicrosoftCryptoProvider::MicrosoftCryptoProvider() : m_hProvider(0) { #if defined(USE_MS_CRYPTOAPI) // See http://support.microsoft.com/en-us/kb/238187 for CRYPT_NEWKEYSET fallback strategy if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { const DWORD firstErr = GetLastError(); if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET /*user*/) && !CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET)) { // Set original error with original code SetLastError(firstErr); throw OS_RNG_Err("CryptAcquireContext"); } } #elif defined(USE_MS_CNGAPI) NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!(BCRYPT_SUCCESS(ret))) { // Hack... OS_RNG_Err calls GetLastError() SetLastError(NtStatusToErrorCode(ret)); throw OS_RNG_Err("BCryptOpenAlgorithmProvider"); } #endif }
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; }
bool ConnectionState::Initialize(std::shared_ptr<SecurityParameters> security_parameters) { wchar_t* algorithm; switch(security_parameters->bulk_cipher_algorithm) { case BulkCipherAlgorithm::bca_null: break; case BulkCipherAlgorithm::aes: algorithm = BCRYPT_AES_ALGORITHM; break; case BulkCipherAlgorithm::rc4: algorithm = BCRYPT_RC4_ALGORITHM; break; case BulkCipherAlgorithm::_3des: algorithm = BCRYPT_3DES_ALGORITHM; break; default: return Basic::globals->HandleError("Tls::ConnectionState::Initialize unsupported cipher_suite", 0); } Basic::BCRYPT_ALG_HANDLE bulk_cipher_algorithm_handle; NTSTATUS error = BCryptOpenAlgorithmProvider(&bulk_cipher_algorithm_handle, algorithm, 0, 0); if (error != 0) throw FatalError("BCryptOpenAlgorithmProvider", error); ByteString key_blob; key_blob.reserve(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + this->encryption_key.size()); key_blob.resize(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)); key_blob.insert(key_blob.end(), this->encryption_key.begin(), this->encryption_key.end()); BCRYPT_KEY_DATA_BLOB_HEADER* header = (BCRYPT_KEY_DATA_BLOB_HEADER*)key_blob.address(); header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; header->cbKeyData = this->encryption_key.size(); error = BCryptImportKey(bulk_cipher_algorithm_handle, 0, BCRYPT_KEY_DATA_BLOB, &this->key_handle, 0, 0, key_blob.address(), key_blob.size(), 0); if (error != 0) return Basic::globals->HandleError("BCryptImportKey", error); this->security_parameters = security_parameters; return true; }
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; }
void mongoc_crypto_cng_init (void) { NTSTATUS status = STATUS_UNSUCCESSFUL; _sha1_hash_algo = 0; status = BCryptOpenAlgorithmProvider ( &_sha1_hash_algo, BCRYPT_SHA1_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1): %x", status); } _sha1_hmac_algo = 0; status = BCryptOpenAlgorithmProvider (&_sha1_hmac_algo, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA1 HMAC): %x", status); } _sha256_hash_algo = 0; status = BCryptOpenAlgorithmProvider ( &_sha256_hash_algo, BCRYPT_SHA256_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256): %x", status); } _sha256_hmac_algo = 0; status = BCryptOpenAlgorithmProvider (&_sha256_hmac_algo, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(SHA256 HMAC): %x", status); } }
NTSTATUS _init() { DWORD cbHashObject; DWORD cbResult; RETURN_IF_NTSTATUS_FAILED_LOG(BCryptOpenAlgorithmProvider(&_hAlg, _algorithm, NULL, 0)); RETURN_IF_NTSTATUS_FAILED_LOG( BCryptGetProperty(_hAlg, BCRYPT_OBJECT_LENGTH, reinterpret_cast<PBYTE>(&cbHashObject), sizeof(DWORD), &cbResult, 0)); _pHashObject = new BYTE[cbHashObject]; if (_pHashObject == nullptr) { RETURN_IF_NTSTATUS_FAILED_MSG(STATUS_NO_MEMORY, "CC_Digest_State Unable to allocate Hash object"); } RETURN_IF_NTSTATUS_FAILED_LOG(BCryptCreateHash(_hAlg, &_hHash, _pHashObject, cbHashObject, NULL, 0, 0)); return 0; }
BCryptHashImpl::BCryptHashImpl(LPCWSTR algorithmName, bool isHMAC) : m_algorithmHandle(nullptr), m_hashBufferLength(0), m_hashBuffer(nullptr), m_hashObjectLength(0), m_hashObject(nullptr), m_algorithmMutex() { NTSTATUS status = BCryptOpenAlgorithmProvider(&m_algorithmHandle, algorithmName, MS_PRIMITIVE_PROVIDER, isHMAC ? BCRYPT_ALG_HANDLE_HMAC_FLAG : 0); if (!NT_SUCCESS(status)) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Failed initializing BCryptOpenAlgorithmProvider for ", algorithmName); return; } DWORD resultLength = 0; status = BCryptGetProperty(m_algorithmHandle, BCRYPT_HASH_LENGTH, (PBYTE)&m_hashBufferLength, sizeof(m_hashBufferLength), &resultLength, 0); if (!NT_SUCCESS(status) || m_hashBufferLength <= 0) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error computing hash buffer length."); return; } m_hashBuffer = Aws::NewArray<BYTE>(m_hashBufferLength, BCRYPT_LOG_TAG); if (!m_hashBuffer) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error allocating hash buffer."); return; } resultLength = 0; status = BCryptGetProperty(m_algorithmHandle, BCRYPT_OBJECT_LENGTH, (PBYTE)&m_hashObjectLength, sizeof(m_hashObjectLength), &resultLength, 0); if (!NT_SUCCESS(status) || m_hashObjectLength <= 0) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error computing hash object length."); return; } m_hashObject = Aws::NewArray<BYTE>(m_hashObjectLength, BCRYPT_LOG_TAG); if (!m_hashObject) { AWS_LOG_ERROR(BCRYPT_LOG_TAG, "Error allocating hash object."); return; } }
static void read_entropy(uint8_t *entropy, size_t size) { NTSTATUS nts = 0; BCRYPT_ALG_HANDLE hAlgorithm = 0; nts = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(nts)) { nts = BCryptGenRandom(hAlgorithm, (PUCHAR)entropy, (ULONG)size, 0); (void)BCryptCloseAlgorithmProvider(hAlgorithm, 0); } if (!BCRYPT_SUCCESS(nts)) { perror("ptls_minicrypto_random_bytes: could not open BCrypt RNG Algorithm"); abort(); } }
static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { #pragma GCC diagnostic ignored "-Wcast-qual" BCRYPT_ALG_HANDLE hAlg; BCRYPT_HASH_HANDLE hHash; DWORD hash_len; PBYTE hash; ULONG result; NTSTATUS status; ctx->hAlg = NULL; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, sizeof(hash_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); if (hash == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptCreateHash(hAlg, &hHash, NULL, 0, (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, hash); return -1; } ctx->hAlg = hAlg; ctx->hHash = hHash; ctx->hash_len = hash_len; ctx->hash = hash; return 0; }
static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { NTSTATUS status; BCRYPT_ALG_HANDLE hAlg; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptDeriveKeyPBKDF2(hAlg, (PUCHAR)(uintptr_t)pw, (ULONG)pw_len, (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds, (PUCHAR)derived_key, (ULONG)derived_key_len, 0); BCryptCloseAlgorithmProvider(hAlg, 0); return (BCRYPT_SUCCESS(status)) ? 0: -1; }
int xpfurandom_prep(void** data, uint32_t size, void** win_alg_handle, xpfurandom_settings* s) { NTSTATUS st; *data = malloc(size); if (*data == NULL) { fprintf(stderr, "XPFUrandom: Random data buffer allocation failed."); return FAIL; } *win_alg_handle = malloc(sizeof(PVOID)); if (*win_alg_handle == NULL) { fprintf(stderr, "XPFUrandom: RNG Algorithm handle space allocation failed."); return FAIL; } st = BCryptOpenAlgorithmProvider(win_alg_handle, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); switch (st) { case STATUS_SUCCESS:break; case STATUS_NOT_FOUND: { fprintf(stderr, "XPFUrandom: BCryptOpenAlgorithm failed: no RNG provider found(STATUS_NOT_FOUND)(this should never happen)\n"); return FAIL; }break; case STATUS_INVALID_PARAMETER: { fprintf(stderr, "XPFUrandom: BCryptOpenAlgorithm failed: invalid parameter(STATUS_INVALID_PARAMETER)\n"); return FAIL; }break; case STATUS_NO_MEMORY: { fprintf(stderr, "XPFUrandom: BCryptOpenAlgorithm failed: memory allocation failure(STATUS_NO_MEMORY)\n"); return FAIL; }break; // if NOT_FOUND happens and this is run on Win7+, something is SERIOUSLY WRONG; // INVALID_PARAMETER shouldn't happen either, but maybe if wrong pointer is given it could; } if (s->filename != NULL) { s->file_out = fopen(s->filename, "wb"); if (s->file_out == NULL) { fprintf(stderr, "XPFUrandom: fopen failed: %s\n", strerror(errno)); return FAIL; } } return OK; }
int _mongoc_rand_bytes (uint8_t *buf, int num) { static BCRYPT_ALG_HANDLE algorithm = 0; NTSTATUS status = 0; if (!algorithm) { status = BCryptOpenAlgorithmProvider ( &algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status); return 0; } } status = BCryptGenRandom (algorithm, buf, num, 0); if (NT_SUCCESS (status)) { return 1; } MONGOC_ERROR ("BCryptGenRandom(): %d", status); return 0; }
int Everest_init(ENGINE *e) { // Initialize the global variables needed for BCrypt if (!NT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_ECDH_ALGORITHM, NULL, 0))) { fprintf(stderr, "Cannot open algorithm provider\n"); return 0; } if (!NT_SUCCESS(BCryptSetProperty(hAlg, BCRYPT_ECC_CURVE_NAME, (PUCHAR) BCRYPT_ECC_CURVE_25519, sizeof(BCRYPT_ECC_CURVE_25519), 0))) { fprintf(stderr, "Cannot select the right curve\n"); return 0; } // Initialize our new method bcrypt_x25519_meth = EVP_PKEY_meth_new(NID_X25519, 0); EVP_PKEY_meth_set_derive(bcrypt_x25519_meth, NULL, bcrypt_derive); EVP_PKEY_meth_set_ctrl(bcrypt_x25519_meth, bcrypt_ctrl, NULL); EVP_PKEY_meth_set_keygen(bcrypt_x25519_meth, NULL, bcrypt_keygen); return 1; }
// // 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; }
PBYTE HashDigest = NULL; DWORD HashDigestLength = 0; DWORD ResultLength = 0; *DataDigestPointer = NULL; *DataDigestLengthPointer = 0; // // Open a Hash algorithm handle // Status = BCryptOpenAlgorithmProvider( &HashAlgHandle, BCRYPT_SHA1_ALGORITHM, NULL, 0); if( !NT_SUCCESS(Status) ) { ReportError(Status); goto cleanup; } // // Calculate the length of the Hash // Status= BCryptGetProperty( HashAlgHandle,
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); }
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; }
bool aes_decrypt_check(m0_kdbx_header_entry_t *hdr, uint8_t *masterkey, m0_kdbx_payload_t *payload) { bool res = false; BCRYPT_ALG_HANDLE aes = NULL; BCRYPT_KEY_HANDLE ctx = NULL; NTSTATUS status = 0; DWORD len_ciphertext = 0, tmp_len = 0, key_objectlen = 0; PBYTE key_object = NULL; uint8_t plaintext[32] = {0}; uint8_t iv[256] = {0}; uint8_t ivlen = hdr[ENCRYPTIONIV].len & 0xFF; // we need to create a local copy of IV, as it is modified during decryption. memcpy(&iv, hdr[ENCRYPTIONIV].data, ivlen); // Open an algorithm handle. status = BCryptOpenAlgorithmProvider( &aes, BCRYPT_AES_ALGORITHM, NULL, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto cleanup; } // Calculate the size of the buffer to hold the Key Object. status = BCryptGetProperty( aes, BCRYPT_OBJECT_LENGTH, (PBYTE)&key_objectlen, sizeof(DWORD), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGetProperty\n", status); goto cleanup; } // We should use preallocated memory for better performance... key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_objectlen); if(NULL == key_object) { printf("[!] memory allocation failed\n"); goto cleanup; } status = BCryptSetProperty( aes, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptSetProperty\n", status); goto cleanup; } // Generate the key from supplied input key bytes. status = BCryptGenerateSymmetricKey( aes, &ctx, key_object, key_objectlen, masterkey, 32, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGenerateSymmetricKey\n", status); goto cleanup; } status = BCryptDecrypt( ctx, payload->encrypted, hdr[STREAMSTARTBYTES].len, NULL, iv, ivlen, plaintext, sizeof(plaintext), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptDecrypt\n", status); goto cleanup; } // success! if (0 == memcmp(plaintext, hdr[STREAMSTARTBYTES].data, hdr[STREAMSTARTBYTES].len)) { res = true; payload->decrypted = malloc(hdr[STREAMSTARTBYTES].len); memcpy(payload->decrypted, plaintext, hdr[STREAMSTARTBYTES].len); } cleanup: if(aes) { BCryptCloseAlgorithmProvider(aes,0); } if (ctx) { BCryptDestroyKey(ctx); } if(key_object) { HeapFree(GetProcessHeap(), 0, key_object); } return res; }
int aes_transformkey(m0_kdbx_header_entry_t *hdr, uint8_t *tkey, size_t tkeylen) { BCRYPT_ALG_HANDLE aes = NULL; BCRYPT_KEY_HANDLE key = NULL; NTSTATUS status = 0; DWORD len_ciphertext = 0, tmp_len = 0, key_objectlen = 0; PBYTE key_object = NULL; uint64_t rounds = 0; // Open an algorithm handle. status = BCryptOpenAlgorithmProvider( &aes, BCRYPT_AES_ALGORITHM, NULL, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto cleanup; } // Calculate the size of the buffer to hold the KeyObject. status = BCryptGetProperty( aes, BCRYPT_OBJECT_LENGTH, (PBYTE)&key_objectlen, sizeof(DWORD), &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGetProperty\n", status); goto cleanup; } // Allocate the key object on the heap. key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_objectlen); if(NULL == key_object) { printf("[!] memory allocation failed\n"); goto cleanup; } status = BCryptSetProperty( aes, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptSetProperty\n", status); goto cleanup; } // Generate the key from supplied input key bytes. status = BCryptGenerateSymmetricKey( aes, &key, key_object, key_objectlen, hdr[TRANSFORMSEED].data, hdr[TRANSFORMSEED].len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptGenerateSymmetricKey\n", status); goto cleanup; } status = BCryptEncrypt( key, tkey, tkeylen, NULL, NULL, 0, NULL, 0, &len_ciphertext, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptEncrypt (calculate)\n", status); goto cleanup; } for(rounds = 0; rounds < hdr[TRANSFORMROUNDS].qw; rounds++) { status = BCryptEncrypt( key, tkey, tkeylen, NULL, NULL, 0, tkey, tkeylen, &tmp_len, 0); if(!NT_SUCCESS(status)) { printf("[!] Error 0x%x returned by BCryptEncrypt (encrypt)\n", status); goto cleanup; } } cleanup: if(aes) { BCryptCloseAlgorithmProvider(aes,0); } if (key) { BCryptDestroyKey(key); } if(key_object) { HeapFree(GetProcessHeap(), 0, key_object); } return status; }
EXTERN_C NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { const FLT_OPERATION_REGISTRATION fltCallbacks[] = { { IRP_MJ_CLEANUP, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, nullptr, ScvnpPostCleanupAndFlushBuffers, }, { IRP_MJ_FLUSH_BUFFERS, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, nullptr, ScvnpPostCleanupAndFlushBuffers, }, {IRP_MJ_SET_INFORMATION, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, ScvnpPreSetInformation, nullptr}, {IRP_MJ_OPERATION_END}}; const FLT_REGISTRATION filterRegistration = { sizeof(filterRegistration), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags nullptr, // Context fltCallbacks, // Operation callbacks ScvnpUnload, // FilterUnload nullptr, // InstanceSetup nullptr, // InstanceQueryTeardown nullptr, // InstanceTeardownStart nullptr, // InstanceTeardownComplete nullptr, // GenerateFileName nullptr, // GenerateDestinationFileName nullptr, // NormalizeNameComponent }; PAGED_CODE(); UNREFERENCED_PARAMETER(RegistryPath); // DBG_BREAK(); auto status = ScvnpCreateDirectory(SCVNP_OUT_DIRECTORY_PATH); if (!NT_SUCCESS(status)) { return status; } // Initialize the Log system status = LogInitialization( SCVNP_LOG_LEVEL | LOG_OPT_DISABLE_TIME | LOG_OPT_DISABLE_FUNCTION_NAME, SCVNP_LOG_FILE_PATH, nullptr); if (!NT_SUCCESS(status)) { return status; } // Initialize the crypt APIs. status = BCryptOpenAlgorithmProvider(&g_ScvnpSha1AlgorithmHandle, BCRYPT_SHA1_ALGORITHM, nullptr, 0); if (!NT_SUCCESS(status)) { LOG_ERROR("BCryptOpenAlgorithmProvider failed (%08x)", status); LogTermination(nullptr); return status; } // Register and start a mini filter driver status = FltRegisterFilter(DriverObject, &filterRegistration, &g_ScvnpFilterHandle); if (!NT_SUCCESS(status)) { LOG_ERROR("FltRegisterFilter failed (%08x)", status); BCryptCloseAlgorithmProvider(g_ScvnpSha1AlgorithmHandle, 0); LogTermination(nullptr); return status; } status = FltStartFiltering(g_ScvnpFilterHandle); if (!NT_SUCCESS(status)) { LOG_ERROR("FltStartFiltering failed (%08x)", status); FltUnregisterFilter(g_ScvnpFilterHandle); BCryptCloseAlgorithmProvider(g_ScvnpSha1AlgorithmHandle, 0); LogTermination(nullptr); return status; } LOG_INFO("Scavenger installed"); return status; }