Signed-off-by: Hans Leidekker hans@codeweavers.com --- configure.ac | 2 +- dlls/bcrypt/bcrypt_main.c | 139 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac index 5d0f4cb6fe..fce97f85d3 100644 --- a/configure.ac +++ b/configure.ac @@ -397,7 +397,7 @@ AC_CHECK_HEADERS(\ AudioUnit/AudioComponent.h \ CL/cl.h \ Carbon/Carbon.h \ - CommonCrypto/CommonDigest.h \ + CommonCrypto/CommonCryptor.h \ CoreAudio/CoreAudio.h \ CoreServices/CoreServices.h \ DiskArbitration/DiskArbitration.h \ diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 931db2be99..765f7589be 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -21,9 +21,8 @@ #include "wine/port.h"
#include <stdarg.h> -#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H -#include <CommonCrypto/CommonDigest.h> -#include <CommonCrypto/CommonHMAC.h> +#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H +#include <CommonCrypto/CommonCryptor.h> #elif defined(SONAME_LIBGNUTLS) #include <gnutls/gnutls.h> #include <gnutls/crypto.h> @@ -46,7 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
static HINSTANCE instance;
-#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) WINE_DECLARE_DEBUG_CHANNEL(winediag);
static void *libgnutls_handle; @@ -121,7 +120,7 @@ static void gnutls_uninitialize(void) wine_dlclose( libgnutls_handle, NULL, 0 ); libgnutls_handle = NULL; } -#endif /* HAVE_GNUTLS_CIPHER_INIT && !HAVE_COMMONCRYPTO_COMMONDIGEST_H */ +#endif /* HAVE_GNUTLS_CIPHER_INIT && !HAVE_COMMONCRYPTO_COMMONCRYPTOR_H */
NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount, BCRYPT_ALGORITHM_IDENTIFIER **ppAlgList, ULONG dwFlags) @@ -731,7 +730,16 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se return BCryptDestroyHash( handle ); }
-#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +#if defined(HAVE_GNUTLS_CIPHER_INIT) || defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) +static ULONG get_block_size( enum alg_id alg ) +{ + ULONG ret = 0, size = sizeof(ret); + get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size ); + return ret; +} +#endif + +#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) struct key { struct object hdr; @@ -742,13 +750,6 @@ struct key ULONG secret_len; };
-static ULONG get_block_size( enum alg_id alg ) -{ - ULONG ret = 0, size = sizeof(ret); - get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size ); - return ret; -} - static NTSTATUS key_init( struct key *key, enum alg_id id, const UCHAR *secret, ULONG secret_len ) { UCHAR *buffer; @@ -858,6 +859,114 @@ static NTSTATUS key_destroy( struct key *key ) HeapFree( GetProcessHeap(), 0, key ); return STATUS_SUCCESS; } +#elif defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) +struct key +{ + struct object hdr; + enum alg_id alg_id; + ULONG block_size; + CCCryptorRef ref_encrypt; + CCCryptorRef ref_decrypt; + UCHAR *secret; + ULONG secret_len; +}; + +static NTSTATUS key_init( struct key *key, enum alg_id id, const UCHAR *secret, ULONG secret_len ) +{ + UCHAR *buffer; + + switch (id) + { + case ALG_ID_AES: + break; + + default: + FIXME( "algorithm %u not supported\n", id ); + return STATUS_NOT_SUPPORTED; + } + + if (!(key->block_size = get_block_size( id ))) return STATUS_INVALID_PARAMETER; + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, secret_len ))) return STATUS_NO_MEMORY; + memcpy( buffer, secret, secret_len ); + + key->alg_id = id; + key->ref_encrypt = NULL; /* initialized on first use */ + key->ref_decrypt = NULL; + key->secret = buffer; + key->secret_len = secret_len; + + return STATUS_SUCCESS; +} + +static NTSTATUS key_set_params( struct key *key, UCHAR *iv, ULONG iv_len ) +{ + CCCryptorStatus status; + + if (key->ref_encrypt) + { + CCCryptorRelease( key->ref_encrypt ); + key->ref_encrypt = NULL; + } + if (key->ref_decrypt) + { + CCCryptorRelease( key->ref_decrypt ); + key->ref_decrypt = NULL; + } + + if ((status = CCCryptorCreateWithMode( kCCEncrypt, kCCModeCBC, kCCAlgorithmAES, ccNoPadding, iv, + key->secret, key->secret_len, NULL, 0, 0, 0, &key->ref_encrypt )) != kCCSuccess) + { + WARN( "CCCryptorCreateWithMode failed %d\n", status ); + return STATUS_INTERNAL_ERROR; + } + if ((status = CCCryptorCreateWithMode( kCCDecrypt, kCCModeCBC, kCCAlgorithmAES, ccNoPadding, iv, + key->secret, key->secret_len, NULL, 0, 0, 0, &key->ref_decrypt )) != kCCSuccess) + { + WARN( "CCCryptorCreateWithMode failed %d\n", status ); + CCCryptorRelease( key->ref_encrypt ); + key->ref_encrypt = NULL; + return STATUS_INTERNAL_ERROR; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS key_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, + ULONG output_len ) +{ + CCCryptorStatus status; + + if ((status = CCCryptorUpdate( key->ref_encrypt, input, input_len, output, output_len, NULL )) != kCCSuccess) + { + WARN( "CCCryptorUpdate failed %d\n", status ); + return STATUS_INTERNAL_ERROR; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS key_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, + ULONG output_len ) +{ + CCCryptorStatus status; + + if ((status = CCCryptorUpdate( key->ref_decrypt, input, input_len, output, output_len, NULL )) != kCCSuccess) + { + WARN( "CCCryptorUpdate failed %d\n", status ); + return STATUS_INTERNAL_ERROR; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS key_destroy( struct key *key ) +{ + if (key->ref_encrypt) CCCryptorRelease( key->ref_encrypt ); + if (key->ref_decrypt) CCCryptorRelease( key->ref_decrypt ); + HeapFree( GetProcessHeap(), 0, key->secret ); + HeapFree( GetProcessHeap(), 0, key ); + return STATUS_SUCCESS; +} #else struct key { @@ -1066,14 +1175,14 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) case DLL_PROCESS_ATTACH: instance = hinst; DisableThreadLibraryCalls( hinst ); -#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) gnutls_initialize(); #endif break;
case DLL_PROCESS_DETACH: if (reserved) break; -#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +#if defined(HAVE_GNUTLS_CIPHER_INIT) && !defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) gnutls_uninitialize(); #endif break;