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;
}
Exemple #2
0
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);
        }
    }
}
Exemple #3
0
int xpfurandom_cleanup(void** data, uint32_t size, void** win_alg_handle, xpfurandom_settings* s) {
	NTSTATUS st;
	char* x = *data;
	st = BCryptCloseAlgorithmProvider(*win_alg_handle, 0);
	switch (st){
		case STATUS_SUCCESS: break;
		case STATUS_INVALID_HANDLE: {
			fprintf(stderr, "XPFUrandom: BCryptCloseAlgorithmProvider failed: invalid algorithm handle(STATUS_INVALID_HANDLE)\n");
			return FAIL;
		}break;
	}
	SecureZeroMemory(*data, size);
	if (x[0]) {
		fprintf(stderr, "XPFUrandom: SecureZeroMemory failed, memory not zeroed, will not be freed\n");
		return FAIL;
	}
	if (s->file_out) {
		st = fclose(s->file_out);
		if (st) {
			fprintf(stderr, "XPFUrandom: fclose failed: %s\n", strerror(errno));
			return FAIL;
		}
	}
	free(*data);
	*data = NULL;
	return OK;
}
Exemple #4
0
void
mongoc_crypto_cng_cleanup (void)
{
   if (_sha1_hash_algo) {
      BCryptCloseAlgorithmProvider (&_sha1_hash_algo, 0);
   }
   if (_sha1_hmac_algo) {
      BCryptCloseAlgorithmProvider (&_sha1_hmac_algo, 0);
   }
   if (_sha256_hash_algo) {
      BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0);
   }
   if (_sha256_hash_algo) {
      BCryptCloseAlgorithmProvider (&_sha256_hash_algo, 0);
   }
}
Exemple #5
0
void
_libssh2_wincng_free(void)
{
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0);
    (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0);

    memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng));
}
Exemple #6
0
static void xmlSecMSCngSignatureFinalize(xmlSecTransformPtr transform) {
    xmlSecMSCngSignatureCtxPtr ctx;

    xmlSecAssert(xmlSecMSCngSignatureCheckId(transform));
    xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecMSCngSignatureSize));

    ctx = xmlSecMSCngSignatureGetCtx(transform);
    xmlSecAssert(ctx != NULL);

    if(ctx->data != NULL)  {
        xmlSecKeyDataDestroy(ctx->data);
    }

    if (ctx->pbHash != NULL) {
        xmlFree(ctx->pbHash);
    }

    if(ctx->hHashAlg != 0) {
        BCryptCloseAlgorithmProvider(ctx->hHashAlg, 0);
    }

    if(ctx->pbHashObject != NULL) {
        xmlFree(ctx->pbHashObject);
    }

    if(ctx->hHash != 0) {
        BCryptDestroyHash(ctx->hHash);
    }

    memset(ctx, 0, sizeof(xmlSecMSCngSignatureCtx));
}
static void
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
{
	if (ctx->hAlg != NULL) {
		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
		HeapFree(GetProcessHeap(), 0, ctx->hash);
		ctx->hAlg = NULL;
	}
}
BCryptHashImpl::~BCryptHashImpl()
{
    Aws::DeleteArray(m_hashObject);
    Aws::DeleteArray(m_hashBuffer);

    if (m_algorithmHandle)
    {
        BCryptCloseAlgorithmProvider(m_algorithmHandle, 0);
    }
}
Exemple #9
0
MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
{
#if defined(USE_MS_CRYPTOAPI)
    if (m_hProvider)
        CryptReleaseContext(m_hProvider, 0);
#elif defined(USE_MS_CNGAPI)
    if (m_hProvider)
        BCryptCloseAlgorithmProvider(m_hProvider, 0);
#endif
}
Exemple #10
0
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;
}
Exemple #11
0
EXTERN_C static NTSTATUS FLTAPI
ScvnpUnload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags) {
  PAGED_CODE();
  UNREFERENCED_PARAMETER(Flags);

  FltUnregisterFilter(g_ScvnpFilterHandle);
  BCryptCloseAlgorithmProvider(g_ScvnpSha1AlgorithmHandle, 0);
  LogTermination(nullptr);

  return STATUS_SUCCESS;
}
Exemple #12
0
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;
}
Exemple #13
0
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;

}
static int
aes_ctr_release(archive_crypto_ctx *ctx)
{

	if (ctx->hAlg != NULL) {
		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
		ctx->hAlg = NULL;
		BCryptDestroyKey(ctx->hKey);
		ctx->hKey = NULL;
		HeapFree(GetProcessHeap(), 0, ctx->keyObj);
		ctx->keyObj = NULL;
	}
	memset(ctx, 0, sizeof(*ctx));
	return 0;
}
Exemple #15
0
 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
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;
}
Exemple #17
0
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);
}
Exemple #18
0
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;
}
Exemple #19
0
//
// 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;
}
Exemple #20
0
int main(int argc, char **argv)
{
    // Handles for RSA
    BCRYPT_ALG_HANDLE hAlgo = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;

    FILE_CRYPTO_INFO cryptoInfo;
    PBYTE psPlainText = NULL;
    DWORD dwBytesWritten = 0;
    DWORD dwBytesRead = 0;
    CCRYPT_STATUS status;

    // TEST DATA //
    PBYTE pbData1 = "Hello world!\n";
    PBYTE pbData2 = "Hello person!\n";
    PBYTE pbData3 = "This is cool!\n";
    
    if (argc != 2) {
        printf("USAGE: %s <encrypt|decrypt>\n\n", argv[0]);
        return -1;
    }

    // --------------------------------------------------------------------------
    //
    //  Testing encrypting/writing to file
    //
    // --------------------------------------------------------------------------

    if (strcmp(argv[1], "encrypt") == 0)
    {
        if (CCRYPT_STATUS_SUCCESS != (status = CCryptCreateFile(&cryptoInfo, TEXT("test.log"), CCRYPT_FILE_WRITE))) {
            printf("CCryptCreateFile error: %x\n", status);
            return -1;
        }

        // Write data to file
        if (!CCryptWriteFile(&cryptoInfo, pbData1, strlen(pbData1), &dwBytesWritten)) {
            printf("CCryptWriteFile error: %x\n", GetLastError());
            return -1;
        }
        if (!CCryptWriteFile(&cryptoInfo, pbData2, strlen(pbData2), &dwBytesWritten)) {
            printf("CCryptWriteFile error: %x\n", GetLastError());
            return -1;
        }
        if (!CCryptWriteFile(&cryptoInfo, pbData3, strlen(pbData3), &dwBytesWritten)) {
            printf("CCryptWriteFile error: %x\n", GetLastError());
            return -1;
        }

        // Import our RSA public key to encrypt AES key
        if (CCRYPT_STATUS_SUCCESS != (status = RSAImportKey(&hAlgo, &hKey, TEXT("public.key"), BCRYPT_RSAPUBLIC_BLOB))) {
            printf("RSAImportKey error (public): %x\n", status);
            return -1;
        }

        // Finalize the file write
        if (!CCryptFinalizeFile(&cryptoInfo, hKey)) {
            printf("CCryptFinalizeFile error: %d\n", GetLastError());
            return -1;
        }

        CCryptCloseHandle(&cryptoInfo);
        BCryptDestroyKey(hKey);
        BCryptCloseAlgorithmProvider(hAlgo, 0);
    }

    // --------------------------------------------------------------------------
    //
    //  Testing reading/decrypting from file
    //
    // --------------------------------------------------------------------------

    else
    {
        if (CCRYPT_STATUS_SUCCESS != (status = CCryptCreateFile(&cryptoInfo, TEXT("test.log"), CCRYPT_FILE_READ))) {
            printf("CCryptCreateFile error: %x\n", status);
            return -1;
        }

        // Import our RSA private key to decrypt AES key
        if (CCRYPT_STATUS_SUCCESS != (status = RSAImportKey(&hAlgo, &hKey, TEXT("private.key"), BCRYPT_RSAPRIVATE_BLOB))) {
            printf("RSAImportKey error (private): %x\n", status);
            return -1;
        }

        if (!CCryptReadFile(&cryptoInfo, hKey, &psPlainText, &dwBytesRead))
        {
            printf("CCryptReadFile error: %x\n", GetLastError());
            return -1;
        }

        printf("Plain text: %s\n\n", psPlainText);

        if (psPlainText != NULL) {
            HeapFree(GetProcessHeap(), 0, psPlainText);
        }

        CCryptCloseHandle(&cryptoInfo);
        BCryptDestroyKey(hKey);
        BCryptCloseAlgorithmProvider(hAlgo, 0);
    }
    
    return 0;
}
Exemple #21
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);
}
Exemple #22
0
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);
}
Exemple #23
0
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);
}
Exemple #24
0
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);

}
Exemple #25
0
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;
}
Exemple #26
0
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;
}
//----------------------------------------------------------------------------
//
// PerformKeyDerivation
//
//----------------------------------------------------------------------------
NTSTATUS
PeformKeyDerivation(
    _In_  DWORD    ArrayIndex
    )
{
    NTSTATUS            Status;
    BCRYPT_ALG_HANDLE   KdfAlgHandle = NULL;
    BCRYPT_KEY_HANDLE   SecretKeyHandle = NULL;
    
    DWORD   ResultLength = 0;
    PBYTE   DerivedKey = NULL;
    DWORD   DerivedKeyLength = 0;
  
    
    Status = BCryptOpenAlgorithmProvider(
                                        &KdfAlgHandle,              // Alg Handle pointer
                                        KdfAlgorithmNameArray[ArrayIndex],   
                                                                    // Cryptographic Algorithm name (null terminated unicode string)
                                        NULL,                       // Provider name; if null, the default provider is loaded
                                        0);                         // Flags
        if( !NT_SUCCESS(Status) )
        {
            ReportError(Status);
            goto cleanup;
        }
        
        Status = BCryptGenerateSymmetricKey(
                                        KdfAlgHandle,               // Algorithm Handle 
                                        &SecretKeyHandle,           // A pointer to a key handle
                                        NULL,                       // Buffer that recieves the key object;NULL implies memory is allocated and freed by the function
                                        0,                          // Size of the buffer in bytes
                                        (PBYTE) Secret,             // Buffer that contains the key material
                                        sizeof(Secret),             // Size of the buffer in bytes
                                        0);                         // Flags
        if( !NT_SUCCESS(Status) )
        {
            ReportError(Status);
            goto cleanup;
        }
        
        //
        // Derive the key
        //
        
        DerivedKeyLength = DERIVED_KEY_LEN;
        
        DerivedKey = (PBYTE)HeapAlloc(GetProcessHeap(), 0, DerivedKeyLength);
        if( NULL == DerivedKey )
        {
            Status = STATUS_NO_MEMORY;
            ReportError(Status);
            goto cleanup;
        }

        // Generic parameters: 
        // KDF_GENERIC_PARAMETER and KDF_HASH_ALGORITHM are the generic parameters that can be passed for the following KDF algorithms:
        // BCRYPT_SP800108_CTR_HMAC_ALGORITHM 
        //      KDF_GENERIC_PARAMETER = KDF_LABEL||0x00||KDF_CONTEXT 
        // BCRYPT_SP80056A_CONCAT_ALGORITHM
        //      KDF_GENERIC_PARAMETER = KDF_ALGORITHMID || KDF_PARTYUINFO || KDF_PARTYVINFO {|| KDF_SUPPPUBINFO } {|| KDF_SUPPPRIVINFO }
        // BCRYPT_PBKDF2_ALGORITHM
        //      KDF_GENERIC_PARAMETER = KDF_SALT
        // BCRYPT_CAPI_KDF_ALGORITHM
        //      KDF_GENERIC_PARAMETER = Not used
        //
        // Alternatively, KDF specific parameters can be passed.
        // For BCRYPT_SP800108_CTR_HMAC_ALGORITHM: 
        //      KDF_HASH_ALGORITHM, KDF_LABEL and KDF_CONTEXT are required
        // For BCRYPT_SP80056A_CONCAT_ALGORITHM:
        //      KDF_HASH_ALGORITHM, KDF_ALGORITHMID, KDF_PARTYUINFO, KDF_PARTYVINFO are required
        //      KDF_SUPPPUBINFO, KDF_SUPPPRIVINFO are optional
        // For BCRYPT_PBKDF2_ALGORITHM
        //      KDF_HASH_ALGORITHM is required
        //      KDF_ITERATION_COUNT, KDF_SALT are optional
        //      Iteration count, (if not specified) will default to 10,000
        // For BCRYPT_CAPI_KDF_ALGORITHM
        //      KDF_HASH_ALGORITHM is required
        //
       
        // 
        // This sample uses KDF specific parameters defined in KeyDerivation.h
        //

        Status = BCryptKeyDerivation(
                                        SecretKeyHandle,            // Handle to the password key
                                        &ParamList[ArrayIndex],     // Parameters to the KDF algorithm
                                        DerivedKey,                 // Address of the buffer which recieves the derived bytes
                                        DerivedKeyLength,           // Size of the buffer in bytes
                                        &ResultLength,              // Variable that recieves number of bytes copied to above buffer 
                                        0);                         // Flags
        if( !NT_SUCCESS(Status) )
        {
            ReportError(Status);
            goto cleanup;
        }

        //
        // DerivedKeyLength bytes have been derived
        //

cleanup:    
   
        if( NULL != DerivedKey )
        {
            HeapFree( GetProcessHeap(), 0, DerivedKey);
            DerivedKey = NULL;
        }

        if( NULL != SecretKeyHandle )
        {
            Status = BCryptDestroyKey(SecretKeyHandle);
            if( !NT_SUCCESS(Status) )
            {
                ReportError(Status);
            }
            SecretKeyHandle = NULL;
        }

        if( NULL != KdfAlgHandle )
        {
            Status = BCryptCloseAlgorithmProvider(KdfAlgHandle,0);
            if( !NT_SUCCESS(Status) )
            {
                ReportError(Status);
            }
            KdfAlgHandle = NULL;
        }

    return Status;

}
Exemple #28
0
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;
}
Exemple #29
0
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);
}
Exemple #30
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;
}