bcrypt: Add support for AES encryption on macOS.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
72f3227d71
commit
20aaf167dd
|
@ -6910,7 +6910,7 @@ for ac_header in \
|
||||||
AudioUnit/AudioComponent.h \
|
AudioUnit/AudioComponent.h \
|
||||||
CL/cl.h \
|
CL/cl.h \
|
||||||
Carbon/Carbon.h \
|
Carbon/Carbon.h \
|
||||||
CommonCrypto/CommonDigest.h \
|
CommonCrypto/CommonCryptor.h \
|
||||||
CoreAudio/CoreAudio.h \
|
CoreAudio/CoreAudio.h \
|
||||||
CoreServices/CoreServices.h \
|
CoreServices/CoreServices.h \
|
||||||
DiskArbitration/DiskArbitration.h \
|
DiskArbitration/DiskArbitration.h \
|
||||||
|
|
|
@ -396,7 +396,7 @@ AC_CHECK_HEADERS(\
|
||||||
AudioUnit/AudioComponent.h \
|
AudioUnit/AudioComponent.h \
|
||||||
CL/cl.h \
|
CL/cl.h \
|
||||||
Carbon/Carbon.h \
|
Carbon/Carbon.h \
|
||||||
CommonCrypto/CommonDigest.h \
|
CommonCrypto/CommonCryptor.h \
|
||||||
CoreAudio/CoreAudio.h \
|
CoreAudio/CoreAudio.h \
|
||||||
CoreServices/CoreServices.h \
|
CoreServices/CoreServices.h \
|
||||||
DiskArbitration/DiskArbitration.h \
|
DiskArbitration/DiskArbitration.h \
|
||||||
|
|
|
@ -21,9 +21,8 @@
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
|
#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
|
||||||
#include <CommonCrypto/CommonDigest.h>
|
#include <CommonCrypto/CommonCryptor.h>
|
||||||
#include <CommonCrypto/CommonHMAC.h>
|
|
||||||
#elif defined(SONAME_LIBGNUTLS)
|
#elif defined(SONAME_LIBGNUTLS)
|
||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
#include <gnutls/crypto.h>
|
#include <gnutls/crypto.h>
|
||||||
|
@ -46,7 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
|
||||||
|
|
||||||
static HINSTANCE instance;
|
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);
|
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||||
|
|
||||||
static void *libgnutls_handle;
|
static void *libgnutls_handle;
|
||||||
|
@ -121,7 +120,7 @@ static void gnutls_uninitialize(void)
|
||||||
wine_dlclose( libgnutls_handle, NULL, 0 );
|
wine_dlclose( libgnutls_handle, NULL, 0 );
|
||||||
libgnutls_handle = NULL;
|
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,
|
NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount,
|
||||||
BCRYPT_ALGORITHM_IDENTIFIER **ppAlgList, ULONG dwFlags)
|
BCRYPT_ALGORITHM_IDENTIFIER **ppAlgList, ULONG dwFlags)
|
||||||
|
@ -731,7 +730,16 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se
|
||||||
return BCryptDestroyHash( handle );
|
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 key
|
||||||
{
|
{
|
||||||
struct object hdr;
|
struct object hdr;
|
||||||
|
@ -742,13 +750,6 @@ struct key
|
||||||
ULONG secret_len;
|
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 )
|
static NTSTATUS key_init( struct key *key, enum alg_id id, const UCHAR *secret, ULONG secret_len )
|
||||||
{
|
{
|
||||||
UCHAR *buffer;
|
UCHAR *buffer;
|
||||||
|
@ -858,6 +859,114 @@ static NTSTATUS key_destroy( struct key *key )
|
||||||
HeapFree( GetProcessHeap(), 0, key );
|
HeapFree( GetProcessHeap(), 0, key );
|
||||||
return STATUS_SUCCESS;
|
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
|
#else
|
||||||
struct key
|
struct key
|
||||||
{
|
{
|
||||||
|
@ -1066,14 +1175,14 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
instance = hinst;
|
instance = hinst;
|
||||||
DisableThreadLibraryCalls( 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();
|
gnutls_initialize();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
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();
|
gnutls_uninitialize();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -89,8 +89,8 @@
|
||||||
/* Define to 1 if you have the <CL/cl.h> header file. */
|
/* Define to 1 if you have the <CL/cl.h> header file. */
|
||||||
#undef HAVE_CL_CL_H
|
#undef HAVE_CL_CL_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
|
/* Define to 1 if you have the <CommonCrypto/CommonCryptor.h> header file. */
|
||||||
#undef HAVE_COMMONCRYPTO_COMMONDIGEST_H
|
#undef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <CoreAudio/CoreAudio.h> header file. */
|
/* Define to 1 if you have the <CoreAudio/CoreAudio.h> header file. */
|
||||||
#undef HAVE_COREAUDIO_COREAUDIO_H
|
#undef HAVE_COREAUDIO_COREAUDIO_H
|
||||||
|
|
Loading…
Reference in New Issue