From 209b968efc2336a72f5223f0c73ff46f11a2f1ba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 29 Sep 2020 15:27:32 +0200 Subject: [PATCH] bcrypt: Split the key structure into generic and backend-specific parts. Signed-off-by: Alexandre Julliard --- dlls/bcrypt/bcrypt_internal.h | 73 +---------------------------------- dlls/bcrypt/gnutls.c | 48 ++++++++++++++--------- dlls/bcrypt/macos.c | 40 ++++++++++++------- 3 files changed, 58 insertions(+), 103 deletions(-) diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index ca48d20f777..cd7c9694176 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -21,14 +21,6 @@ #define __BCRYPT_INTERNAL_H #include -#ifdef HAVE_GNUTLS_CIPHER_INIT -#include -#include -#include -#elif HAVE_COMMONCRYPTO_COMMONCRYPTOR_H -#include -#include -#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 { diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 341089c127d..81c729b66d8 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -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 diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c index 1a9bb888806..bfc8f5af964 100644 --- a/dlls/bcrypt/macos.c +++ b/dlls/bcrypt/macos.c @@ -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 )