bcrypt: Split the key structure into generic and backend-specific parts.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f0e1384777
commit
209b968efc
|
@ -21,14 +21,6 @@
|
|||
#define __BCRYPT_INTERNAL_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_GNUTLS_CIPHER_INIT
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#include <gnutls/abstract.h>
|
||||
#elif HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <CommonCrypto/CommonCryptor.h>
|
||||
#endif
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -162,68 +154,6 @@ struct algorithm
|
|||
ULONG flags;
|
||||
};
|
||||
|
||||
#if defined(HAVE_GNUTLS_CIPHER_INIT)
|
||||
struct key_symmetric
|
||||
{
|
||||
enum mode_id mode;
|
||||
ULONG block_size;
|
||||
gnutls_cipher_hd_t handle;
|
||||
UCHAR *vector;
|
||||
ULONG vector_len;
|
||||
UCHAR *secret;
|
||||
ULONG secret_len;
|
||||
};
|
||||
|
||||
struct key_asymmetric
|
||||
{
|
||||
gnutls_privkey_t handle;
|
||||
ULONG bitlen; /* ignored for ECC keys */
|
||||
UCHAR *pubkey;
|
||||
ULONG pubkey_len;
|
||||
DSSSEED dss_seed;
|
||||
};
|
||||
|
||||
struct key
|
||||
{
|
||||
struct object hdr;
|
||||
enum alg_id alg_id;
|
||||
union
|
||||
{
|
||||
struct key_symmetric s;
|
||||
struct key_asymmetric a;
|
||||
} u;
|
||||
};
|
||||
#elif defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
struct key_symmetric
|
||||
{
|
||||
enum mode_id mode;
|
||||
ULONG block_size;
|
||||
CCCryptorRef ref_encrypt;
|
||||
CCCryptorRef ref_decrypt;
|
||||
UCHAR *vector;
|
||||
ULONG vector_len;
|
||||
UCHAR *secret;
|
||||
ULONG secret_len;
|
||||
};
|
||||
|
||||
struct key_asymmetric
|
||||
{
|
||||
ULONG bitlen;
|
||||
UCHAR *pubkey;
|
||||
ULONG pubkey_len;
|
||||
};
|
||||
|
||||
struct key
|
||||
{
|
||||
struct object hdr;
|
||||
enum alg_id alg_id;
|
||||
union
|
||||
{
|
||||
struct key_symmetric s;
|
||||
struct key_asymmetric a;
|
||||
} u;
|
||||
};
|
||||
#else
|
||||
struct key_symmetric
|
||||
{
|
||||
enum mode_id mode;
|
||||
|
@ -239,19 +169,20 @@ struct key_asymmetric
|
|||
ULONG bitlen; /* ignored for ECC keys */
|
||||
UCHAR *pubkey;
|
||||
ULONG pubkey_len;
|
||||
DSSSEED dss_seed;
|
||||
};
|
||||
|
||||
struct key
|
||||
{
|
||||
struct object hdr;
|
||||
enum alg_id alg_id;
|
||||
void *private[2]; /* private data for backend */
|
||||
union
|
||||
{
|
||||
struct key_symmetric s;
|
||||
struct key_asymmetric a;
|
||||
} u;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct secret
|
||||
{
|
||||
|
|
|
@ -64,6 +64,18 @@ typedef enum
|
|||
} gnutls_ecc_curve_t;
|
||||
#endif
|
||||
|
||||
union key_data
|
||||
{
|
||||
gnutls_cipher_hd_t cipher;
|
||||
gnutls_privkey_t privkey;
|
||||
};
|
||||
C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
|
||||
|
||||
static union key_data *key_data( struct key *key )
|
||||
{
|
||||
return (union key_data *)key->private;
|
||||
}
|
||||
|
||||
/* Not present in gnutls version < 3.0 */
|
||||
static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
|
||||
static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
|
||||
|
@ -502,10 +514,10 @@ static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
|
|||
|
||||
void key_symmetric_vector_reset( struct key *key )
|
||||
{
|
||||
if (!key->u.s.handle) return;
|
||||
if (!key_data(key)->cipher) return;
|
||||
TRACE( "invalidating cipher handle\n" );
|
||||
pgnutls_cipher_deinit( key->u.s.handle );
|
||||
key->u.s.handle = NULL;
|
||||
pgnutls_cipher_deinit( key_data(key)->cipher );
|
||||
key_data(key)->cipher = NULL;
|
||||
}
|
||||
|
||||
static NTSTATUS init_cipher_handle( struct key *key )
|
||||
|
@ -514,7 +526,7 @@ static NTSTATUS init_cipher_handle( struct key *key )
|
|||
gnutls_datum_t secret, vector;
|
||||
int ret;
|
||||
|
||||
if (key->u.s.handle) return STATUS_SUCCESS;
|
||||
if (key_data(key)->cipher) return STATUS_SUCCESS;
|
||||
if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
secret.data = key->u.s.secret;
|
||||
|
@ -523,7 +535,7 @@ static NTSTATUS init_cipher_handle( struct key *key )
|
|||
vector.data = key->u.s.vector;
|
||||
vector.size = key->u.s.vector_len;
|
||||
|
||||
if ((ret = pgnutls_cipher_init( &key->u.s.handle, cipher, &secret, key->u.s.vector ? &vector : NULL )))
|
||||
if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -540,7 +552,7 @@ NTSTATUS key_symmetric_set_auth_data( struct key *key, UCHAR *auth_data, ULONG l
|
|||
if (!auth_data) return STATUS_SUCCESS;
|
||||
if ((status = init_cipher_handle( key ))) return status;
|
||||
|
||||
if ((ret = pgnutls_cipher_add_auth( key->u.s.handle, auth_data, len )))
|
||||
if ((ret = pgnutls_cipher_add_auth( key_data(key)->cipher, auth_data, len )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -555,7 +567,7 @@ NTSTATUS key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input
|
|||
|
||||
if ((status = init_cipher_handle( key ))) return status;
|
||||
|
||||
if ((ret = pgnutls_cipher_encrypt2( key->u.s.handle, input, input_len, output, output_len )))
|
||||
if ((ret = pgnutls_cipher_encrypt2( key_data(key)->cipher, input, input_len, output, output_len )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -570,7 +582,7 @@ NTSTATUS key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input
|
|||
|
||||
if ((status = init_cipher_handle( key ))) return status;
|
||||
|
||||
if ((ret = pgnutls_cipher_decrypt2( key->u.s.handle, input, input_len, output, output_len )))
|
||||
if ((ret = pgnutls_cipher_decrypt2( key_data(key)->cipher, input, input_len, output, output_len )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -585,7 +597,7 @@ NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
|||
|
||||
if ((status = init_cipher_handle( key ))) return status;
|
||||
|
||||
if ((ret = pgnutls_cipher_tag( key->u.s.handle, tag, len )))
|
||||
if ((ret = pgnutls_cipher_tag( key_data(key)->cipher, tag, len )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -595,7 +607,7 @@ NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
|||
|
||||
void key_symmetric_destroy( struct key *key )
|
||||
{
|
||||
if (key->u.s.handle) pgnutls_cipher_deinit( key->u.s.handle );
|
||||
if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
|
||||
}
|
||||
|
||||
static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bitlen, UCHAR **pubkey, ULONG *pubkey_len )
|
||||
|
@ -861,7 +873,7 @@ NTSTATUS key_asymmetric_generate( struct key *key )
|
|||
return status;
|
||||
}
|
||||
|
||||
key->u.a.handle = handle;
|
||||
key_data(key)->privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -890,7 +902,7 @@ NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key->u.a.handle, &curve, &x, &y, &d )))
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, &d )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -978,7 +990,7 @@ NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
|
|||
return status;
|
||||
}
|
||||
|
||||
key->u.a.handle = handle;
|
||||
key_data(key)->privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -990,7 +1002,7 @@ NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret
|
|||
UCHAR *src, *dst;
|
||||
int ret, size;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key->u.a.handle, &p, &q, &g, &y, &x )))
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, &x )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1087,7 +1099,7 @@ NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
|
|||
|
||||
memcpy( &key->u.a.dss_seed, x.data + x.size, sizeof(key->u.a.dss_seed) );
|
||||
|
||||
key->u.a.handle = handle;
|
||||
key_data(key)->privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1528,7 +1540,7 @@ NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULON
|
|||
*ret_len = key->u.a.bitlen / 8;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
if (!key->u.a.handle) return STATUS_INVALID_PARAMETER;
|
||||
if (!key_data(key)->privkey) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
hash.data = input;
|
||||
hash.size = input_len;
|
||||
|
@ -1536,7 +1548,7 @@ NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULON
|
|||
signature.data = NULL;
|
||||
signature.size = 0;
|
||||
|
||||
if ((ret = pgnutls_privkey_sign_hash( key->u.a.handle, hash_alg, 0, &hash, &signature )))
|
||||
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->privkey, hash_alg, 0, &hash, &signature )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1550,6 +1562,6 @@ NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULON
|
|||
|
||||
void key_asymmetric_destroy( struct key *key )
|
||||
{
|
||||
if (key->u.a.handle) pgnutls_privkey_deinit( key->u.a.handle );
|
||||
if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,18 @@
|
|||
#if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 && !defined(HAVE_GNUTLS_CIPHER_INIT)
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
|
||||
|
||||
struct key_data
|
||||
{
|
||||
CCCryptorRef ref_encrypt;
|
||||
CCCryptorRef ref_decrypt;
|
||||
};
|
||||
C_ASSERT( sizeof(struct key_data) <= sizeof(((struct key *)0)->private) );
|
||||
|
||||
static struct key_data *key_data( struct key *key )
|
||||
{
|
||||
return (struct key_data *)key->private;
|
||||
}
|
||||
|
||||
NTSTATUS key_set_property( struct key *key, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags )
|
||||
{
|
||||
if (!strcmpW( prop, BCRYPT_CHAINING_MODE ))
|
||||
|
@ -104,14 +116,14 @@ static CCMode get_cryptor_mode( struct key *key )
|
|||
|
||||
void key_symmetric_vector_reset( struct key *key )
|
||||
{
|
||||
if (!key->u.s.ref_encrypt) return;
|
||||
if (!key_data(key)->ref_encrypt) return;
|
||||
|
||||
TRACE( "invalidating cryptor handles\n" );
|
||||
CCCryptorRelease( key->u.s.ref_encrypt );
|
||||
key->u.s.ref_encrypt = NULL;
|
||||
CCCryptorRelease( key_data(key)->ref_encrypt );
|
||||
key_data(key)->ref_encrypt = NULL;
|
||||
|
||||
CCCryptorRelease( key->u.s.ref_decrypt );
|
||||
key->u.s.ref_decrypt = NULL;
|
||||
CCCryptorRelease( key_data(key)->ref_decrypt );
|
||||
key_data(key)->ref_decrypt = NULL;
|
||||
}
|
||||
|
||||
static NTSTATUS init_cryptor_handles( struct key *key )
|
||||
|
@ -119,23 +131,23 @@ static NTSTATUS init_cryptor_handles( struct key *key )
|
|||
CCCryptorStatus status;
|
||||
CCMode mode;
|
||||
|
||||
if (key->u.s.ref_encrypt) return STATUS_SUCCESS;
|
||||
if (key_data(key)->ref_encrypt) return STATUS_SUCCESS;
|
||||
if (!(mode = get_cryptor_mode( key ))) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
if ((status = CCCryptorCreateWithMode( kCCEncrypt, mode, kCCAlgorithmAES128, ccNoPadding, key->u.s.vector,
|
||||
key->u.s.secret, key->u.s.secret_len, NULL, 0, 0, 0,
|
||||
&key->u.s.ref_encrypt )) != kCCSuccess)
|
||||
&key_data(key)->ref_encrypt )) != kCCSuccess)
|
||||
{
|
||||
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
if ((status = CCCryptorCreateWithMode( kCCDecrypt, mode, kCCAlgorithmAES128, ccNoPadding, key->u.s.vector,
|
||||
key->u.s.secret, key->u.s.secret_len, NULL, 0, 0, 0,
|
||||
&key->u.s.ref_decrypt )) != kCCSuccess)
|
||||
&key_data(key)->ref_decrypt )) != kCCSuccess)
|
||||
{
|
||||
WARN( "CCCryptorCreateWithMode failed %d\n", status );
|
||||
CCCryptorRelease( key->u.s.ref_encrypt );
|
||||
key->u.s.ref_encrypt = NULL;
|
||||
CCCryptorRelease( key_data(key)->ref_encrypt );
|
||||
key_data(key)->ref_encrypt = NULL;
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -155,7 +167,7 @@ NTSTATUS key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input
|
|||
|
||||
if ((ret = init_cryptor_handles( key ))) return ret;
|
||||
|
||||
if ((status = CCCryptorUpdate( key->u.s.ref_encrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||
if ((status = CCCryptorUpdate( key_data(key)->ref_encrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||
{
|
||||
WARN( "CCCryptorUpdate failed %d\n", status );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -170,7 +182,7 @@ NTSTATUS key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input
|
|||
|
||||
if ((ret = init_cryptor_handles( key ))) return ret;
|
||||
|
||||
if ((status = CCCryptorUpdate( key->u.s.ref_decrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||
if ((status = CCCryptorUpdate( key_data(key)->ref_decrypt, input, input_len, output, output_len, NULL )) != kCCSuccess)
|
||||
{
|
||||
WARN( "CCCryptorUpdate failed %d\n", status );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -186,8 +198,8 @@ NTSTATUS key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len )
|
|||
|
||||
void key_symmetric_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 );
|
||||
if (key_data(key)->ref_encrypt) CCCryptorRelease( key_data(key)->ref_encrypt );
|
||||
if (key_data(key)->ref_decrypt) CCCryptorRelease( key_data(key)->ref_decrypt );
|
||||
}
|
||||
|
||||
NTSTATUS key_asymmetric_init( struct key *key )
|
||||
|
|
Loading…
Reference in New Issue