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