@verbatim
-Copyright (c) 2009, Secure Endpoints Inc.
+Copyright (c) 2009-2015, Secure Endpoints Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
rc2test \
rctest \
test_bn \
+ test_bulk \
test_cipher \
test_engine_dso \
test_hmac \
$(HCRYPTOINCLUDEDIR)\evp.h \
$(HCRYPTOINCLUDEDIR)\evp-hcrypto.h \
$(HCRYPTOINCLUDEDIR)\evp-cc.h \
+ $(HCRYPTOINCLUDEDIR)\evp-wincng.h \
+ $(HCRYPTOINCLUDEDIR)\evp-w32.h \
$(HCRYPTOINCLUDEDIR)\hmac.h \
$(HCRYPTOINCLUDEDIR)\md2.h \
$(HCRYPTOINCLUDEDIR)\md4.h \
$(OBJ)\evp.obj \
$(OBJ)\evp-hcrypto.obj \
$(OBJ)\evp-cc.obj \
+ $(OBJ)\evp-wincng.obj \
+ $(OBJ)\evp-w32.obj \
$(OBJ)\engine.obj \
$(OBJ)\hmac.obj \
$(OBJ)\md2.obj \
$(OBJ)\rc2test.exe \
$(OBJ)\rctest.exe \
$(OBJ)\test_bn.exe \
+ $(OBJ)\test_bulk.exe \
$(OBJ)\test_cipher.exe \
$(OBJ)\test_engine_dso.exe \
$(OBJ)\test_hmac.exe \
$(EXECONLINK)
$(EXEPREP_NODIST)
+$(OBJ)\test_bulk.exe: $(OBJ)\test_bulk.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
+ $(EXECONLINK)
+ $(EXEPREP_NODIST)
+
$(OBJ)\test_cipher.exe: $(OBJ)\test_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
$(EXECONLINK)
$(EXEPREP_NODIST)
rc2test.exe
rctest.exe
test_bn.exe
+ test_bulk.exe
test_cipher.exe
test_engine_dso.exe
test_hmac.exe
+++ /dev/null
-/*
- * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <config.h>
-
-#include <Windows.h>
-
-BOOL WINAPI
-DllMain (HANDLE hInst,
- ULONG reason,
- LPVOID lpReserved)
-{
- switch(reason) {
- case DLL_PROCESS_ATTACH:
- case DLL_PROCESS_DETACH:
- default:
- return TRUE;
- }
-}
CCCryptorRelease(*ref);
}
- ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
- if (ret)
- return 0;
+ if (key) {
+ ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
+ if (ret)
+ return 0;
+ }
+
return 1;
}
int encp)
{
struct cc_key *cc = ctx->cipher_data;
- memcpy(ctx->iv, iv, ctx->cipher->iv_len);
+ if (iv)
+ memcpy(ctx->iv, iv, ctx->cipher->iv_len);
return init_cc_key(1, kCCAlgorithmAES128, kCCOptionECBMode,
key, ctx->cipher->key_len, NULL, &cc->href);
}
int encp)
{
AES_KEY *k = ctx->cipher_data;
- if (ctx->encrypt)
+ if (ctx->encrypt || EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB8_MODE)
AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
else
AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k);
unsigned int size)
{
AES_KEY *k = ctx->cipher_data;
- if (ctx->flags & EVP_CIPH_CFB8_MODE)
+ if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB8_MODE)
AES_cfb8_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
else
AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
--- /dev/null
+/*
+ * Copyright (c) 2015, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Windows fallback provider: decides whether to use hcrypto or
+ * wincng depending on whether bcrypt.dll is available (i.e. it
+ * is runtime compatible back to XP, but will use the native
+ * crypto APIs from Vista onwards).
+ */
+
+#include "config.h"
+
+#include <windows.h>
+#include <assert.h>
+
+#include <evp.h>
+#include <evp-w32.h>
+#include <evp-hcrypto.h>
+
+#if NTDDI_VERSION >= NTDDI_VISTA
+
+#include <evp-wincng.h>
+
+static LONG wincng_available = -1;
+
+static __inline int
+wincng_check_availability(void)
+{
+ if (wincng_available == -1) {
+ char szBCryptDllPath[MAX_PATH];
+ UINT cbBCryptDllPath;
+
+ cbBCryptDllPath = GetSystemDirectory(szBCryptDllPath,
+ sizeof(szBCryptDllPath));
+ if (cbBCryptDllPath > 0 &&
+ cbBCryptDllPath < sizeof(szBCryptDllPath) &&
+ strncat_s(szBCryptDllPath,
+ sizeof(szBCryptDllPath), "\\bcrypt.dll", 11) == 0) {
+ HANDLE hBCryptDll = LoadLibrary(szBCryptDllPath);
+
+ InterlockedCompareExchangeRelease(&wincng_available,
+ !!hBCryptDll, -1);
+ if (hBCryptDll)
+ FreeLibrary(hBCryptDll);
+ }
+ }
+
+ return wincng_available == 1;
+}
+
+BOOL WINAPI
+_hc_w32crypto_DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
+{
+ if (fdwReason == DLL_PROCESS_DETACH) {
+ /*
+ * Don't bother cleaning up on process exit, only on
+ * FreeLibrary() (in which case lpvReserved will be NULL).
+ */
+ if (lpvReserved == NULL)
+ _hc_wincng_cleanup();
+ }
+
+ return TRUE;
+}
+
+#define EVP_W32CRYPTO_PROVIDER(type, name) \
+ \
+ const type *hc_EVP_w32crypto_ ##name (void) \
+ { \
+ if (wincng_check_availability()) \
+ return hc_EVP_wincng_ ##name (); \
+ else \
+ return hc_EVP_hcrypto_ ##name (); \
+ }
+
+#else
+
+#define EVP_W32CRYPTO_PROVIDER(type, name) \
+ EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(type, name)
+
+#endif /* NTDDI_VERSION >= NTDDI_VISTA */
+
+#define EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(type, name) \
+ \
+ const type *hc_EVP_w32crypto_ ##name (void) \
+ { \
+ return hc_EVP_hcrypto_ ##name (); \
+ }
+
+EVP_W32CRYPTO_PROVIDER(EVP_MD, md2)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, md4)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, md5)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, sha1)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, sha256)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, sha384)
+EVP_W32CRYPTO_PROVIDER(EVP_MD, sha512)
+
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_cbc)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_40_cbc)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc2_64_cbc)
+
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, rc4_40)
+
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_cbc)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, des_ede3_cbc)
+
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cbc)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cbc)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cbc)
+
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_128_cfb8)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_192_cfb8)
+EVP_W32CRYPTO_PROVIDER(EVP_CIPHER, aes_256_cfb8)
+
+EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_128_cbc)
+EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_192_cbc)
+EVP_W32CRYPTO_PROVIDER_CNG_UNAVAILABLE(EVP_CIPHER, camellia_256_cbc)
--- /dev/null
+/*
+ * Copyright (c) 2015, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_W32_H
+#define HEIM_EVP_W32_H 1
+
+/* symbol renaming */
+#define EVP_w32crypto_md2() hc_EVP_w32crypto_md2()
+#define EVP_w32crypto_md4() hc_EVP_w32crypto_md4()
+#define EVP_w32crypto_md5() hc_EVP_w32crypto_md5()
+#define EVP_w32crypto_sha1() hc_EVP_w32crypto_sha1()
+#define EVP_w32crypto_sha256() hc_EVP_w32crypto_sha256()
+#define EVP_w32crypto_sha384() hc_EVP_w32crypto_sha384()
+#define EVP_w32crypto_sha512() hc_EVP_w32crypto_sha512()
+#define EVP_w32crypto_des_cbc() hc_EVP_w32crypto_des_cbc()
+#define EVP_w32crypto_des_ede3_cbc() hc_EVP_w32crypto_des_ede3_cbc()
+#define EVP_w32crypto_aes_128_cbc() hc_EVP_w32crypto_aes_128_cbc()
+#define EVP_w32crypto_aes_192_cbc() hc_EVP_w32crypto_aes_192_cbc()
+#define EVP_w32crypto_aes_256_cbc() hc_EVP_w32crypto_aes_256_cbc()
+#define EVP_w32crypto_aes_128_cfb8() hc_EVP_w32crypto_aes_128_cfb8()
+#define EVP_w32crypto_aes_192_cfb8() hc_EVP_w32crypto_aes_192_cfb8()
+#define EVP_w32crypto_aes_256_cfb8() hc_EVP_w32crypto_aes_256_cfb8()
+#define EVP_w32crypto_rc4() hc_EVP_w32crypto_rc4()
+#define EVP_w32crypto_rc4_40() hc_EVP_w32crypto_rc4_40()
+#define EVP_w32crypto_rc2_40_cbc() hc_EVP_w32crypto_rc2_40_cbc()
+#define EVP_w32crypto_rc2_64_cbc() hc_EVP_w32crypto_rc2_64_cbc()
+#define EVP_w32crypto_rc2_cbc() hc_EVP_w32crypto_rc2_cbc()
+#define EVP_w32crypto_camellia_128_cbc() hc_EVP_w32crypto_camellia_128_cbc()
+#define EVP_w32crypto_camellia_192_cbc() hc_EVP_w32crypto_camellia_192_cbc()
+#define EVP_w32crypto_camellia_256_cbc() hc_EVP_w32crypto_camellia_256_cbc()
+
+/*
+ * This provider dynamically selects between Windows CNG (if running
+ * on Vista or above) or the inbuilt provider (if running on XP).
+ */
+
+HC_CPP_BEGIN
+
+const EVP_MD * hc_EVP_w32crypto_md2(void);
+const EVP_MD * hc_EVP_w32crypto_md4(void);
+const EVP_MD * hc_EVP_w32crypto_md5(void);
+const EVP_MD * hc_EVP_w32crypto_sha1(void);
+const EVP_MD * hc_EVP_w32crypto_sha256(void);
+const EVP_MD * hc_EVP_w32crypto_sha384(void);
+const EVP_MD * hc_EVP_w32crypto_sha512(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_des_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_des_ede3_cbc(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_aes_128_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_aes_192_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_aes_256_cbc(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_aes_128_cfb8(void);
+const EVP_CIPHER * hc_EVP_w32crypto_aes_192_cfb8(void);
+const EVP_CIPHER * hc_EVP_w32crypto_aes_256_cfb8(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_rc4(void);
+const EVP_CIPHER * hc_EVP_w32crypto_rc4_40(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_rc2_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_rc2_40_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_rc2_64_cbc(void);
+
+const EVP_CIPHER * hc_EVP_w32crypto_camellia_128_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_camellia_192_cbc(void);
+const EVP_CIPHER * hc_EVP_w32crypto_camellia_256_cbc(void);
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_W32_H */
--- /dev/null
+/*
+ * Copyright (c) 2015, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Windows CNG provider */
+
+#include "config.h"
+
+#include <windows.h>
+#include <assert.h>
+
+#if NTDDI_VERSION >= NTDDI_VISTA
+
+#include <evp.h>
+#include <evp-wincng.h>
+
+#include <bcrypt.h>
+
+/*
+ * CNG cipher provider
+ */
+
+struct wincng_key {
+ BCRYPT_KEY_HANDLE hKey;
+ UCHAR rgbKeyObject[1];
+};
+
+#define WINCNG_KEY_OBJECT_SIZE(ctx) \
+ ((ctx)->cipher->ctx_size - sizeof(struct wincng_key) + 1)
+
+static int
+wincng_do_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in,
+ unsigned int size)
+{
+ struct wincng_key *cng = ctx->cipher_data;
+ NTSTATUS status;
+ ULONG cbResult;
+
+ assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER ||
+ (size % ctx->cipher->block_size) == 0);
+
+ if (ctx->encrypt) {
+ status = BCryptEncrypt(cng->hKey,
+ (PUCHAR)in,
+ size,
+ NULL, /* pPaddingInfo */
+ ctx->cipher->iv_len ? ctx->iv : NULL,
+ ctx->cipher->iv_len,
+ out,
+ size,
+ &cbResult,
+ 0);
+ } else {
+ status = BCryptDecrypt(cng->hKey,
+ (PUCHAR)in,
+ size,
+ NULL, /* pPaddingInfo */
+ ctx->cipher->iv_len ? ctx->iv : NULL,
+ ctx->cipher->iv_len,
+ out,
+ size,
+ &cbResult,
+ 0);
+ }
+
+ return BCRYPT_SUCCESS(status) && cbResult == size;
+}
+
+static int
+wincng_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ struct wincng_key *cng = ctx->cipher_data;
+
+ if (cng->hKey)
+ BCryptDestroyKey(cng->hKey);
+ SecureZeroMemory(cng->rgbKeyObject, WINCNG_KEY_OBJECT_SIZE(ctx));
+
+ return 1;
+}
+
+static int
+wincng_cipher_algorithm_init(EVP_CIPHER *cipher,
+ LPWSTR pszAlgId)
+{
+ BCRYPT_ALG_HANDLE hAlgorithm = NULL;
+ NTSTATUS status;
+ LPCWSTR pszChainingMode;
+ ULONG cbKeyObject, cbChainingMode, cbData;
+
+ if (cipher->app_data)
+ return 1;
+
+ status = BCryptOpenAlgorithmProvider(&hAlgorithm,
+ pszAlgId,
+ NULL,
+ 0);
+ if (!BCRYPT_SUCCESS(status))
+ return 0;
+
+ status = BCryptGetProperty(hAlgorithm,
+ BCRYPT_OBJECT_LENGTH,
+ (PUCHAR)&cbKeyObject,
+ sizeof(ULONG),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return 0;
+ }
+
+ cipher->ctx_size = sizeof(struct wincng_key) + cbKeyObject - 1;
+
+ switch (cipher->flags & EVP_CIPH_MODE) {
+ case EVP_CIPH_CBC_MODE:
+ pszChainingMode = BCRYPT_CHAIN_MODE_CBC;
+ cbChainingMode = sizeof(BCRYPT_CHAIN_MODE_CBC);
+ break;
+ case EVP_CIPH_CFB8_MODE:
+ pszChainingMode = BCRYPT_CHAIN_MODE_CFB;
+ cbChainingMode = sizeof(BCRYPT_CHAIN_MODE_CFB);
+ break;
+ default:
+ pszChainingMode = NULL;
+ cbChainingMode = 0;
+ break;
+ }
+
+ if (cbChainingMode) {
+ status = BCryptSetProperty(hAlgorithm,
+ BCRYPT_CHAINING_MODE,
+ (PUCHAR)pszChainingMode,
+ cbChainingMode,
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return 0;
+ }
+ }
+
+ if (wcscmp(pszAlgId, BCRYPT_RC2_ALGORITHM) == 0) {
+ ULONG cbEffectiveKeyLength = EVP_CIPHER_key_length(cipher) * 8;
+
+ status = BCryptSetProperty(hAlgorithm,
+ BCRYPT_EFFECTIVE_KEY_LENGTH,
+ (PUCHAR)&cbEffectiveKeyLength,
+ sizeof(cbEffectiveKeyLength),
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return 0;
+ }
+ }
+
+ InterlockedCompareExchangePointerRelease(&cipher->app_data,
+ hAlgorithm, NULL);
+ return 1;
+}
+
+static int
+wincng_key_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char *key,
+ const unsigned char *iv,
+ int encp)
+{
+ struct wincng_key *cng = ctx->cipher_data;
+ NTSTATUS status;
+
+ assert(cng != NULL);
+ assert(ctx->cipher != NULL);
+
+ if (ctx->cipher->app_data == NULL)
+ return 0;
+
+ /*
+ * Note: ctx->key_len not EVP_CIPHER_CTX_key_length() for
+ * variable length key support.
+ */
+ status = BCryptGenerateSymmetricKey(ctx->cipher->app_data,
+ &cng->hKey,
+ cng->rgbKeyObject,
+ WINCNG_KEY_OBJECT_SIZE(ctx),
+ (PUCHAR)key,
+ ctx->key_len,
+ 0);
+
+ return BCRYPT_SUCCESS(status);
+}
+
+#define WINCNG_CIPHER_ALGORITHM(name, alg_id, block_size, key_len, \
+ iv_len, flags) \
+ \
+ static EVP_CIPHER \
+ wincng_##name = { \
+ 0, \
+ block_size, \
+ key_len, \
+ iv_len, \
+ flags, \
+ wincng_key_init, \
+ wincng_do_cipher, \
+ wincng_cleanup, \
+ 0, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+ }; \
+ \
+ const EVP_CIPHER * \
+ hc_EVP_wincng_##name(void) \
+ { \
+ wincng_cipher_algorithm_init(&wincng_##name, alg_id); \
+ return wincng_##name.app_data ? &wincng_##name : NULL; \
+ }
+
+#define WINCNG_CIPHER_ALGORITHM_CLEANUP(name) do { \
+ if (wincng_##name.app_data) { \
+ BCryptCloseAlgorithmProvider(wincng_##name.app_data, 0); \
+ wincng_##name.app_data = NULL; \
+ } \
+ } while (0)
+
+#define WINCNG_CIPHER_ALGORITHM_UNAVAILABLE(name) \
+ \
+ const EVP_CIPHER * \
+ hc_EVP_wincng_##name(void) \
+ { \
+ return NULL; \
+ }
+
+/**
+ * The tripple DES cipher type (Windows CNG provider)
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(des_ede3_cbc,
+ BCRYPT_3DES_ALGORITHM,
+ 8,
+ 24,
+ 8,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The DES cipher type (Windows CNG provider)
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(des_cbc,
+ BCRYPT_DES_ALGORITHM,
+ 8,
+ 8,
+ 8,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The AES-128 cipher type (Windows CNG provider)
+ *
+ * @return the AES-128-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_128_cbc,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 16,
+ 16,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The AES-192 cipher type (Windows CNG provider)
+ *
+ * @return the AES-192-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_192_cbc,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 24,
+ 16,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The AES-256 cipher type (Windows CNG provider)
+ *
+ * @return the AES-256-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_256_cbc,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 32,
+ 16,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The AES-128 CFB8 cipher type (Windows CNG provider)
+ *
+ * @return the AES-128-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_128_cfb8,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 16,
+ 16,
+ EVP_CIPH_CFB8_MODE);
+
+/**
+ * The AES-192 CFB8 cipher type (Windows CNG provider)
+ *
+ * @return the AES-192-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_192_cfb8,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 24,
+ 16,
+ EVP_CIPH_CFB8_MODE);
+
+/**
+ * The AES-256 CFB8 cipher type (Windows CNG provider)
+ *
+ * @return the AES-256-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(aes_256_cfb8,
+ BCRYPT_AES_ALGORITHM,
+ 16,
+ 32,
+ 16,
+ EVP_CIPH_CFB8_MODE);
+
+/**
+ * The RC2 cipher type - Windows CNG
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(rc2_cbc,
+ BCRYPT_RC2_ALGORITHM,
+ 8,
+ 16,
+ 8,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The RC2-40 cipher type - Windows CNG
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(rc2_40_cbc,
+ BCRYPT_RC2_ALGORITHM,
+ 8,
+ 5,
+ 8,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The RC2-64 cipher type - Windows CNG
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(rc2_64_cbc,
+ BCRYPT_RC2_ALGORITHM,
+ 8,
+ 8,
+ 8,
+ EVP_CIPH_CBC_MODE);
+
+/**
+ * The Camellia-128 cipher type - CommonCrypto
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM_UNAVAILABLE(camellia_128_cbc);
+
+/**
+ * The Camellia-198 cipher type - CommonCrypto
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM_UNAVAILABLE(camellia_192_cbc);
+
+/**
+ * The Camellia-256 cipher type - CommonCrypto
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM_UNAVAILABLE(camellia_256_cbc);
+
+/**
+ * The RC4 cipher type (Windows CNG provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(rc4,
+ BCRYPT_RC4_ALGORITHM,
+ 1,
+ 16,
+ 0,
+ EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH);
+
+/**
+ * The RC4-40 cipher type (Windows CNG provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+WINCNG_CIPHER_ALGORITHM(rc4_40,
+ BCRYPT_RC4_ALGORITHM,
+ 1,
+ 5,
+ 0,
+ EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH);
+
+static void
+wincng_cipher_algorithm_cleanup(void)
+{
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(des_ede3_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(des_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_128_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_192_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_256_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_128_cfb8);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_192_cfb8);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(aes_256_cfb8);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(rc2_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(rc2_40_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(rc2_64_cbc);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(rc4);
+ WINCNG_CIPHER_ALGORITHM_CLEANUP(rc4_40);
+}
+
+/*
+ * CNG digest provider
+ */
+
+struct wincng_md_ctx {
+ BCRYPT_HASH_HANDLE hHash;
+ ULONG cbHashObject;
+ UCHAR rgbHashObject[1];
+};
+
+static BCRYPT_ALG_HANDLE
+wincng_md_algorithm_init(EVP_MD *md,
+ LPCWSTR pszAlgId)
+{
+ BCRYPT_ALG_HANDLE hAlgorithm;
+ NTSTATUS status;
+ ULONG cbHashObject, cbData;
+ ULONG cbHash = 0, cbBlock = 0;
+
+ status = BCryptOpenAlgorithmProvider(&hAlgorithm,
+ pszAlgId,
+ NULL,
+ 0);
+ if (!BCRYPT_SUCCESS(status))
+ return NULL;
+
+ status = BCryptGetProperty(hAlgorithm,
+ BCRYPT_HASH_LENGTH,
+ (PUCHAR)&cbHash,
+ sizeof(ULONG),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return NULL;
+ }
+
+ status = BCryptGetProperty(hAlgorithm,
+ BCRYPT_HASH_BLOCK_LENGTH,
+ (PUCHAR)&cbBlock,
+ sizeof(ULONG),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return NULL;
+ }
+
+ status = BCryptGetProperty(hAlgorithm,
+ BCRYPT_OBJECT_LENGTH,
+ (PUCHAR)&cbHashObject,
+ sizeof(ULONG),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+ return NULL;
+ }
+
+ md->hash_size = cbHash;
+ md->block_size = cbBlock;
+ md->ctx_size = sizeof(struct wincng_md_ctx) + cbHashObject - 1;
+
+ return hAlgorithm;
+}
+
+static int
+wincng_md_hash_init(BCRYPT_ALG_HANDLE hAlgorithm,
+ EVP_MD_CTX *ctx)
+{
+ struct wincng_md_ctx *cng = (struct wincng_md_ctx *)ctx;
+ NTSTATUS status;
+ ULONG cbData;
+
+ status = BCryptGetProperty(hAlgorithm,
+ BCRYPT_OBJECT_LENGTH,
+ (PUCHAR)&cng->cbHashObject,
+ sizeof(ULONG),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status))
+ return 0;
+
+ status = BCryptCreateHash(hAlgorithm,
+ &cng->hHash,
+ cng->rgbHashObject,
+ cng->cbHashObject,
+ NULL,
+ 0,
+ 0);
+
+ return BCRYPT_SUCCESS(status);
+}
+
+static int
+wincng_md_update(EVP_MD_CTX *ctx,
+ const void *data,
+ size_t length)
+{
+ struct wincng_md_ctx *cng = (struct wincng_md_ctx *)ctx;
+ NTSTATUS status;
+
+ status = BCryptHashData(cng->hHash, (PUCHAR)data, length, 0);
+
+ return BCRYPT_SUCCESS(status);
+}
+
+static int
+wincng_md_final(void *digest,
+ EVP_MD_CTX *ctx)
+{
+ struct wincng_md_ctx *cng = (struct wincng_md_ctx *)ctx;
+ NTSTATUS status;
+ ULONG cbHash, cbData;
+
+ status = BCryptGetProperty(cng->hHash,
+ BCRYPT_HASH_LENGTH,
+ (PUCHAR)&cbHash,
+ sizeof(DWORD),
+ &cbData,
+ 0);
+ if (!BCRYPT_SUCCESS(status))
+ return 0;
+
+ status = BCryptFinishHash(cng->hHash,
+ digest,
+ cbHash,
+ 0);
+
+ return BCRYPT_SUCCESS(status);
+}
+
+static int
+wincng_md_cleanup(EVP_MD_CTX *ctx)
+{
+ struct wincng_md_ctx *cng = (struct wincng_md_ctx *)ctx;
+
+ if (cng->hHash)
+ BCryptDestroyHash(cng->hHash);
+ SecureZeroMemory(cng->rgbHashObject, cng->cbHashObject);
+
+ return 1;
+}
+
+#define WINCNG_MD_ALGORITHM(name, alg_id) \
+ \
+ static BCRYPT_ALG_HANDLE wincng_hAlgorithm_##name; \
+ \
+ static int wincng_##name##_init(EVP_MD_CTX *ctx) \
+ { \
+ return wincng_md_hash_init(wincng_hAlgorithm_##name, ctx); \
+ } \
+ \
+ const EVP_MD * \
+ hc_EVP_wincng_##name(void) \
+ { \
+ static struct hc_evp_md name = { \
+ 0, \
+ 0, \
+ 0, \
+ wincng_##name##_init, \
+ wincng_md_update, \
+ wincng_md_final, \
+ wincng_md_cleanup \
+ }; \
+ \
+ if (wincng_hAlgorithm_##name == NULL) { \
+ BCRYPT_ALG_HANDLE hAlgorithm = \
+ wincng_md_algorithm_init(&name, alg_id); \
+ InterlockedCompareExchangePointerRelease( \
+ &wincng_hAlgorithm_##name, hAlgorithm, NULL); \
+ } \
+ return wincng_hAlgorithm_##name ? &name : NULL; \
+ }
+
+#define WINCNG_MD_ALGORITHM_CLEANUP(name) do { \
+ if (wincng_hAlgorithm_##name) { \
+ BCryptCloseAlgorithmProvider(wincng_hAlgorithm_##name, 0); \
+ wincng_hAlgorithm_##name = NULL; \
+ } \
+ } while (0)
+
+WINCNG_MD_ALGORITHM(md2, BCRYPT_MD2_ALGORITHM);
+WINCNG_MD_ALGORITHM(md4, BCRYPT_MD4_ALGORITHM);
+WINCNG_MD_ALGORITHM(md5, BCRYPT_MD5_ALGORITHM);
+WINCNG_MD_ALGORITHM(sha1, BCRYPT_SHA1_ALGORITHM);
+WINCNG_MD_ALGORITHM(sha256, BCRYPT_SHA256_ALGORITHM);
+WINCNG_MD_ALGORITHM(sha384, BCRYPT_SHA384_ALGORITHM);
+WINCNG_MD_ALGORITHM(sha512, BCRYPT_SHA512_ALGORITHM);
+
+static void
+wincng_md_algorithm_cleanup(void)
+{
+ WINCNG_MD_ALGORITHM_CLEANUP(md2);
+ WINCNG_MD_ALGORITHM_CLEANUP(md4);
+ WINCNG_MD_ALGORITHM_CLEANUP(md5);
+ WINCNG_MD_ALGORITHM_CLEANUP(sha1);
+ WINCNG_MD_ALGORITHM_CLEANUP(sha256);
+ WINCNG_MD_ALGORITHM_CLEANUP(sha384);
+ WINCNG_MD_ALGORITHM_CLEANUP(sha512);
+}
+
+void _hc_wincng_cleanup(void)
+{
+ wincng_md_algorithm_cleanup();
+ wincng_cipher_algorithm_cleanup();
+}
+
+#endif /* NTDDI_VERSION >= NTDDI_VISTA */
--- /dev/null
+/*
+ * Copyright (c) 2015, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_WINCNG_H
+#define HEIM_EVP_WINCNG_H 1
+
+/* symbol renaming */
+#define EVP_wincng_md2() EVP_wincng_md2()
+#define EVP_wincng_md4() EVP_wincng_md4()
+#define EVP_wincng_md5() EVP_wincng_md5()
+#define EVP_wincng_sha1() EVP_wincng_sha1()
+#define EVP_wincng_sha256() EVP_wincng_sha256()
+#define EVP_wincng_sha384() EVP_wincng_sha384()
+#define EVP_wincng_sha512() EVP_wincng_sha512()
+#define EVP_wincng_des_cbc() EVP_wincng_des_cbc()
+#define EVP_wincng_des_ede3_cbc() EVP_wincng_des_ede3_cbc()
+#define EVP_wincng_aes_128_cbc() EVP_wincng_aes_128_cbc()
+#define EVP_wincng_aes_192_cbc() EVP_wincng_aes_192_cbc()
+#define EVP_wincng_aes_256_cbc() EVP_wincng_aes_256_cbc()
+#define EVP_wincng_aes_128_cfb8() EVP_wincng_aes_128_cfb8()
+#define EVP_wincng_aes_192_cfb8() EVP_wincng_aes_192_cfb8()
+#define EVP_wincng_aes_256_cfb8() EVP_wincng_aes_256_cfb8()
+#define EVP_wincng_rc4() EVP_wincng_rc4()
+#define EVP_wincng_rc4_40() EVP_wincng_rc4_40()
+#define EVP_wincng_rc2_40_cbc() EVP_wincng_rc2_40_cbc()
+#define EVP_wincng_rc2_64_cbc() EVP_wincng_rc2_64_cbc()
+#define EVP_wincng_rc2_cbc() EVP_wincng_rc2_cbc()
+#define EVP_wincng_camellia_128_cbc() EVP_wincng_camellia_128_cbc()
+#define EVP_wincng_camellia_192_cbc() EVP_wincng_camellia_192_cbc()
+#define EVP_wincng_camellia_256_cbc() EVP_wincng_camellia_256_cbc()
+
+/*
+ *
+ */
+
+HC_CPP_BEGIN
+
+const EVP_MD * hc_EVP_wincng_md2(void);
+const EVP_MD * hc_EVP_wincng_md4(void);
+const EVP_MD * hc_EVP_wincng_md5(void);
+const EVP_MD * hc_EVP_wincng_sha1(void);
+const EVP_MD * hc_EVP_wincng_sha256(void);
+const EVP_MD * hc_EVP_wincng_sha384(void);
+const EVP_MD * hc_EVP_wincng_sha512(void);
+
+const EVP_CIPHER * hc_EVP_wincng_rc2_cbc(void);
+const EVP_CIPHER * hc_EVP_wincng_rc2_40_cbc(void);
+const EVP_CIPHER * hc_EVP_wincng_rc2_64_cbc(void);
+
+const EVP_CIPHER * hc_EVP_wincng_rc4(void);
+const EVP_CIPHER * hc_EVP_wincng_rc4_40(void);
+
+const EVP_CIPHER * hc_EVP_wincng_des_cbc(void);
+const EVP_CIPHER * hc_EVP_wincng_des_ede3_cbc(void);
+
+const EVP_CIPHER * hc_EVP_wincng_aes_128_cbc(void);
+const EVP_CIPHER * hc_EVP_wincng_aes_192_cbc(void);
+const EVP_CIPHER * hc_EVP_wincng_aes_256_cbc(void);
+
+const EVP_CIPHER * hc_EVP_wincng_aes_128_cfb8(void);
+const EVP_CIPHER * hc_EVP_wincng_aes_192_cfb8(void);
+const EVP_CIPHER * hc_EVP_wincng_aes_256_cfb8(void);
+
+void _hc_wincng_cleanup(void);
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_WINCNG_H */
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
+#include <evp-w32.h>
#include <krb5-types.h>
#include <roken.h>
int
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) HC_DEPRECATED
{
- if (ctx->md && ctx->md->cleanup)
- (ctx->md->cleanup)(ctx);
- else if (ctx->md)
+ if (ctx->md && ctx->md->cleanup) {
+ int ret = (ctx->md->cleanup)(ctx);
+ if (!ret)
+ return ret;
+ } else if (ctx->md) {
memset(ctx->ptr, 0, ctx->md->ctx_size);
+ }
ctx->md = NULL;
ctx->engine = NULL;
free(ctx->ptr);
if (ctx->ptr == NULL)
return 0;
}
- (ctx->md->init)(ctx->ptr);
- return 1;
+ return (ctx->md->init)(ctx->ptr);
}
/**
int
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{
- if (c->cipher && c->cipher->cleanup)
- c->cipher->cleanup(c);
+ if (c->cipher && c->cipher->cleanup) {
+ int ret = c->cipher->cleanup(c);
+ if (!ret)
+ return ret;
+ }
if (c->cipher_data) {
memset(c->cipher_data, 0, c->cipher->ctx_size);
free(c->cipher_data);
}
if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT))
- ctx->cipher->init(ctx, key, iv, encp);
+ return ctx->cipher->init(ctx, key, iv, encp);
return 1;
}
;! hc_EVP_cc_aes_192_cfb8
;! hc_EVP_cc_aes_256_cfb8
+ hc_EVP_w32crypto_md2 ;!
+ hc_EVP_w32crypto_md4 ;!
+ hc_EVP_w32crypto_md5 ;!
+ hc_EVP_w32crypto_sha1 ;!
+ hc_EVP_w32crypto_sha256 ;!
+ hc_EVP_w32crypto_sha384 ;!
+ hc_EVP_w32crypto_sha512 ;!
+ hc_EVP_w32crypto_des_ede3_cbc ;!
+ hc_EVP_w32crypto_aes_128_cbc ;!
+ hc_EVP_w32crypto_aes_192_cbc ;!
+ hc_EVP_w32crypto_aes_256_cbc ;!
+ hc_EVP_w32crypto_rc2_40_cbc ;!
+ hc_EVP_w32crypto_rc2_cbc ;!
+ hc_EVP_w32crypto_rc4 ;!
+ hc_EVP_w32crypto_rc4_40 ;!
+
+ hc_EVP_w32crypto_aes_128_cfb8 ;!
+ hc_EVP_w32crypto_aes_192_cfb8 ;!
+ hc_EVP_w32crypto_aes_256_cfb8 ;!
+
hc_EVP_hcrypto_md2
hc_EVP_hcrypto_md4
hc_EVP_hcrypto_md5
hc_EVP_CIPHER_CTX_ctrl
hc_EVP_CIPHER_CTX_rand_key
hc_EVP_CIPHER_CTX_set_key_length
+ hc_EVP_hcrypto_rc2_cbc
hc_EVP_hcrypto_rc2_40_cbc
hc_EVP_hcrypto_camellia_128_cbc
hc_EVP_CipherUpdate
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
-void
+int
MD2_Init (struct md2 *m)
{
memset(m, 0, sizeof(*m));
+ return 1;
}
static void
memset(x, 0, sizeof(x));
}
-void
+int
MD2_Update (struct md2 *m, const void *v, size_t len)
{
size_t idx = m->len & 0xf;
}
memcpy(m->data + idx, p, len);
+ return 1;
}
-void
+int
MD2_Final (void *res, struct md2 *m)
{
unsigned char pad[16];
memcpy(res, m->state, MD2_DIGEST_LENGTH);
memset(m, 0, sizeof(*m));
+ return 1;
}
typedef struct md2 MD2_CTX;
-void MD2_Init (struct md2 *m);
-void MD2_Update (struct md2 *m, const void *p, size_t len);
-void MD2_Final (void *res, struct md2 *m);
+int MD2_Init (struct md2 *m);
+int MD2_Update (struct md2 *m, const void *p, size_t len);
+int MD2_Final (void *res, struct md2 *m);
#endif /* HEIM_MD2_H */
#define D m->counter[3]
#define X data
-void
+int
MD4_Init (struct md4 *m)
{
m->sz[0] = 0;
C = 0x98badcfe;
B = 0xefcdab89;
A = 0x67452301;
+ return 1;
}
#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
unsigned int b:32;
};
-void
+int
MD4_Update (struct md4 *m, const void *v, size_t len)
{
const unsigned char *p = v;
offset = 0;
}
}
+ return 1;
}
-void
+int
MD4_Final (void *res, struct md4 *m)
{
unsigned char zeros[72];
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
+ return 1;
}
typedef struct md4 MD4_CTX;
-void MD4_Init (struct md4 *m);
-void MD4_Update (struct md4 *m, const void *p, size_t len);
-void MD4_Final (void *res, struct md4 *m);
+int MD4_Init (struct md4 *m);
+int MD4_Update (struct md4 *m, const void *p, size_t len);
+int MD4_Final (void *res, struct md4 *m);
#endif /* HEIM_MD4_H */
#define D m->counter[3]
#define X data
-void
+int
MD5_Init (struct md5 *m)
{
m->sz[0] = 0;
C = 0x98badcfe;
B = 0xefcdab89;
A = 0x67452301;
+ return 1;
}
#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
unsigned int b:32;
};
-void
+int
MD5_Update (struct md5 *m, const void *v, size_t len)
{
const unsigned char *p = v;
offset = 0;
}
}
+ return 1;
}
-void
+int
MD5_Final (void *res, struct md5 *m)
{
unsigned char zeros[72];
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
+ return 1;
}
typedef struct md5 MD5_CTX;
-void MD5_Init (struct md5 *m);
-void MD5_Update (struct md5 *m, const void *p, size_t len);
-void MD5_Final (void *res, struct md5 *m); /* uint32_t res[4] */
+int MD5_Init (struct md5 *m);
+int MD5_Update (struct md5 *m, const void *p, size_t len);
+int MD5_Final (void *res, struct md5 *m); /* uint32_t res[4] */
#endif /* HEIM_MD5_H */
#define E m->counter[4]
#define X data
-void
+int
SHA1_Init (struct sha *m)
{
m->sz[0] = 0;
C = 0x98badcfe;
D = 0x10325476;
E = 0xc3d2e1f0;
+ return 1;
}
unsigned int b:32;
};
-void
+int
SHA1_Update (struct sha *m, const void *v, size_t len)
{
const unsigned char *p = v;
offset = 0;
}
}
+ return 1;
}
-void
+int
SHA1_Final (void *res, struct sha *m)
{
unsigned char zeros[72];
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
+ return 1;
}
typedef struct sha SHA_CTX;
-void SHA1_Init (struct sha *m);
-void SHA1_Update (struct sha *m, const void *v, size_t len);
-void SHA1_Final (void *res, struct sha *m);
+int SHA1_Init (struct sha *m);
+int SHA1_Update (struct sha *m, const void *v, size_t len);
+int SHA1_Final (void *res, struct sha *m);
/*
* SHA-2 256
typedef struct hc_sha256state SHA256_CTX;
-void SHA256_Init (SHA256_CTX *);
-void SHA256_Update (SHA256_CTX *, const void *, size_t);
-void SHA256_Final (void *, SHA256_CTX *);
+int SHA256_Init (SHA256_CTX *);
+int SHA256_Update (SHA256_CTX *, const void *, size_t);
+int SHA256_Final (void *, SHA256_CTX *);
/*
* SHA-2 512
typedef struct hc_sha512state SHA512_CTX;
-void SHA512_Init (SHA512_CTX *);
-void SHA512_Update (SHA512_CTX *, const void *, size_t);
-void SHA512_Final (void *, SHA512_CTX *);
+int SHA512_Init (SHA512_CTX *);
+int SHA512_Update (SHA512_CTX *, const void *, size_t);
+int SHA512_Final (void *, SHA512_CTX *);
#define SHA384_DIGEST_LENGTH 48
typedef struct hc_sha512state SHA384_CTX;
-void SHA384_Init (SHA384_CTX *);
-void SHA384_Update (SHA384_CTX *, const void *, size_t);
-void SHA384_Final (void *, SHA384_CTX *);
+int SHA384_Init (SHA384_CTX *);
+int SHA384_Update (SHA384_CTX *, const void *, size_t);
+int SHA384_Final (void *, SHA384_CTX *);
#endif /* HEIM_SHA_H */
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
-void
+int
SHA256_Init (SHA256_CTX *m)
{
m->sz[0] = 0;
F = 0x9b05688c;
G = 0x1f83d9ab;
H = 0x5be0cd19;
+ return 1;
}
static void
unsigned int b:32;
};
-void
+int
SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
{
const unsigned char *p = v;
offset = 0;
}
}
+ return 1;
}
-void
+int
SHA256_Final (void *res, SHA256_CTX *m)
{
unsigned char zeros[72];
r[4*i] = (m->counter[i] >> 24) & 0xFF;
}
}
+ return 1;
}
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
-void
+int
SHA512_Init (SHA512_CTX *m)
{
m->sz[0] = 0;
F = 0x9b05688c2b3e6c1fULL;
G = 0x1f83d9abfb41bd6bULL;
H = 0x5be0cd19137e2179ULL;
+ return 1;
}
static void
};
#endif
-void
+int
SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
{
const unsigned char *p = v;
offset = 0;
}
}
+ return 1;
}
-void
+int
SHA512_Final (void *res, SHA512_CTX *m)
{
unsigned char zeros[128 + 16];
r[8*i] = (m->counter[i] >> 56) & 0xFF;
}
}
+ return 1;
}
-void
+int
SHA384_Init(SHA384_CTX *m)
{
m->sz[0] = 0;
F = 0x8eb44a8768581511ULL;
G = 0xdb0c2e0d64f98fa7ULL;
H = 0x47b5481dbefa4fa4ULL;
+ return 1;
}
-void
+int
SHA384_Update (SHA384_CTX *m, const void *v, size_t len)
{
SHA512_Update(m, v, len);
+ return 1;
}
-void
+int
SHA384_Final (void *res, SHA384_CTX *m)
{
unsigned char data[SHA512_DIGEST_LENGTH];
SHA512_Final(data, m);
memcpy(res, data, SHA384_DIGEST_LENGTH);
+ return 1;
}
--- /dev/null
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getarg.h>
+#include <roken.h>
+
+#include <evp.h>
+#include <evp-hcrypto.h>
+#include <evp-cc.h>
+#include <evp-w32.h>
+#include <hex.h>
+#include <err.h>
+
+#ifdef WIN32
+#define STATS_START(M) \
+ LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds; \
+ LARGE_INTEGER Frequency; \
+ \
+ QueryPerformanceFrequency(&Frequency); \
+ QueryPerformanceCounter(&StartingTime);
+
+#define STATS_END(M) \
+ QueryPerformanceCounter(&EndingTime); \
+ ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; \
+ ElapsedMicroseconds.QuadPart *= 1000000; \
+ ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; \
+ \
+ M += (ElapsedMicroseconds.QuadPart - M) / (i + 1);
+#else
+#define STATS_START(M) \
+ struct timeval StartingTime, EndingTime; \
+ \
+ gettimeofday(&StartingTime, NULL);
+
+#define STATS_END(M) \
+ gettimeofday(&EndingTime, NULL); \
+ timevalsub(&EndingTime, &StartingTime); \
+ M += (EndingTime.tv_sec * 1000000 + EndingTime.tv_usec - M) / (i + 1);
+#endif
+
+static int version_flag;
+static int help_flag;
+static int len = 1;
+static int loops = 20;
+static char *provider = "hcrypto";
+static unsigned char *d;
+
+#ifdef __APPLE__
+#define PROVIDER_USAGE "hcrypto|cc"
+#elif defined(WIN32)
+#define PROVIDER_USAGE "hcrypto|w32crypto"
+#else
+#define PROVIDER_USAGE "hcrypto"
+#endif
+
+static struct getargs args[] = {
+ { "provider", 0, arg_string, &provider,
+ "crypto provider", PROVIDER_USAGE },
+ { "loops", 0, arg_integer, &loops,
+ "number of loops", "loops" },
+ { "size", 0, arg_integer, &len,
+ "size (KB)", NULL },
+ { "version", 0, arg_flag, &version_flag,
+ "print version", NULL },
+ { "help", 0, arg_flag, &help_flag,
+ NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "");
+ exit (ret);
+}
+
+static int
+test_bulk_cipher(const char *cname, const EVP_CIPHER *c)
+{
+ static unsigned char key[16];
+ static unsigned char iv[16];
+ int i;
+ int64_t M = 0;
+
+ for (i = 0; i < loops; i++) {
+ EVP_CIPHER_CTX ectx;
+ EVP_CIPHER_CTX dctx;
+
+ STATS_START(M)
+
+ EVP_CIPHER_CTX_init(&ectx);
+ EVP_CIPHER_CTX_init(&dctx);
+
+ if (EVP_CipherInit_ex(&ectx, c, NULL, NULL, NULL, 1) != 1)
+ errx(1, "can't init encrypt");
+ if (EVP_CipherInit_ex(&dctx, c, NULL, NULL, NULL, 0) != 1)
+ errx(1, "can't init decrypt");
+
+ EVP_CIPHER_CTX_set_key_length(&ectx, sizeof(key));
+ EVP_CIPHER_CTX_set_key_length(&dctx, sizeof(key));
+
+ if (EVP_CipherInit_ex(&ectx, NULL, NULL, key, iv, 1) != 1)
+ errx(1, "can't init encrypt");
+ if (EVP_CipherInit_ex(&dctx, NULL, NULL, key, iv, 0) != 1)
+ errx(1, "can't init decrypt");
+
+ if (!EVP_Cipher(&ectx, d, d, len))
+ errx(1, "can't encrypt");
+ if (!EVP_Cipher(&dctx, d, d, len))
+ errx(1, "can't decrypt");
+
+ EVP_CIPHER_CTX_cleanup(&ectx);
+ EVP_CIPHER_CTX_cleanup(&dctx);
+
+ STATS_END(M);
+
+ if (d[0] != 0x00 || d[len - 1] != ((len - 1) & 0xff))
+ errx(1, "encrypt/decrypt inconsistent");
+ }
+
+ printf("%s: mean time %llu usec%s\n", cname, M, (M == 1) ? "" : "s");
+
+ return 0;
+}
+
+static int
+test_bulk_digest(const char *cname, const EVP_MD *md)
+{
+ char digest[EVP_MAX_MD_SIZE];
+ int i;
+ unsigned int tmp = sizeof(digest);
+ int64_t M = 0;
+
+ for (i = 0; i < loops; i++) {
+ STATS_START(M);
+ EVP_Digest(d, len, digest, &tmp, md, NULL);
+ STATS_END(M);
+ }
+
+ printf("%s: mean time %llu usec%s\n", cname, M, (M == 1) ? "" : "s");
+
+ return 0;
+}
+
+static void
+test_bulk_provider_hcrypto(void)
+{
+ test_bulk_cipher("hcrypto_aes_256_cbc", EVP_hcrypto_aes_256_cbc());
+#if 0
+ test_bulk_cipher("hcrypto_aes_256_cfb8", EVP_hcrypto_aes_256_cfb8());
+#endif
+ test_bulk_cipher("hcrypto_rc4", EVP_hcrypto_rc4());
+ test_bulk_digest("hcrypto_md2", EVP_hcrypto_md2());
+ test_bulk_digest("hcrypto_md4", EVP_hcrypto_md4());
+ test_bulk_digest("hcrypto_md5", EVP_hcrypto_md5());
+ test_bulk_digest("hcrypto_sha1", EVP_hcrypto_sha1());
+ test_bulk_digest("hcrypto_sha256", EVP_hcrypto_sha256());
+ test_bulk_digest("hcrypto_sha384", EVP_hcrypto_sha384());
+ test_bulk_digest("hcrypto_sha512", EVP_hcrypto_sha512());
+}
+
+#ifdef __APPLE__
+static void
+test_bulk_provider_cc(void)
+{
+ test_bulk_cipher("cc_aes_256_cbc", EVP_cc_aes_256_cbc());
+#if 0
+ test_bulk_cipher("cc_aes_256_cfb8", EVP_cc_aes_256_cfb8());
+#endif
+ test_bulk_cipher("cc_rc4", EVP_cc_rc4());
+ test_bulk_digest("cc_md2", EVP_cc_md2());
+ test_bulk_digest("cc_md4", EVP_cc_md4());
+ test_bulk_digest("cc_md5", EVP_cc_md5());
+ test_bulk_digest("cc_sha1", EVP_cc_sha1());
+ test_bulk_digest("cc_sha256", EVP_cc_sha256());
+}
+#endif /* __APPLE__ */
+
+#ifdef WIN32
+static void
+test_bulk_provider_w32crypto(void)
+{
+ test_bulk_cipher("w32crypto_aes_256_cbc", EVP_w32crypto_aes_256_cbc());
+#if 0
+ test_bulk_cipher("w32crypto_aes_256_cfb8", EVP_w32crypto_aes_256_cfb8());
+#endif
+ test_bulk_cipher("w32crypto_rc4", EVP_w32crypto_rc4());
+ test_bulk_digest("w32crypto_md2", EVP_w32crypto_md2());
+ test_bulk_digest("w32crypto_md4", EVP_w32crypto_md4());
+ test_bulk_digest("w32crypto_md5", EVP_w32crypto_md5());
+ test_bulk_digest("w32crypto_sha1", EVP_w32crypto_sha1());
+ test_bulk_digest("w32crypto_sha256", EVP_w32crypto_sha256());
+ test_bulk_digest("w32crypto_sha384", EVP_w32crypto_sha384());
+ test_bulk_digest("w32crypto_sha512", EVP_w32crypto_sha512());
+}
+#endif /* WIN32 */
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+ int idx = 0;
+ int i;
+
+ setprogname(argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
+ usage(1);
+
+ if (help_flag)
+ usage(0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= idx;
+ argv += idx;
+
+ len *= 1024;
+
+ d = emalloc(len);
+ for (i = 0; i < len; i++)
+ d[i] = i & 0xff;
+
+ if (strcmp(provider, "hcrypto") == 0)
+ test_bulk_provider_hcrypto();
+#ifdef __APPLE__
+ else if (strcmp(provider, "cc") == 0)
+ test_bulk_provider_cc();
+#endif
+#ifdef WIN32
+ else if (strcmp(provider, "w32crypto") == 0)
+ test_bulk_provider_w32crypto();
+#endif
+ else
+ usage(1);
+
+ free(d);
+
+ return ret;
+}
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
+#include <evp-w32.h>
#include <hex.h>
#include <err.h>
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
16,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e",
+ "\x66\x16\xf9\x2e\x42\xa8\xf1\x1a\x91\x16\x68\x57\x8e\xc3\xaa\x0f",
NULL
}
};
+
+struct tests rc2_tests[] = {
+ { "rc2",
+ "\x88\xbc\xa9\x0e\x90\x87\x5a\x7f\x0f\x79\xc3\x84\x62\x7b\xaf\xb2",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x22\x69\x55\x2a\xb0\xf8\x5c\xa6",
+ NULL
+ }
+};
+
+
struct tests rc2_40_tests[] = {
{ "rc2-40",
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
d = emalloc(t->datasize);
if (!EVP_Cipher(&ectx, d, t->indata, t->datasize))
- return 1;
+ errx(1, "%s: %d EVP_Cipher encrypt failed", t->name, i);
if (memcmp(d, t->outdata, t->datasize) != 0) {
char *s, *s2;
}
if (!EVP_Cipher(&dctx, d, d, t->datasize))
- return 1;
+ errx(1, "%s: %d EVP_Cipher decrypt failed", t->name, i);
if (memcmp(d, t->indata, t->datasize) != 0) {
char *s;
ret += test_cipher(i, EVP_hcrypto_aes_256_cbc(), &aes_tests[i]);
for (i = 0; i < sizeof(aes_cfb_tests)/sizeof(aes_cfb_tests[0]); i++)
ret += test_cipher(i, EVP_hcrypto_aes_128_cfb8(), &aes_cfb_tests[i]);
-
+ for (i = 0; i < sizeof(rc2_tests)/sizeof(rc2_tests[0]); i++)
+ ret += test_cipher(i, EVP_hcrypto_rc2_cbc(), &rc2_tests[i]);
for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
ret += test_cipher(i, EVP_hcrypto_rc2_40_cbc(), &rc2_40_tests[i]);
for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
#ifdef __APPLE__
for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
ret += test_cipher(i, EVP_cc_aes_256_cbc(), &aes_tests[i]);
-#if 0
for (i = 0; i < sizeof(aes_cfb_tests)/sizeof(aes_cfb_tests[0]); i++)
ret += test_cipher(i, EVP_cc_aes_128_cfb8(), &aes_cfb_tests[i]);
-#endif
for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
ret += test_cipher(i, EVP_cc_rc2_40_cbc(), &rc2_40_tests[i]);
for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
&camellia128_tests[i]);
for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
ret += test_cipher(i, EVP_cc_rc4(), &rc4_tests[i]);
-#endif
+#endif /* __APPLE__ */
+
+ /* Windows CNG (if available) */
+#ifdef WIN32
+ for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_aes_256_cbc(), &aes_tests[i]);
+ for (i = 0; i < sizeof(aes_cfb_tests)/sizeof(aes_cfb_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_aes_128_cfb8(), &aes_cfb_tests[i]);
+ for (i = 0; i < sizeof(rc2_tests)/sizeof(rc2_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_rc2_cbc(), &rc2_tests[i]);
+ for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_rc2_40_cbc(), &rc2_40_tests[i]);
+ for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_des_ede3_cbc(), &des_ede3_tests[i]);
+ for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
+ ret += test_cipher(i, EVP_w32crypto_rc4(), &rc4_tests[i]);
+#endif /* WIN32 */
return ret;
}
hc_EVP_CIPHER_CTX_ctrl;
hc_EVP_CIPHER_CTX_rand_key;
hc_EVP_CIPHER_CTX_set_key_length;
+ hc_EVP_hcrypto_rc2_cbc;
hc_EVP_hcrypto_rc2_40_cbc;
hc_EVP_hcrypto_camellia_128_cbc;
hc_EVP_CipherUpdate;
dnsapi.lib \
shlwapi.lib
+dlllflags=$(dlllflags) /DELAYLOAD:bcrypt.dll
+DLLSDKDEPS=$(DLLSDKDEPS)\
+ bcrypt.lib \
+ delayimp.lib
+
DEF=$(OBJ)\heimdal.def
RES=$(OBJ)\heimdal-version.res
HINSTANCE _krb5_hInstance = NULL;
+#if NTDDI_VERSION >= NTDDI_VISTA
+extern BOOL WINAPI
+_hc_w32crypto_DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved);
+#endif
+
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
+#if NTDDI_VERSION >= NTDDI_VISTA
+ BOOL ret;
+
+ ret = _hc_w32crypto_DllMain(hinstDLL, fdwReason, lpvReserved);
+ if (!ret)
+ return ret;
+#endif
+
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
cincdirs=$(cincdirs) -I$(INCDIR) -I$(INCDIR)\krb5 $(pthreadinc)
cdefines=$(cdefines) -DHAVE_CONFIG_H
+# Windows CNG provider
+cdefines=$(cdefines) -DHCRYPTO_DEF_PROVIDER=w32crypto
cdebug=$(cdebug) /Zi
ldebug=$(ldebug) /DEBUG
localcflags=$(localcflags) /Oy-