Module: wine Branch: master Commit: a9193a200faeaaf9025506e07c003846b0343a7f URL: https://gitlab.winehq.org/wine/wine/-/commit/a9193a200faeaaf9025506e07c00384...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Dec 6 19:59:45 2023 +0100
bcrypt: Add support for setting DH parameters.
---
dlls/bcrypt/bcrypt_internal.h | 6 ++++-- dlls/bcrypt/bcrypt_main.c | 15 +++++++++++++++ dlls/bcrypt/gnutls.c | 41 ++++++++++++++++++++++++++++++++++++++--- include/bcrypt.h | 13 +++++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index cfbc5d2ac83..a31d170c621 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -187,7 +187,7 @@ struct key { struct object hdr; enum alg_id alg_id; - UINT64 private[2]; /* private data for backend */ + UINT64 private[3]; /* private data for backend */ union { struct key_symmetric s; @@ -294,7 +294,9 @@ struct key_asymmetric_export_params ULONG *ret_len; };
-#define KEY_IMPORT_FLAG_PUBLIC 0x00000001 +#define KEY_IMPORT_FLAG_PUBLIC 0x00000001 +#define KEY_IMPORT_FLAG_DH_PARAMETERS 0x00000002 + struct key_asymmetric_import_params { struct key *key; diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 52066a32c74..f58ddaf13aa 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -887,6 +887,21 @@ static NTSTATUS set_key_property( struct key *key, const WCHAR *prop, UCHAR *val key->u.a.bitlen = *(DWORD*)value; return STATUS_SUCCESS; } + else if (!wcscmp( prop, BCRYPT_DH_PARAMETERS )) + { + BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)value; + struct key_asymmetric_import_params params; + + if (key->alg_id != ALG_ID_DH || size < sizeof(*hdr) || hdr->cbLength != size || + hdr->dwMagic != BCRYPT_DH_PARAMETERS_MAGIC || hdr->cbKeyLength != key->u.a.bitlen / 8) + return STATUS_INVALID_PARAMETER; + + params.key = key; + params.flags = KEY_IMPORT_FLAG_DH_PARAMETERS; + params.buf = value; + params.len = size; + return UNIX_CALL( key_asymmetric_import, ¶ms ); + }
FIXME( "unsupported key property %s\n", debugstr_w(prop) ); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 68f84a553d2..0d912e7a2d7 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -84,8 +84,9 @@ union key_data gnutls_cipher_hd_t cipher; struct { - gnutls_privkey_t privkey; - gnutls_pubkey_t pubkey; + gnutls_privkey_t privkey; + gnutls_pubkey_t pubkey; + gnutls_dh_params_t dh_params; } a; }; C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) ); @@ -1833,6 +1834,36 @@ static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len ) return STATUS_SUCCESS; }
+static NTSTATUS key_import_dh_params( struct key *key, UCHAR *buf, ULONG len ) +{ + BCRYPT_DH_PARAMETER_HEADER *dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buf; + gnutls_dh_params_t params; + gnutls_datum_t p, g; + int ret; + + if ((ret = pgnutls_dh_params_init( ¶ms ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + + p.data = (unsigned char *)(dh_header + 1); + p.size = dh_header->cbKeyLength; + g.data = p.data + dh_header->cbKeyLength; + g.size = dh_header->cbKeyLength; + + if ((ret = pgnutls_dh_params_import_raw( params, &p, &g ))) + { + pgnutls_perror( ret ); + pgnutls_dh_params_deinit( params ); + return STATUS_INTERNAL_ERROR; + } + + if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params ); + key_data(key)->a.dh_params = params; + return STATUS_SUCCESS; +} + static NTSTATUS key_asymmetric_import( void *args ) { const struct key_asymmetric_import_params *params = args; @@ -1875,9 +1906,12 @@ static NTSTATUS key_asymmetric_import( void *args ) return STATUS_NOT_IMPLEMENTED;
case ALG_ID_DH: + if (flags & KEY_IMPORT_FLAG_DH_PARAMETERS) + return key_import_dh_params( key, params->buf, params->len ); if (flags & KEY_IMPORT_FLAG_PUBLIC) return key_import_dh_public( key, params->buf, params->len ); - return key_import_dh( key, params->buf, params->len ); + ret = key_import_dh( key, params->buf, params->len ); + break;
default: FIXME( "algorithm %u not yet supported\n", key->alg_id ); @@ -2300,6 +2334,7 @@ static NTSTATUS key_asymmetric_destroy( void *args )
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey ); if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey ); + if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params ); return STATUS_SUCCESS; }
diff --git a/include/bcrypt.h b/include/bcrypt.h index 7f768f61679..462c43a7021 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -118,6 +118,8 @@ typedef LONG NTSTATUS; #define BCRYPT_KDF_TLS_PRF L"TLS_PRF" #define BCRYPT_KDF_SP80056A_CONCAT L"SP800_56A_CONCAT" #define BCRYPT_KDF_RAW_SECRET L"TRUNCATE" + +#define BCRYPT_DH_PARAMETERS L"DHParameters" #else static const WCHAR BCRYPT_ALGORITHM_NAME[] = {'A','l','g','o','r','i','t','h','m','N','a','m','e',0}; static const WCHAR BCRYPT_AUTH_TAG_LENGTH[] = {'A','u','t','h','T','a','g','L','e','n','g','t','h',0}; @@ -198,6 +200,8 @@ static const WCHAR BCRYPT_KDF_HMAC[] = {'H','M','A','C',0}; static const WCHAR BCRYPT_KDF_TLS_PRF[] = {'T','L','S','_','P','R','F',0}; static const WCHAR BCRYPT_KDF_SP80056A_CONCAT[] = {'S','P','8','0','0','_','5','6','A','_','C','O','N','C','A','T',0}; static const WCHAR BCRYPT_KDF_RAW_SECRET[] = {'T','R','U','N','C','A','T','E',0}; + +static const WCHAR BCRYPT_DH_PARAMETERS[] = {'D','H','P','a','r','a','m','e','t','e','r','s',0}; #endif
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC 0x31534345 @@ -363,6 +367,15 @@ typedef struct _BCRYPT_DH_KEY_BLOB ULONG cbKey; } BCRYPT_DH_KEY_BLOB, *PBCRYPT_DH_KEY_BLOB;
+#define BCRYPT_DH_PARAMETERS_MAGIC 0x4d504844 + +typedef struct _BCRYPT_DH_PARAMETER_HEADER +{ + ULONG cbLength; + ULONG dwMagic; + ULONG cbKeyLength; +} BCRYPT_DH_PARAMETER_HEADER; + #define BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION 1
#define BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG 0x00000001