Add Windows CNG (BCrypt) support to HCrypto EVP API

This commit is contained in:
Luke Howard
2015-02-06 16:26:08 +11:00
parent 49861eb2c5
commit 5023f55208
28 changed files with 1517 additions and 113 deletions

View File

@@ -443,7 +443,7 @@ Windows support
@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

View File

@@ -60,6 +60,7 @@ PROGRAM_TESTS = \
rc2test \
rctest \
test_bn \
test_bulk \
test_cipher \
test_engine_dso \
test_hmac \

View File

@@ -62,6 +62,8 @@ INCFILES= \
$(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 \
@@ -103,6 +105,8 @@ libhcrypto_OBJs = \
$(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 \
@@ -150,6 +154,7 @@ test-binaries: \
$(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 \
@@ -184,6 +189,10 @@ $(OBJ)\test_bn.exe: $(OBJ)\test_bn.obj $(LIBHEIMDAL) $(LIBROKEN)
$(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)
@@ -231,6 +240,7 @@ test-run:
rc2test.exe
rctest.exe
test_bn.exe
test_bulk.exe
test_cipher.exe
test_engine_dso.exe
test_hmac.exe

View File

@@ -1,49 +0,0 @@
/*
* 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;
}
}

View File

@@ -148,9 +148,12 @@ init_cc_key(int encp, CCAlgorithm alg, CCOptions opts, const void *key,
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;
}
@@ -375,7 +378,8 @@ cc_aes_cfb8_init(EVP_CIPHER_CTX *ctx,
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);
}

View File

@@ -69,7 +69,7 @@ aes_init(EVP_CIPHER_CTX *ctx,
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);
@@ -83,7 +83,7 @@ aes_do_cipher(EVP_CIPHER_CTX *ctx,
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);

147
lib/hcrypto/evp-w32.c Normal file
View File

@@ -0,0 +1,147 @@
/*
* 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)

100
lib/hcrypto/evp-w32.h Normal file
View File

@@ -0,0 +1,100 @@
/*
* 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 */

710
lib/hcrypto/evp-wincng.c Normal file
View File

@@ -0,0 +1,710 @@
/*
* 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 */

97
lib/hcrypto/evp-wincng.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* 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 */

View File

@@ -47,6 +47,7 @@
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
#include <evp-w32.h>
#include <krb5-types.h>
#include <roken.h>
@@ -175,10 +176,13 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
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);
@@ -258,8 +262,7 @@ EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
if (ctx->ptr == NULL)
return 0;
}
(ctx->md->init)(ctx->ptr);
return 1;
return (ctx->md->init)(ctx->ptr);
}
/**
@@ -582,8 +585,11 @@ EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
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);
@@ -814,7 +820,7 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
}
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;
}

View File

@@ -175,6 +175,26 @@ EXPORTS
;! 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
@@ -284,6 +304,7 @@ EXPORTS
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

View File

@@ -57,10 +57,11 @@ static const unsigned char subst[256] = {
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
@@ -91,7 +92,7 @@ calc(struct md2 *m, const void *v)
memset(x, 0, sizeof(x));
}
void
int
MD2_Update (struct md2 *m, const void *v, size_t len)
{
size_t idx = m->len & 0xf;
@@ -114,9 +115,10 @@ MD2_Update (struct md2 *m, const void *v, size_t len)
}
memcpy(m->data + idx, p, len);
return 1;
}
void
int
MD2_Final (void *res, struct md2 *m)
{
unsigned char pad[16];
@@ -131,4 +133,5 @@ MD2_Final (void *res, struct md2 *m)
memcpy(res, m->state, MD2_DIGEST_LENGTH);
memset(m, 0, sizeof(*m));
return 1;
}

View File

@@ -56,8 +56,8 @@ struct md2 {
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 */

View File

@@ -42,7 +42,7 @@
#define D m->counter[3]
#define X data
void
int
MD4_Init (struct md4 *m)
{
m->sz[0] = 0;
@@ -51,6 +51,7 @@ MD4_Init (struct md4 *m)
C = 0x98badcfe;
B = 0xefcdab89;
A = 0x67452301;
return 1;
}
#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
@@ -170,7 +171,7 @@ struct x32{
unsigned int b:32;
};
void
int
MD4_Update (struct md4 *m, const void *v, size_t len)
{
const unsigned char *p = v;
@@ -203,9 +204,10 @@ MD4_Update (struct md4 *m, const void *v, size_t len)
offset = 0;
}
}
return 1;
}
void
int
MD4_Final (void *res, struct md4 *m)
{
unsigned char zeros[72];
@@ -243,4 +245,5 @@ MD4_Final (void *res, struct md4 *m)
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
return 1;
}

View File

@@ -55,8 +55,8 @@ struct md4 {
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 */

View File

@@ -42,7 +42,7 @@
#define D m->counter[3]
#define X data
void
int
MD5_Init (struct md5 *m)
{
m->sz[0] = 0;
@@ -51,6 +51,7 @@ MD5_Init (struct md5 *m)
C = 0x98badcfe;
B = 0xefcdab89;
A = 0x67452301;
return 1;
}
#define F(x,y,z) CRAYFIX((x & y) | (~x & z))
@@ -194,7 +195,7 @@ struct x32{
unsigned int b:32;
};
void
int
MD5_Update (struct md5 *m, const void *v, size_t len)
{
const unsigned char *p = v;
@@ -227,9 +228,10 @@ MD5_Update (struct md5 *m, const void *v, size_t len)
offset = 0;
}
}
return 1;
}
void
int
MD5_Final (void *res, struct md5 *m)
{
unsigned char zeros[72];
@@ -267,4 +269,5 @@ MD5_Final (void *res, struct md5 *m)
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
return 1;
}

View File

@@ -55,8 +55,8 @@ struct md5 {
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 */

View File

@@ -43,7 +43,7 @@
#define E m->counter[4]
#define X data
void
int
SHA1_Init (struct sha *m)
{
m->sz[0] = 0;
@@ -53,6 +53,7 @@ SHA1_Init (struct sha *m)
C = 0x98badcfe;
D = 0x10325476;
E = 0xc3d2e1f0;
return 1;
}
@@ -220,7 +221,7 @@ struct x32{
unsigned int b:32;
};
void
int
SHA1_Update (struct sha *m, const void *v, size_t len)
{
const unsigned char *p = v;
@@ -253,9 +254,10 @@ SHA1_Update (struct sha *m, const void *v, size_t len)
offset = 0;
}
}
return 1;
}
void
int
SHA1_Final (void *res, struct sha *m)
{
unsigned char zeros[72];
@@ -293,4 +295,5 @@ SHA1_Final (void *res, struct sha *m)
r[i] = swap_uint32_t (m->counter[i]);
}
#endif
return 1;
}

View File

@@ -64,9 +64,9 @@ struct sha {
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
@@ -82,9 +82,9 @@ struct hc_sha256state {
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
@@ -100,16 +100,16 @@ struct hc_sha512state {
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 */

View File

@@ -74,7 +74,7 @@ static const uint32_t constant_256[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
void
int
SHA256_Init (SHA256_CTX *m)
{
m->sz[0] = 0;
@@ -87,6 +87,7 @@ SHA256_Init (SHA256_CTX *m)
F = 0x9b05688c;
G = 0x1f83d9ab;
H = 0x5be0cd19;
return 1;
}
static void
@@ -162,7 +163,7 @@ struct x32{
unsigned int b:32;
};
void
int
SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
{
const unsigned char *p = v;
@@ -195,9 +196,10 @@ SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
offset = 0;
}
}
return 1;
}
void
int
SHA256_Final (void *res, SHA256_CTX *m)
{
unsigned char zeros[72];
@@ -226,4 +228,5 @@ SHA256_Final (void *res, SHA256_CTX *m)
r[4*i] = (m->counter[i] >> 24) & 0xFF;
}
}
return 1;
}

View File

@@ -98,7 +98,7 @@ static const uint64_t constant_512[80] = {
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
void
int
SHA512_Init (SHA512_CTX *m)
{
m->sz[0] = 0;
@@ -111,6 +111,7 @@ SHA512_Init (SHA512_CTX *m)
F = 0x9b05688c2b3e6c1fULL;
G = 0x1f83d9abfb41bd6bULL;
H = 0x5be0cd19137e2179ULL;
return 1;
}
static void
@@ -184,7 +185,7 @@ struct x64{
};
#endif
void
int
SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
{
const unsigned char *p = v;
@@ -217,9 +218,10 @@ SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
offset = 0;
}
}
return 1;
}
void
int
SHA512_Final (void *res, SHA512_CTX *m)
{
unsigned char zeros[128 + 16];
@@ -261,9 +263,10 @@ SHA512_Final (void *res, SHA512_CTX *m)
r[8*i] = (m->counter[i] >> 56) & 0xFF;
}
}
return 1;
}
void
int
SHA384_Init(SHA384_CTX *m)
{
m->sz[0] = 0;
@@ -276,19 +279,22 @@ SHA384_Init(SHA384_CTX *m)
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;
}

283
lib/hcrypto/test_bulk.c Normal file
View File

@@ -0,0 +1,283 @@
/*
* 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;
}

View File

@@ -46,6 +46,7 @@
#include <evp.h>
#include <evp-hcrypto.h>
#include <evp-cc.h>
#include <evp-w32.h>
#include <hex.h>
#include <err.h>
@@ -80,11 +81,25 @@ struct tests aes_cfb_tests[] = {
"\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",
@@ -264,7 +279,7 @@ test_cipher(int i, const EVP_CIPHER *c, struct tests *t)
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;
@@ -274,7 +289,7 @@ test_cipher(int i, const EVP_CIPHER *c, struct tests *t)
}
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;
@@ -338,7 +353,8 @@ main(int argc, char **argv)
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++)
@@ -353,10 +369,8 @@ main(int argc, char **argv)
#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++)
@@ -366,7 +380,23 @@ main(int argc, char **argv)
&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;
}

View File

@@ -289,6 +289,7 @@ HEIMDAL_CRYPTO_1.0 {
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;

View File

@@ -54,6 +54,11 @@ DLLSDKDEPS= \
dnsapi.lib \
shlwapi.lib
dlllflags=$(dlllflags) /DELAYLOAD:bcrypt.dll
DLLSDKDEPS=$(DLLSDKDEPS)\
bcrypt.lib \
delayimp.lib
DEF=$(OBJ)\heimdal.def
RES=$(OBJ)\heimdal-version.res

View File

@@ -33,10 +33,25 @@
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:

View File

@@ -162,6 +162,8 @@ pthreadinc= -I$(PTHREAD_INC)
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-