bcrypt: Move macOS support to a new file.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
018b695efa
commit
d265dd88cd
|
@ -6,6 +6,7 @@ EXTRAINCL = $(GNUTLS_CFLAGS)
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
bcrypt_main.c \
|
bcrypt_main.c \
|
||||||
gnutls.c \
|
gnutls.c \
|
||||||
|
macos.c \
|
||||||
md2.c \
|
md2.c \
|
||||||
sha256.c \
|
sha256.c \
|
||||||
sha512.c
|
sha512.c
|
||||||
|
|
|
@ -815,186 +815,6 @@ void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
|
||||||
NTSTATUS key_set_property( struct key *key, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
|
|
||||||
{
|
|
||||||
if (!strcmpW( prop, BCRYPT_CHAINING_MODE ))
|
|
||||||
{
|
|
||||||
if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_ECB, size ))
|
|
||||||
{
|
|
||||||
key->u.s.mode = MODE_ID_ECB;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC, size ))
|
|
||||||
{
|
|
||||||
key->u.s.mode = MODE_ID_CBC;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FIXME( "unsupported mode %s\n", debugstr_wn( (WCHAR *)value, size ) );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME( "unsupported key property %s\n", debugstr_w(prop) );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG get_block_size( struct algorithm *alg )
|
|
||||||
{
|
|
||||||
ULONG ret = 0, size = sizeof(ret);
|
|
||||||
get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_init( struct key *key, struct algorithm *alg, const UCHAR *secret, ULONG secret_len )
|
|
||||||
{
|
|
||||||
UCHAR *buffer;
|
|
||||||
|
|
||||||
switch (alg->id)
|
|
||||||
{
|
|
||||||
case ALG_ID_AES:
|
|
||||||
switch (alg->mode)
|
|
||||||
{
|
|
||||||
case MODE_ID_ECB:
|
|
||||||
case MODE_ID_CBC:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FIXME( "mode %u not supported\n", alg->mode );
|
|
||||||
return STATUS_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME( "algorithm %u not supported\n", alg->id );
|
|
||||||
return STATUS_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(key->u.s.block_size = get_block_size( alg ))) return STATUS_INVALID_PARAMETER;
|
|
||||||
if (!(buffer = heap_alloc( secret_len ))) return STATUS_NO_MEMORY;
|
|
||||||
memcpy( buffer, secret, secret_len );
|
|
||||||
|
|
||||||
key->alg_id = alg->id;
|
|
||||||
key->u.s.mode = alg->mode;
|
|
||||||
key->u.s.ref_encrypt = NULL; /* initialized on first use */
|
|
||||||
key->u.s.ref_decrypt = NULL;
|
|
||||||
key->u.s.secret = buffer;
|
|
||||||
key->u.s.secret_len = secret_len;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CCMode get_cryptor_mode( struct key *key )
|
|
||||||
{
|
|
||||||
switch (key->u.s.mode)
|
|
||||||
{
|
|
||||||
case MODE_ID_ECB: return kCCModeECB;
|
|
||||||
case MODE_ID_CBC: return kCCModeCBC;
|
|
||||||
default:
|
|
||||||
FIXME( "unsupported mode %u\n", key->u.s.mode );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_set_params( struct key *key, UCHAR *iv, ULONG iv_len )
|
|
||||||
{
|
|
||||||
CCCryptorStatus status;
|
|
||||||
CCMode mode;
|
|
||||||
|
|
||||||
if (!(mode = get_cryptor_mode( key ))) return STATUS_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
if (key->u.s.ref_encrypt)
|
|
||||||
{
|
|
||||||
CCCryptorRelease( key->u.s.ref_encrypt );
|
|
||||||
key->u.s.ref_encrypt = NULL;
|
|
||||||
}
|
|
||||||
if (key->u.s.ref_decrypt)
|
|
||||||
{
|
|
||||||
CCCryptorRelease( key->u.s.ref_decrypt );
|
|
||||||
key->u.s.ref_decrypt = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status = CCCryptorCreateWithMode( kCCEncrypt, mode, kCCAlgorithmAES128, ccNoPadding, iv, key->u.s.secret,
|
|
||||||
key->u.s.secret_len, NULL, 0, 0, 0, &key->u.s.ref_encrypt )) != kCCSuccess)
|
|
||||||
{
|
|
||||||
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
|
||||||
return STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
if ((status = CCCryptorCreateWithMode( kCCDecrypt, mode, kCCAlgorithmAES128, ccNoPadding, iv, key->u.s.secret,
|
|
||||||
key->u.s.secret_len, NULL, 0, 0, 0, &key->u.s.ref_decrypt )) != kCCSuccess)
|
|
||||||
{
|
|
||||||
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
|
||||||
CCCryptorRelease( key->u.s.ref_encrypt );
|
|
||||||
key->u.s.ref_encrypt = NULL;
|
|
||||||
return STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_set_auth_data( struct key *key, UCHAR *auth_data, ULONG len )
|
|
||||||
{
|
|
||||||
FIXME( "not implemented on Mac\n" );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
|
||||||
ULONG output_len )
|
|
||||||
{
|
|
||||||
CCCryptorStatus status;
|
|
||||||
|
|
||||||
if ((status = CCCryptorUpdate( key->u.s.ref_encrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
|
||||||
{
|
|
||||||
WARN( "CCCryptorUpdate failed %d\n", status );
|
|
||||||
return STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output,
|
|
||||||
ULONG output_len )
|
|
||||||
{
|
|
||||||
CCCryptorStatus status;
|
|
||||||
|
|
||||||
if ((status = CCCryptorUpdate( key->u.s.ref_decrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
|
||||||
{
|
|
||||||
WARN( "CCCryptorUpdate failed %d\n", status );
|
|
||||||
return STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
|
||||||
{
|
|
||||||
FIXME( "not implemented on Mac\n" );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_asymmetric_init( struct key *key, struct algorithm *alg, const UCHAR *pubkey, ULONG pubkey_len )
|
|
||||||
{
|
|
||||||
FIXME( "not implemented on Mac\n" );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len, UCHAR *signature,
|
|
||||||
ULONG signature_len, DWORD flags )
|
|
||||||
{
|
|
||||||
FIXME( "not implemented on Mac\n" );
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS key_destroy( struct key *key )
|
|
||||||
{
|
|
||||||
if (key->u.s.ref_encrypt) CCCryptorRelease( key->u.s.ref_encrypt );
|
|
||||||
if (key->u.s.ref_decrypt) CCCryptorRelease( key->u.s.ref_decrypt );
|
|
||||||
heap_free( key->u.s.secret );
|
|
||||||
heap_free( key );
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_GNUTLS_CIPHER_INIT) || defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
#if defined(HAVE_GNUTLS_CIPHER_INIT) || defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||||
BOOL key_is_symmetric( struct key *key )
|
BOOL key_is_symmetric( struct key *key )
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009 Henri Verbeet for CodeWeavers
|
||||||
|
* Copyright 2018 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
#include <CommonCrypto/CommonCryptor.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "ntsecapi.h"
|
||||||
|
#include "bcrypt.h"
|
||||||
|
|
||||||
|
#include "bcrypt_internal.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
#include "wine/library.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
|
||||||
|
|
||||||
|
NTSTATUS key_set_property( struct key *key, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
|
||||||
|
{
|
||||||
|
if (!strcmpW( prop, BCRYPT_CHAINING_MODE ))
|
||||||
|
{
|
||||||
|
if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_ECB, size ))
|
||||||
|
{
|
||||||
|
key->u.s.mode = MODE_ID_ECB;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (!strncmpW( (WCHAR *)value, BCRYPT_CHAIN_MODE_CBC, size ))
|
||||||
|
{
|
||||||
|
key->u.s.mode = MODE_ID_CBC;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME( "unsupported mode %s\n", debugstr_wn( (WCHAR *)value, size ) );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME( "unsupported key property %s\n", debugstr_w(prop) );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG get_block_size( struct algorithm *alg )
|
||||||
|
{
|
||||||
|
ULONG ret = 0, size = sizeof(ret);
|
||||||
|
get_alg_property( alg, BCRYPT_BLOCK_LENGTH, (UCHAR *)&ret, sizeof(ret), &size );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_init( struct key *key, struct algorithm *alg, const UCHAR *secret, ULONG secret_len )
|
||||||
|
{
|
||||||
|
switch (alg->id)
|
||||||
|
{
|
||||||
|
case ALG_ID_AES:
|
||||||
|
switch (alg->mode)
|
||||||
|
{
|
||||||
|
case MODE_ID_ECB:
|
||||||
|
case MODE_ID_CBC:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME( "mode %u not supported\n", alg->mode );
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FIXME( "algorithm %u not supported\n", alg->id );
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(key->u.s.block_size = get_block_size( alg ))) return STATUS_INVALID_PARAMETER;
|
||||||
|
if (!(key->u.s.secret = heap_alloc( secret_len ))) return STATUS_NO_MEMORY;
|
||||||
|
memcpy( key->u.s.secret, secret, secret_len );
|
||||||
|
key->u.s.secret_len = secret_len;
|
||||||
|
|
||||||
|
key->alg_id = alg->id;
|
||||||
|
key->u.s.mode = alg->mode;
|
||||||
|
key->u.s.ref_encrypt = NULL; /* initialized on first use */
|
||||||
|
key->u.s.ref_decrypt = NULL;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CCMode get_cryptor_mode( struct key *key )
|
||||||
|
{
|
||||||
|
switch (key->u.s.mode)
|
||||||
|
{
|
||||||
|
case MODE_ID_ECB: return kCCModeECB;
|
||||||
|
case MODE_ID_CBC: return kCCModeCBC;
|
||||||
|
default:
|
||||||
|
FIXME( "unsupported mode %u\n", key->u.s.mode );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_set_params( struct key *key, UCHAR *iv, ULONG iv_len )
|
||||||
|
{
|
||||||
|
CCCryptorStatus status;
|
||||||
|
CCMode mode;
|
||||||
|
|
||||||
|
if (!(mode = get_cryptor_mode( key ))) return STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
if (key->u.s.ref_encrypt)
|
||||||
|
{
|
||||||
|
CCCryptorRelease( key->u.s.ref_encrypt );
|
||||||
|
key->u.s.ref_encrypt = NULL;
|
||||||
|
}
|
||||||
|
if (key->u.s.ref_decrypt)
|
||||||
|
{
|
||||||
|
CCCryptorRelease( key->u.s.ref_decrypt );
|
||||||
|
key->u.s.ref_decrypt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = CCCryptorCreateWithMode( kCCEncrypt, mode, kCCAlgorithmAES128, ccNoPadding, iv, key->u.s.secret,
|
||||||
|
key->u.s.secret_len, NULL, 0, 0, 0, &key->u.s.ref_encrypt )) != kCCSuccess)
|
||||||
|
{
|
||||||
|
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if ((status = CCCryptorCreateWithMode( kCCDecrypt, mode, kCCAlgorithmAES128, ccNoPadding, iv, key->u.s.secret,
|
||||||
|
key->u.s.secret_len, NULL, 0, 0, 0, &key->u.s.ref_decrypt )) != kCCSuccess)
|
||||||
|
{
|
||||||
|
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
||||||
|
CCCryptorRelease( key->u.s.ref_encrypt );
|
||||||
|
key->u.s.ref_encrypt = NULL;
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_set_auth_data( struct key *key, UCHAR *auth_data, ULONG len )
|
||||||
|
{
|
||||||
|
FIXME( "not implemented on Mac\n" );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len )
|
||||||
|
{
|
||||||
|
CCCryptorStatus status;
|
||||||
|
if ((status = CCCryptorUpdate( key->u.s.ref_encrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||||
|
{
|
||||||
|
WARN( "CCCryptorUpdate failed %d\n", status );
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len )
|
||||||
|
{
|
||||||
|
CCCryptorStatus status;
|
||||||
|
if ((status = CCCryptorUpdate( key->u.s.ref_decrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||||
|
{
|
||||||
|
WARN( "CCCryptorUpdate failed %d\n", status );
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
||||||
|
{
|
||||||
|
FIXME( "not implemented on Mac\n" );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_asymmetric_init( struct key *key, struct algorithm *alg, const UCHAR *pubkey, ULONG pubkey_len )
|
||||||
|
{
|
||||||
|
FIXME( "not implemented on Mac\n" );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len, UCHAR *signature,
|
||||||
|
ULONG signature_len, DWORD flags )
|
||||||
|
{
|
||||||
|
FIXME( "not implemented on Mac\n" );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS key_destroy( struct key *key )
|
||||||
|
{
|
||||||
|
if (key->u.s.ref_encrypt) CCCryptorRelease( key->u.s.ref_encrypt );
|
||||||
|
if (key->u.s.ref_decrypt) CCCryptorRelease( key->u.s.ref_decrypt );
|
||||||
|
heap_free( key->u.s.secret );
|
||||||
|
heap_free( key );
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue