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 @verbatim
Copyright (c) 2009, Secure Endpoints Inc. Copyright (c) 2009-2015, Secure Endpoints Inc.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

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

View File

@@ -62,6 +62,8 @@ INCFILES= \
$(HCRYPTOINCLUDEDIR)\evp.h \ $(HCRYPTOINCLUDEDIR)\evp.h \
$(HCRYPTOINCLUDEDIR)\evp-hcrypto.h \ $(HCRYPTOINCLUDEDIR)\evp-hcrypto.h \
$(HCRYPTOINCLUDEDIR)\evp-cc.h \ $(HCRYPTOINCLUDEDIR)\evp-cc.h \
$(HCRYPTOINCLUDEDIR)\evp-wincng.h \
$(HCRYPTOINCLUDEDIR)\evp-w32.h \
$(HCRYPTOINCLUDEDIR)\hmac.h \ $(HCRYPTOINCLUDEDIR)\hmac.h \
$(HCRYPTOINCLUDEDIR)\md2.h \ $(HCRYPTOINCLUDEDIR)\md2.h \
$(HCRYPTOINCLUDEDIR)\md4.h \ $(HCRYPTOINCLUDEDIR)\md4.h \
@@ -103,6 +105,8 @@ libhcrypto_OBJs = \
$(OBJ)\evp.obj \ $(OBJ)\evp.obj \
$(OBJ)\evp-hcrypto.obj \ $(OBJ)\evp-hcrypto.obj \
$(OBJ)\evp-cc.obj \ $(OBJ)\evp-cc.obj \
$(OBJ)\evp-wincng.obj \
$(OBJ)\evp-w32.obj \
$(OBJ)\engine.obj \ $(OBJ)\engine.obj \
$(OBJ)\hmac.obj \ $(OBJ)\hmac.obj \
$(OBJ)\md2.obj \ $(OBJ)\md2.obj \
@@ -150,6 +154,7 @@ test-binaries: \
$(OBJ)\rc2test.exe \ $(OBJ)\rc2test.exe \
$(OBJ)\rctest.exe \ $(OBJ)\rctest.exe \
$(OBJ)\test_bn.exe \ $(OBJ)\test_bn.exe \
$(OBJ)\test_bulk.exe \
$(OBJ)\test_cipher.exe \ $(OBJ)\test_cipher.exe \
$(OBJ)\test_engine_dso.exe \ $(OBJ)\test_engine_dso.exe \
$(OBJ)\test_hmac.exe \ $(OBJ)\test_hmac.exe \
@@ -184,6 +189,10 @@ $(OBJ)\test_bn.exe: $(OBJ)\test_bn.obj $(LIBHEIMDAL) $(LIBROKEN)
$(EXECONLINK) $(EXECONLINK)
$(EXEPREP_NODIST) $(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) $(OBJ)\test_cipher.exe: $(OBJ)\test_cipher.obj $(TESTLIB) $(LIBHEIMDAL) $(LIBROKEN) $(LIBVERS)
$(EXECONLINK) $(EXECONLINK)
$(EXEPREP_NODIST) $(EXEPREP_NODIST)
@@ -231,6 +240,7 @@ test-run:
rc2test.exe rc2test.exe
rctest.exe rctest.exe
test_bn.exe test_bn.exe
test_bulk.exe
test_cipher.exe test_cipher.exe
test_engine_dso.exe test_engine_dso.exe
test_hmac.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); CCCryptorRelease(*ref);
} }
ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref); if (key) {
if (ret) ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
return 0; if (ret)
return 0;
}
return 1; return 1;
} }
@@ -375,7 +378,8 @@ cc_aes_cfb8_init(EVP_CIPHER_CTX *ctx,
int encp) int encp)
{ {
struct cc_key *cc = ctx->cipher_data; 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, return init_cc_key(1, kCCAlgorithmAES128, kCCOptionECBMode,
key, ctx->cipher->key_len, NULL, &cc->href); key, ctx->cipher->key_len, NULL, &cc->href);
} }

View File

@@ -69,7 +69,7 @@ aes_init(EVP_CIPHER_CTX *ctx,
int encp) int encp)
{ {
AES_KEY *k = ctx->cipher_data; 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); AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
else else
AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k); 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) unsigned int size)
{ {
AES_KEY *k = ctx->cipher_data; 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); AES_cfb8_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
else else
AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt); 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.h>
#include <evp-hcrypto.h> #include <evp-hcrypto.h>
#include <evp-cc.h> #include <evp-cc.h>
#include <evp-w32.h>
#include <krb5-types.h> #include <krb5-types.h>
#include <roken.h> #include <roken.h>
@@ -175,10 +176,13 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
int int
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) HC_DEPRECATED EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) HC_DEPRECATED
{ {
if (ctx->md && ctx->md->cleanup) if (ctx->md && ctx->md->cleanup) {
(ctx->md->cleanup)(ctx); int ret = (ctx->md->cleanup)(ctx);
else if (ctx->md) if (!ret)
return ret;
} else if (ctx->md) {
memset(ctx->ptr, 0, ctx->md->ctx_size); memset(ctx->ptr, 0, ctx->md->ctx_size);
}
ctx->md = NULL; ctx->md = NULL;
ctx->engine = NULL; ctx->engine = NULL;
free(ctx->ptr); free(ctx->ptr);
@@ -258,8 +262,7 @@ EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
if (ctx->ptr == NULL) if (ctx->ptr == NULL)
return 0; return 0;
} }
(ctx->md->init)(ctx->ptr); return (ctx->md->init)(ctx->ptr);
return 1;
} }
/** /**
@@ -582,8 +585,11 @@ EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
int int
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{ {
if (c->cipher && c->cipher->cleanup) if (c->cipher && c->cipher->cleanup) {
c->cipher->cleanup(c); int ret = c->cipher->cleanup(c);
if (!ret)
return ret;
}
if (c->cipher_data) { if (c->cipher_data) {
memset(c->cipher_data, 0, c->cipher->ctx_size); memset(c->cipher_data, 0, c->cipher->ctx_size);
free(c->cipher_data); 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)) 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; return 1;
} }

View File

@@ -175,6 +175,26 @@ EXPORTS
;! hc_EVP_cc_aes_192_cfb8 ;! hc_EVP_cc_aes_192_cfb8
;! hc_EVP_cc_aes_256_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_md2
hc_EVP_hcrypto_md4 hc_EVP_hcrypto_md4
hc_EVP_hcrypto_md5 hc_EVP_hcrypto_md5
@@ -284,6 +304,7 @@ EXPORTS
hc_EVP_CIPHER_CTX_ctrl hc_EVP_CIPHER_CTX_ctrl
hc_EVP_CIPHER_CTX_rand_key hc_EVP_CIPHER_CTX_rand_key
hc_EVP_CIPHER_CTX_set_key_length hc_EVP_CIPHER_CTX_set_key_length
hc_EVP_hcrypto_rc2_cbc
hc_EVP_hcrypto_rc2_40_cbc hc_EVP_hcrypto_rc2_40_cbc
hc_EVP_hcrypto_camellia_128_cbc hc_EVP_hcrypto_camellia_128_cbc
hc_EVP_CipherUpdate 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 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
}; };
void int
MD2_Init (struct md2 *m) MD2_Init (struct md2 *m)
{ {
memset(m, 0, sizeof(*m)); memset(m, 0, sizeof(*m));
return 1;
} }
static void static void
@@ -91,7 +92,7 @@ calc(struct md2 *m, const void *v)
memset(x, 0, sizeof(x)); memset(x, 0, sizeof(x));
} }
void int
MD2_Update (struct md2 *m, const void *v, size_t len) MD2_Update (struct md2 *m, const void *v, size_t len)
{ {
size_t idx = m->len & 0xf; 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); memcpy(m->data + idx, p, len);
return 1;
} }
void int
MD2_Final (void *res, struct md2 *m) MD2_Final (void *res, struct md2 *m)
{ {
unsigned char pad[16]; unsigned char pad[16];
@@ -131,4 +133,5 @@ MD2_Final (void *res, struct md2 *m)
memcpy(res, m->state, MD2_DIGEST_LENGTH); memcpy(res, m->state, MD2_DIGEST_LENGTH);
memset(m, 0, sizeof(*m)); memset(m, 0, sizeof(*m));
return 1;
} }

View File

@@ -56,8 +56,8 @@ struct md2 {
typedef struct md2 MD2_CTX; typedef struct md2 MD2_CTX;
void MD2_Init (struct md2 *m); int MD2_Init (struct md2 *m);
void MD2_Update (struct md2 *m, const void *p, size_t len); int MD2_Update (struct md2 *m, const void *p, size_t len);
void MD2_Final (void *res, struct md2 *m); int MD2_Final (void *res, struct md2 *m);
#endif /* HEIM_MD2_H */ #endif /* HEIM_MD2_H */

View File

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

View File

@@ -55,8 +55,8 @@ struct md4 {
typedef struct md4 MD4_CTX; typedef struct md4 MD4_CTX;
void MD4_Init (struct md4 *m); int MD4_Init (struct md4 *m);
void MD4_Update (struct md4 *m, const void *p, size_t len); int MD4_Update (struct md4 *m, const void *p, size_t len);
void MD4_Final (void *res, struct md4 *m); int MD4_Final (void *res, struct md4 *m);
#endif /* HEIM_MD4_H */ #endif /* HEIM_MD4_H */

View File

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

View File

@@ -55,8 +55,8 @@ struct md5 {
typedef struct md5 MD5_CTX; typedef struct md5 MD5_CTX;
void MD5_Init (struct md5 *m); int MD5_Init (struct md5 *m);
void MD5_Update (struct md5 *m, const void *p, size_t len); int 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_Final (void *res, struct md5 *m); /* uint32_t res[4] */
#endif /* HEIM_MD5_H */ #endif /* HEIM_MD5_H */

View File

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

View File

@@ -64,9 +64,9 @@ struct sha {
typedef struct sha SHA_CTX; typedef struct sha SHA_CTX;
void SHA1_Init (struct sha *m); int SHA1_Init (struct sha *m);
void SHA1_Update (struct sha *m, const void *v, size_t len); int SHA1_Update (struct sha *m, const void *v, size_t len);
void SHA1_Final (void *res, struct sha *m); int SHA1_Final (void *res, struct sha *m);
/* /*
* SHA-2 256 * SHA-2 256
@@ -82,9 +82,9 @@ struct hc_sha256state {
typedef struct hc_sha256state SHA256_CTX; typedef struct hc_sha256state SHA256_CTX;
void SHA256_Init (SHA256_CTX *); int SHA256_Init (SHA256_CTX *);
void SHA256_Update (SHA256_CTX *, const void *, size_t); int SHA256_Update (SHA256_CTX *, const void *, size_t);
void SHA256_Final (void *, SHA256_CTX *); int SHA256_Final (void *, SHA256_CTX *);
/* /*
* SHA-2 512 * SHA-2 512
@@ -100,16 +100,16 @@ struct hc_sha512state {
typedef struct hc_sha512state SHA512_CTX; typedef struct hc_sha512state SHA512_CTX;
void SHA512_Init (SHA512_CTX *); int SHA512_Init (SHA512_CTX *);
void SHA512_Update (SHA512_CTX *, const void *, size_t); int SHA512_Update (SHA512_CTX *, const void *, size_t);
void SHA512_Final (void *, SHA512_CTX *); int SHA512_Final (void *, SHA512_CTX *);
#define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_LENGTH 48
typedef struct hc_sha512state SHA384_CTX; typedef struct hc_sha512state SHA384_CTX;
void SHA384_Init (SHA384_CTX *); int SHA384_Init (SHA384_CTX *);
void SHA384_Update (SHA384_CTX *, const void *, size_t); int SHA384_Update (SHA384_CTX *, const void *, size_t);
void SHA384_Final (void *, SHA384_CTX *); int SHA384_Final (void *, SHA384_CTX *);
#endif /* HEIM_SHA_H */ #endif /* HEIM_SHA_H */

View File

@@ -74,7 +74,7 @@ static const uint32_t constant_256[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
}; };
void int
SHA256_Init (SHA256_CTX *m) SHA256_Init (SHA256_CTX *m)
{ {
m->sz[0] = 0; m->sz[0] = 0;
@@ -87,6 +87,7 @@ SHA256_Init (SHA256_CTX *m)
F = 0x9b05688c; F = 0x9b05688c;
G = 0x1f83d9ab; G = 0x1f83d9ab;
H = 0x5be0cd19; H = 0x5be0cd19;
return 1;
} }
static void static void
@@ -162,7 +163,7 @@ struct x32{
unsigned int b:32; unsigned int b:32;
}; };
void int
SHA256_Update (SHA256_CTX *m, const void *v, size_t len) SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
{ {
const unsigned char *p = v; const unsigned char *p = v;
@@ -195,9 +196,10 @@ SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
offset = 0; offset = 0;
} }
} }
return 1;
} }
void int
SHA256_Final (void *res, SHA256_CTX *m) SHA256_Final (void *res, SHA256_CTX *m)
{ {
unsigned char zeros[72]; unsigned char zeros[72];
@@ -226,4 +228,5 @@ SHA256_Final (void *res, SHA256_CTX *m)
r[4*i] = (m->counter[i] >> 24) & 0xFF; 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 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
}; };
void int
SHA512_Init (SHA512_CTX *m) SHA512_Init (SHA512_CTX *m)
{ {
m->sz[0] = 0; m->sz[0] = 0;
@@ -111,6 +111,7 @@ SHA512_Init (SHA512_CTX *m)
F = 0x9b05688c2b3e6c1fULL; F = 0x9b05688c2b3e6c1fULL;
G = 0x1f83d9abfb41bd6bULL; G = 0x1f83d9abfb41bd6bULL;
H = 0x5be0cd19137e2179ULL; H = 0x5be0cd19137e2179ULL;
return 1;
} }
static void static void
@@ -184,7 +185,7 @@ struct x64{
}; };
#endif #endif
void int
SHA512_Update (SHA512_CTX *m, const void *v, size_t len) SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
{ {
const unsigned char *p = v; const unsigned char *p = v;
@@ -217,9 +218,10 @@ SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
offset = 0; offset = 0;
} }
} }
return 1;
} }
void int
SHA512_Final (void *res, SHA512_CTX *m) SHA512_Final (void *res, SHA512_CTX *m)
{ {
unsigned char zeros[128 + 16]; unsigned char zeros[128 + 16];
@@ -261,9 +263,10 @@ SHA512_Final (void *res, SHA512_CTX *m)
r[8*i] = (m->counter[i] >> 56) & 0xFF; r[8*i] = (m->counter[i] >> 56) & 0xFF;
} }
} }
return 1;
} }
void int
SHA384_Init(SHA384_CTX *m) SHA384_Init(SHA384_CTX *m)
{ {
m->sz[0] = 0; m->sz[0] = 0;
@@ -276,19 +279,22 @@ SHA384_Init(SHA384_CTX *m)
F = 0x8eb44a8768581511ULL; F = 0x8eb44a8768581511ULL;
G = 0xdb0c2e0d64f98fa7ULL; G = 0xdb0c2e0d64f98fa7ULL;
H = 0x47b5481dbefa4fa4ULL; H = 0x47b5481dbefa4fa4ULL;
return 1;
} }
void int
SHA384_Update (SHA384_CTX *m, const void *v, size_t len) SHA384_Update (SHA384_CTX *m, const void *v, size_t len)
{ {
SHA512_Update(m, v, len); SHA512_Update(m, v, len);
return 1;
} }
void int
SHA384_Final (void *res, SHA384_CTX *m) SHA384_Final (void *res, SHA384_CTX *m)
{ {
unsigned char data[SHA512_DIGEST_LENGTH]; unsigned char data[SHA512_DIGEST_LENGTH];
SHA512_Final(data, m); SHA512_Final(data, m);
memcpy(res, data, SHA384_DIGEST_LENGTH); 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.h>
#include <evp-hcrypto.h> #include <evp-hcrypto.h>
#include <evp-cc.h> #include <evp-cc.h>
#include <evp-w32.h>
#include <hex.h> #include <hex.h>
#include <err.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", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
16, 16,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\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 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[] = { struct tests rc2_40_tests[] = {
{ "rc2-40", { "rc2-40",
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\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); d = emalloc(t->datasize);
if (!EVP_Cipher(&ectx, d, t->indata, 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) { if (memcmp(d, t->outdata, t->datasize) != 0) {
char *s, *s2; 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)) 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) { if (memcmp(d, t->indata, t->datasize) != 0) {
char *s; char *s;
@@ -338,7 +353,8 @@ main(int argc, char **argv)
ret += test_cipher(i, EVP_hcrypto_aes_256_cbc(), &aes_tests[i]); 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++) 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]); 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++) 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]); 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++) 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__ #ifdef __APPLE__
for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++) for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
ret += test_cipher(i, EVP_cc_aes_256_cbc(), &aes_tests[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++) 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]); 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++) 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]); 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++) 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]); &camellia128_tests[i]);
for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++) for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
ret += test_cipher(i, EVP_cc_rc4(), &rc4_tests[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; return ret;
} }

View File

@@ -289,6 +289,7 @@ HEIMDAL_CRYPTO_1.0 {
hc_EVP_CIPHER_CTX_ctrl; hc_EVP_CIPHER_CTX_ctrl;
hc_EVP_CIPHER_CTX_rand_key; hc_EVP_CIPHER_CTX_rand_key;
hc_EVP_CIPHER_CTX_set_key_length; hc_EVP_CIPHER_CTX_set_key_length;
hc_EVP_hcrypto_rc2_cbc;
hc_EVP_hcrypto_rc2_40_cbc; hc_EVP_hcrypto_rc2_40_cbc;
hc_EVP_hcrypto_camellia_128_cbc; hc_EVP_hcrypto_camellia_128_cbc;
hc_EVP_CipherUpdate; hc_EVP_CipherUpdate;

View File

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

View File

@@ -33,10 +33,25 @@
HINSTANCE _krb5_hInstance = NULL; 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, BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason, DWORD fdwReason,
LPVOID lpvReserved) LPVOID lpvReserved)
{ {
#if NTDDI_VERSION >= NTDDI_VISTA
BOOL ret;
ret = _hc_w32crypto_DllMain(hinstDLL, fdwReason, lpvReserved);
if (!ret)
return ret;
#endif
switch (fdwReason) { switch (fdwReason) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:

View File

@@ -162,6 +162,8 @@ pthreadinc= -I$(PTHREAD_INC)
cincdirs=$(cincdirs) -I$(INCDIR) -I$(INCDIR)\krb5 $(pthreadinc) cincdirs=$(cincdirs) -I$(INCDIR) -I$(INCDIR)\krb5 $(pthreadinc)
cdefines=$(cdefines) -DHAVE_CONFIG_H cdefines=$(cdefines) -DHAVE_CONFIG_H
# Windows CNG provider
cdefines=$(cdefines) -DHCRYPTO_DEF_PROVIDER=w32crypto
cdebug=$(cdebug) /Zi cdebug=$(cdebug) /Zi
ldebug=$(ldebug) /DEBUG ldebug=$(ldebug) /DEBUG
localcflags=$(localcflags) /Oy- localcflags=$(localcflags) /Oy-