Hans Leidekker : bcrypt: Add support for AES encryption on macOS.
Alexandre Julliard
julliard at winehq.org
Fri Dec 8 13:51:29 CST 2017
Module: wine
Branch: master
Commit: 20aaf167dd9f23fa68ff12984f24a2335dd94c03
URL: http://source.winehq.org/git/wine.git/?a=commit;h=20aaf167dd9f23fa68ff12984f24a2335dd94c03
Author: Hans Leidekker <hans at codeweavers.com>
Date: Fri Dec 8 09:17:31 2017 +0100
bcrypt: Add support for AES encryption on macOS.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
configure | 2 +-
configure.ac | 2 +-
dlls/bcrypt/bcrypt_main.c | 139 +++++++++++++++++++++++++++++++++++++++++-----
include/config.h.in | 4 +-
4 files changed, 128 insertions(+), 19 deletions(-)
diff --git a/configure b/configure
index 4704e16..5e1eeef 100755
--- a/configure
+++ b/configure
@@ -6910,7 +6910,7 @@ for ac_header in \
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/configure.ac b/configure.ac
index 69fad41..8d9ec29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -396,7 +396,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 931db2b..765f758 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;
diff --git a/include/config.h.in b/include/config.h.in
index a6ec41b..aff5f35 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -89,8 +89,8 @@
/* Define to 1 if you have the <CL/cl.h> header file. */
#undef HAVE_CL_CL_H
-/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
-#undef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+/* Define to 1 if you have the <CommonCrypto/CommonCryptor.h> header file. */
+#undef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
/* Define to 1 if you have the <CoreAudio/CoreAudio.h> header file. */
#undef HAVE_COREAUDIO_COREAUDIO_H
More information about the wine-cvs
mailing list