diff --git a/patches/bcrypt-ECDHSecretAgreement/0001-bcrypt-Allow-multiple-backends-to-coexist.patch b/patches/bcrypt-ECDHSecretAgreement/0001-bcrypt-Allow-multiple-backends-to-coexist.patch deleted file mode 100644 index 8f54133c..00000000 --- a/patches/bcrypt-ECDHSecretAgreement/0001-bcrypt-Allow-multiple-backends-to-coexist.patch +++ /dev/null @@ -1,312 +0,0 @@ -From 1768ecfc4a7181600df254069f02655fe4e5fa0b Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 2 Oct 2020 11:29:24 -0500 -Subject: [PATCH] bcrypt: Allow multiple backends to coexist. - -Signed-off-by: Derek Lesho ---- - dlls/bcrypt/Makefile.in | 3 +- - dlls/bcrypt/bcrypt_internal.h | 3 + - dlls/bcrypt/gnutls.c | 32 ++++-- - dlls/bcrypt/unixlib.c | 208 ++++++++++++++++++++++++++++++++++ - 4 files changed, 235 insertions(+), 11 deletions(-) - create mode 100644 dlls/bcrypt/unixlib.c - -diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in -index 63a731fa9d9..6dd3066d4a5 100644 ---- a/dlls/bcrypt/Makefile.in -+++ b/dlls/bcrypt/Makefile.in -@@ -8,6 +8,7 @@ C_SRCS = \ - gnutls.c \ - md2.c \ - sha256.c \ -- sha512.c -+ sha512.c \ -+ unixlib.c - - RC_SRCS = version.rc -diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h -index 61c367cae9d..d0697ed807e 100644 ---- a/dlls/bcrypt/bcrypt_internal.h -+++ b/dlls/bcrypt/bcrypt_internal.h -@@ -219,4 +219,7 @@ struct key_funcs - NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG ); - }; - -+struct key_funcs *gnutls_lib_init(DWORD reason); -+struct key_funcs *macos_lib_init(DWORD reason); -+ - #endif /* __BCRYPT_INTERNAL_H */ -diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c -index 7b1bceda889..66845ffc8cf 100644 ---- a/dlls/bcrypt/gnutls.c -+++ b/dlls/bcrypt/gnutls.c -@@ -373,9 +373,12 @@ fail: - - static void gnutls_uninitialize(void) - { -- pgnutls_global_deinit(); -- dlclose( libgnutls_handle ); -- libgnutls_handle = NULL; -+ if (libgnutls_handle) -+ { -+ pgnutls_global_deinit(); -+ dlclose( libgnutls_handle ); -+ libgnutls_handle = NULL; -+ } - } - - struct buffer -@@ -1894,19 +1897,28 @@ static const struct key_funcs key_funcs = - key_import_rsa - }; - --NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) -+struct key_funcs * gnutls_lib_init( DWORD reason ) - { - switch (reason) - { - case DLL_PROCESS_ATTACH: -- if (!gnutls_initialize()) return STATUS_DLL_NOT_FOUND; -- *(const struct key_funcs **)ptr_out = &key_funcs; -- break; -+ if (!gnutls_initialize()) return NULL; -+ return &key_funcs; - case DLL_PROCESS_DETACH: - if (libgnutls_handle) gnutls_uninitialize(); -- break; - } -- return STATUS_SUCCESS; -+ return NULL; - } - --#endif /* HAVE_GNUTLS_CIPHER_INIT */ -+#else /* HAVE_GNUTLS_CIPHER_INIT */ -+#include "ntstatus.h" -+#define WIN32_NO_STATUS -+#include "windef.h" -+#include "winbase.h" -+#include "winternl.h" -+ -+struct key_funcs * gnutls_lib_init( DWORD reason ) -+{ -+ return NULL; -+} -+#endif -diff --git a/dlls/bcrypt/unixlib.c b/dlls/bcrypt/unixlib.c -new file mode 100644 -index 00000000000..1937a8172a4 ---- /dev/null -+++ b/dlls/bcrypt/unixlib.c -@@ -0,0 +1,208 @@ -+#if 0 -+#pragma makedep unix -+#endif -+ -+#include "config.h" -+#include "wine/port.h" -+ -+#include -+ -+#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/unicode.h" -+ -+#if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 || defined(HAVE_GNUTLS_CIPHER_INIT) -+WINE_DEFAULT_DEBUG_CHANNEL(bcrypt); -+ -+static NTSTATUS CDECL key_set_property( struct key *key, const WCHAR *prop, UCHAR *value, ULONG size, ULONG flags ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_symmetric_init( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static void CDECL key_symmetric_vector_reset( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+} -+ -+static NTSTATUS CDECL key_symmetric_set_auth_data( struct key *key, UCHAR *auth_data, ULONG len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_symmetric_encrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_symmetric_decrypt( struct key *key, const UCHAR *input, ULONG input_len, UCHAR *output, ULONG output_len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_symmetric_get_tag( struct key *key, UCHAR *tag, ULONG len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static void CDECL key_symmetric_destroy( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+} -+ -+static NTSTATUS CDECL key_asymmetric_init( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULONG input_len, UCHAR *output, -+ ULONG output_len, ULONG *ret_len, ULONG flags ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len, -+ UCHAR *signature, ULONG signature_len, DWORD flags ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_export_ecc( struct key *key, UCHAR *output, ULONG len, ULONG *ret_len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *input, ULONG len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_asymmetric_generate( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_asymmetric_duplicate( struct key *key_orig, struct key *key_copy ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static void CDECL key_asymmetric_destroy( struct key *key ) -+{ -+ FIXME( "not implemented\n" ); -+} -+ -+static NTSTATUS CDECL key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, -+ UCHAR *output, ULONG output_len, ULONG *ret) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *input, ULONG input_len ) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ -+static struct key_funcs key_funcs = -+{ -+ key_set_property, -+ key_symmetric_init, -+ key_symmetric_vector_reset, -+ key_symmetric_set_auth_data, -+ key_symmetric_encrypt, -+ key_symmetric_decrypt, -+ key_symmetric_get_tag, -+ key_symmetric_destroy, -+ key_asymmetric_init, -+ key_asymmetric_generate, -+ key_asymmetric_decrypt, -+ key_asymmetric_duplicate, -+ key_asymmetric_sign, -+ key_asymmetric_verify, -+ key_asymmetric_destroy, -+ key_export_dsa_capi, -+ key_export_ecc, -+ key_import_dsa_capi, -+ key_import_ecc, -+ key_import_rsa, -+}; -+ -+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) -+{ -+ struct key_funcs *gnutls_funcs = gnutls_lib_init(reason); -+ -+ if (reason == DLL_PROCESS_ATTACH) -+ { -+#define RESOLVE_FUNC(name) \ -+ if (gnutls_funcs && gnutls_funcs->key_##name) \ -+ key_funcs.key_##name = gnutls_funcs->key_##name; -+ -+ RESOLVE_FUNC(set_property) -+ RESOLVE_FUNC(symmetric_init) -+ RESOLVE_FUNC(symmetric_vector_reset) -+ RESOLVE_FUNC(symmetric_set_auth_data) -+ RESOLVE_FUNC(symmetric_encrypt) -+ RESOLVE_FUNC(symmetric_decrypt) -+ RESOLVE_FUNC(symmetric_get_tag) -+ RESOLVE_FUNC(symmetric_destroy) -+ RESOLVE_FUNC(asymmetric_init) -+ RESOLVE_FUNC(asymmetric_generate) -+ RESOLVE_FUNC(asymmetric_decrypt) -+ RESOLVE_FUNC(asymmetric_duplicate) -+ RESOLVE_FUNC(asymmetric_sign) -+ RESOLVE_FUNC(asymmetric_verify) -+ RESOLVE_FUNC(asymmetric_destroy) -+ RESOLVE_FUNC(export_dsa_capi) -+ RESOLVE_FUNC(export_ecc) -+ RESOLVE_FUNC(import_dsa_capi) -+ RESOLVE_FUNC(import_ecc) -+ RESOLVE_FUNC(import_rsa) -+ -+#undef RESOLVE_FUNC -+ -+ *(struct key_funcs **)ptr_out = &key_funcs; -+ } -+ -+ return STATUS_SUCCESS; -+} -+ -+#endif --- -2.33.0 - diff --git a/patches/bcrypt-ECDHSecretAgreement/0002-bcrypt-Implement-BCryptSecretAgreement-with-libgcryp.patch b/patches/bcrypt-ECDHSecretAgreement/0002-bcrypt-Implement-BCryptSecretAgreement-with-libgcryp.patch deleted file mode 100644 index 0e2585a8..00000000 --- a/patches/bcrypt-ECDHSecretAgreement/0002-bcrypt-Implement-BCryptSecretAgreement-with-libgcryp.patch +++ /dev/null @@ -1,559 +0,0 @@ -From 528d7188ba7d6e68622d1b4f95608e68f26e1852 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 2 Oct 2020 12:11:49 -0500 -Subject: [PATCH] bcrypt: Implement BCryptSecretAgreement with libgcrypt. - -Signed-off-by: Derek Lesho ---- - configure.ac | 14 ++ - dlls/bcrypt/Makefile.in | 1 + - dlls/bcrypt/bcrypt_internal.h | 4 + - dlls/bcrypt/bcrypt_main.c | 55 ++++++- - dlls/bcrypt/gcrypt.c | 292 ++++++++++++++++++++++++++++++++++ - dlls/bcrypt/gnutls.c | 3 +- - dlls/bcrypt/tests/bcrypt.c | 2 +- - dlls/bcrypt/unixlib.c | 13 +- - 8 files changed, 376 insertions(+), 8 deletions(-) - create mode 100644 dlls/bcrypt/gcrypt.c - -diff --git a/configure.ac b/configure.ac -index f2401734035..b47f8d016e0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -47,6 +47,7 @@ AC_ARG_WITH(faudio, AS_HELP_STRING([--without-faudio],[do not use FAudio (XAu - AC_ARG_WITH(float-abi, AS_HELP_STRING([--with-float-abi=abi],[specify the ABI (soft|softfp|hard) for ARM platforms])) - AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig])) - AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeType library])) -+AC_ARG_WITH(gcrypt, AS_HELP_STRING([--without-gcrypt],[do not use libgcrypt])) - AC_ARG_WITH(gettext, AS_HELP_STRING([--without-gettext],[do not use gettext])) - AC_ARG_WITH(gettextpo, AS_HELP_STRING([--with-gettextpo],[use the GetTextPO library to rebuild po files]), - [if test "x$withval" = "xno"; then ac_cv_header_gettext_po_h=no; fi]) -@@ -1954,6 +1955,19 @@ WINE_NOTICE_WITH(vkd3d,[test "x$ac_cv_lib_soname_vkd3d" = "x"], - [vkd3d ${notice_platform}development files not found (or too old), Direct3D 12 won't be supported.]) - test "x$ac_cv_lib_soname_vkd3d" != "x" || enable_d3d12=${enable_d3d12:-no} - -+dnl **** Check for gcrypt **** -+if test "x$with_gcrypt" != "xno" -+then -+ WINE_PACKAGE_FLAGS(GCRYPT,[libgcrypt],,,, -+ [AC_CHECK_HEADERS([gcrypt.h]) -+ if test "$ac_cv_header_gcrypt_h" = "yes" -+ then -+ WINE_CHECK_SONAME(gcrypt,gcry_sexp_build,,,[$GCRYPT_LIBS]) -+ fi]) -+fi -+WINE_NOTICE_WITH(gcrypt,[test "x$ac_cv_lib_soname_gcrypt" = "x"], -+ [libgcrypt ${notice_platform}development files not found, GCRYPT won't be supported.]) -+ - dnl **** Check for gcc specific options **** - - AC_SUBST(EXTRACFLAGS,"") -diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in -index 6dd3066d4a5..5336c8fc66b 100644 ---- a/dlls/bcrypt/Makefile.in -+++ b/dlls/bcrypt/Makefile.in -@@ -5,6 +5,7 @@ EXTRAINCL = $(GNUTLS_CFLAGS) - - C_SRCS = \ - bcrypt_main.c \ -+ gcrypt.c \ - gnutls.c \ - md2.c \ - sha256.c \ -diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h -index d0697ed807e..66898c58cd2 100644 ---- a/dlls/bcrypt/bcrypt_internal.h -+++ b/dlls/bcrypt/bcrypt_internal.h -@@ -193,6 +193,8 @@ struct key - struct secret - { - struct object hdr; -+ UCHAR *data; -+ ULONG len; - }; - - struct key_funcs -@@ -217,9 +219,11 @@ struct key_funcs - NTSTATUS (CDECL *key_import_dsa_capi)( struct key *, UCHAR *, ULONG ); - NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG ); - NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG ); -+ NTSTATUS (CDECL *key_compute_secret_ecc)( unsigned char *privkey_in, struct key *pubkey_in, struct secret *secret ); - }; - - struct key_funcs *gnutls_lib_init(DWORD reason); - struct key_funcs *macos_lib_init(DWORD reason); -+struct key_funcs *gcrypt_lib_init(DWORD reason); - - #endif /* __BCRYPT_INTERNAL_H */ -diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c -index 5eb50cd616b..570f452d78e 100644 ---- a/dlls/bcrypt/bcrypt_main.c -+++ b/dlls/bcrypt/bcrypt_main.c -@@ -1925,9 +1925,12 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H - { - struct key *privkey = privatekey; - struct key *pubkey = publickey; -+ UCHAR *privkey_blob = NULL; -+ ULONG privkey_len; - struct secret *secret; -+ NTSTATUS status; - -- FIXME( "%p, %p, %p, %08x\n", privatekey, publickey, handle, flags ); -+ TRACE( "%p, %p, %p, %08x\n", privatekey, publickey, handle, flags ); - - if (!privkey || privkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - if (!pubkey || pubkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; -@@ -1936,18 +1939,39 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H - if (!(secret = heap_alloc_zero( sizeof(*secret) ))) return STATUS_NO_MEMORY; - secret->hdr.magic = MAGIC_SECRET; - -+ if ((status = key_funcs->key_export_ecc( privkey, NULL, 0, &privkey_len))) -+ goto done; -+ -+ privkey_blob = heap_alloc(privkey_len); -+ if ((status = key_funcs->key_export_ecc( privkey, privkey_blob, privkey_len, &privkey_len))) -+ goto done; -+ -+ if ((status = key_funcs->key_compute_secret_ecc( privkey_blob, pubkey, secret ))) -+ goto done; -+ -+done: -+ if (privkey_blob) -+ heap_free(privkey_blob); -+ -+ if (status) -+ { -+ heap_free(secret); -+ secret = NULL; -+ } -+ - *handle = secret; -- return STATUS_SUCCESS; -+ return status; - } - - NTSTATUS WINAPI BCryptDestroySecret(BCRYPT_SECRET_HANDLE handle) - { - struct secret *secret = handle; - -- FIXME( "%p\n", handle ); -+ TRACE( "%p\n", handle ); - - if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; - secret->hdr.magic = 0; -+ heap_free( secret->data ); - heap_free( secret ); - return STATUS_SUCCESS; - } -@@ -1957,12 +1981,33 @@ NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCrypt - { - struct secret *secret = handle; - -- FIXME( "%p, %s, %p, %p, %d, %p, %08x\n", secret, debugstr_w(kdf), parameter, derived, derived_size, result, flags ); -+ TRACE( "%p, %s, %p, %p, %d, %p, %08x\n", secret, debugstr_w(kdf), parameter, derived, derived_size, result, flags ); - - if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; - if (!kdf) return STATUS_INVALID_PARAMETER; - -- return STATUS_INTERNAL_ERROR; -+ if (!(lstrcmpW( kdf, BCRYPT_KDF_RAW_SECRET ))) -+ { -+ ULONG n; -+ ULONG secret_length = secret->len; -+ -+ if (!derived) -+ { -+ *result = secret_length; -+ return STATUS_SUCCESS; -+ } -+ -+ /* outputs in little endian for some reason */ -+ for (n = 0; n < secret_length && n < derived_size; n++) -+ { -+ derived[n] = secret->data[secret_length - n - 1]; -+ } -+ -+ *result = n; -+ return STATUS_SUCCESS; -+ } -+ FIXME( "Derivation function %s not supported.\n", debugstr_w(kdf) ); -+ return STATUS_NOT_IMPLEMENTED; - } - - BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) -diff --git a/dlls/bcrypt/gcrypt.c b/dlls/bcrypt/gcrypt.c -new file mode 100644 -index 00000000000..e72c27feb51 ---- /dev/null -+++ b/dlls/bcrypt/gcrypt.c -@@ -0,0 +1,292 @@ -+#if 0 -+#pragma makedep unix -+#endif -+ -+#include "config.h" -+#include "wine/port.h" -+ -+#include -+ -+#ifdef HAVE_GCRYPT_H -+ -+#include -+ -+#include "ntstatus.h" -+#define WIN32_NO_STATUS -+#include "windef.h" -+#include "winbase.h" -+#include "winternl.h" -+#include "bcrypt.h" -+ -+#include "bcrypt_internal.h" -+ -+#include "wine/debug.h" -+#include "wine/heap.h" -+#include "wine/unicode.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(bcrypt); -+WINE_DECLARE_DEBUG_CHANNEL(winediag); -+ -+static void *libgcrypt_handle; -+#define MAKE_FUNCPTR(f) static typeof(f) * p##f -+MAKE_FUNCPTR(gcry_check_version); -+MAKE_FUNCPTR(gcry_sexp_build); -+MAKE_FUNCPTR(gcry_pk_encrypt); -+MAKE_FUNCPTR(gcry_mpi_new); -+MAKE_FUNCPTR(gcry_mpi_print); -+MAKE_FUNCPTR(gcry_sexp_release); -+MAKE_FUNCPTR(gcry_mpi_release); -+MAKE_FUNCPTR(gcry_strsource); -+MAKE_FUNCPTR(gcry_strerror); -+MAKE_FUNCPTR(gcry_sexp_find_token); -+MAKE_FUNCPTR(gcry_sexp_nth_mpi); -+#undef MAKE_FUNCPTR -+ -+BOOL gcrypt_initialize(void) -+{ -+ if (!(libgcrypt_handle = dlopen( SONAME_LIBGCRYPT, RTLD_NOW))) -+ { -+ ERR_(winediag)( "failed to load libgcrypt, no support for diffie hellman key exchange\n" ); -+ return FALSE; -+ } -+ -+#define LOAD_FUNCPTR(f) \ -+ if (!(p##f = dlsym( libgcrypt_handle, #f))) \ -+ { \ -+ ERR( "failed to load %s\n", #f ); \ -+ goto fail; \ -+ } -+ -+ LOAD_FUNCPTR(gcry_check_version); -+ LOAD_FUNCPTR(gcry_sexp_build); -+ LOAD_FUNCPTR(gcry_pk_encrypt); -+ LOAD_FUNCPTR(gcry_mpi_new); -+ LOAD_FUNCPTR(gcry_mpi_print); -+ LOAD_FUNCPTR(gcry_sexp_release); -+ LOAD_FUNCPTR(gcry_mpi_release); -+ LOAD_FUNCPTR(gcry_strsource); -+ LOAD_FUNCPTR(gcry_strerror); -+ LOAD_FUNCPTR(gcry_sexp_find_token); -+ LOAD_FUNCPTR(gcry_sexp_nth_mpi); -+#undef LOAD_FUNCPTR -+ -+ return TRUE; -+ -+fail: -+ dlclose( libgcrypt_handle); -+ libgcrypt_handle = NULL; -+ return FALSE; -+} -+ -+ -+static void gcrypt_uninitialize(void) -+{ -+ if (libgcrypt_handle) -+ { -+ dlclose( libgcrypt_handle); -+ libgcrypt_handle = NULL; -+ } -+} -+ -+static NTSTATUS extract_result_into_secret(gcry_sexp_t result, struct secret *secret) -+{ -+ NTSTATUS status = STATUS_SUCCESS; -+ gcry_mpi_t fullcoords = NULL; -+ gcry_sexp_t fragment = NULL; -+ UCHAR *tmp_buffer = NULL; -+ gcry_error_t err; -+ size_t size; -+ -+ fragment = pgcry_sexp_find_token(result, "s", 0); -+ if (!fragment) -+ { -+ status = STATUS_NO_MEMORY; -+ goto done; -+ } -+ -+ fullcoords = pgcry_sexp_nth_mpi(fragment, 1, GCRYMPI_FMT_USG); -+ if (!fullcoords) -+ { -+ status = STATUS_NO_MEMORY; -+ goto done; -+ } -+ -+ if ((err = pgcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &size, fullcoords))) -+ { -+ ERR("Error = %s/%s.\n", pgcry_strsource(err), pgcry_strerror(err)); -+ status = STATUS_INTERNAL_ERROR; -+ goto done; -+ } -+ -+ tmp_buffer = malloc(size); -+ if ((err = pgcry_mpi_print(GCRYMPI_FMT_STD, tmp_buffer, size, NULL, fullcoords))) -+ { -+ ERR("Error = %s/%s.\n", pgcry_strsource(err), pgcry_strerror(err)); -+ status = STATUS_INTERNAL_ERROR; -+ goto done; -+ } -+ -+ secret->data = RtlAllocateHeap(GetProcessHeap(), 0, size / 2); -+ memcpy(secret->data, tmp_buffer + size % 2, size / 2); -+ secret->len = size / 2; -+ -+done: -+ free(tmp_buffer); -+ -+ pgcry_mpi_release(fullcoords); -+ pgcry_sexp_release(fragment); -+ -+ return status; -+} -+ -+/* this is necessary since GNUTLS doesn't support ECDH public key encryption, maybe we can replace this when it does: -+ https://github.com/gnutls/gnutls/blob/cdc4fc288d87f91f974aa23b6e8595a53970ce00/lib/nettle/pk.c#L495 */ -+static NTSTATUS CDECL key_compute_secret_ecc(unsigned char *privkey_in, struct key *pubkey_in, struct secret *secret) -+{ -+ const char *pubkey_format; -+ DWORD key_size; -+ gcry_sexp_t pubkey = NULL; -+ gcry_sexp_t privkey = NULL; -+ gcry_sexp_t xchg_result = NULL; -+ gcry_error_t err; -+ NTSTATUS status = STATUS_SUCCESS; -+ -+ if (!libgcrypt_handle) -+ { -+ ERR("Secrets not supported without gcrypt\n"); -+ return STATUS_INTERNAL_ERROR; -+ } -+ -+ switch (pubkey_in->alg_id) -+ { -+ case ALG_ID_ECDH_P256: -+ pubkey_format = "NIST P-256"; -+ key_size = 32; -+ break; -+ default: -+ FIXME("Unsupported algorithm id: %u\n", pubkey_in->alg_id); -+ return STATUS_INTERNAL_ERROR; -+ } -+ -+ /* import public key - -+ copy public key into temporary buffer so we can prepend 0x04 (to indicate it is uncompressed) */ -+ { -+ UCHAR *public_key_raw = malloc((key_size * 2) + 1); -+ public_key_raw[0] = 0x04; -+ memcpy(public_key_raw + 1, pubkey_in->u.a.pubkey + sizeof(BCRYPT_ECCKEY_BLOB), key_size * 2); -+ -+ err = pgcry_sexp_build(&pubkey, NULL, -+ "(key-data(public-key(ecdh(curve %s)(q %b))))", -+ pubkey_format, -+ (key_size * 2) + 1, -+ public_key_raw); -+ -+ free(public_key_raw); -+ } -+ -+ if (err) -+ { -+ ERR("Failed to build gcrypt public key\n"); -+ goto done; -+ } -+ -+ /* import private key */ -+ /* extract private key from blob structure */ -+ err = pgcry_sexp_build(&privkey, NULL, -+ "(data(flags raw)(value %b))", -+ key_size, -+ privkey_in + sizeof(BCRYPT_ECCKEY_BLOB) + key_size * 2); -+ -+ if (err) -+ { -+ ERR("Failed to build gcrypt private key data\n"); -+ goto done; -+ } -+ -+ if ((err = pgcry_pk_encrypt(&xchg_result, privkey, pubkey))) -+ { -+ ERR("Failed to perform key exchange\n"); -+ goto done; -+ } -+ -+ status = extract_result_into_secret(xchg_result, secret); -+ if (status) -+ { -+ ERR("Failed to extract secret key\n"); -+ goto done; -+ } -+ -+ if (secret->len != key_size) -+ { -+ ERR("got secret size %u, expected %u\n", secret->len, key_size); -+ status = STATUS_INTERNAL_ERROR; -+ goto done; -+ } -+ -+ done: -+ pgcry_sexp_release(pubkey); -+ pgcry_sexp_release(privkey); -+ pgcry_sexp_release(xchg_result); -+ -+ if (status) -+ { -+ return status; -+ } -+ if (err) -+ { -+ ERR("Error = %s/%s\n", pgcry_strsource (err), pgcry_strerror (err)); -+ return STATUS_INTERNAL_ERROR; -+ } -+ return STATUS_SUCCESS; -+} -+ -+static struct key_funcs key_funcs = -+{ -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ key_compute_secret_ecc -+}; -+ -+struct key_funcs * gcrypt_lib_init( DWORD reason ) -+{ -+ switch (reason) -+ { -+ case DLL_PROCESS_ATTACH: -+ if (!gcrypt_initialize()) return NULL; -+ return &key_funcs; -+ case DLL_PROCESS_DETACH: -+ gcrypt_uninitialize(); -+ } -+ return NULL; -+} -+ -+#else -+#include "ntstatus.h" -+#define WIN32_NO_STATUS -+#include "windef.h" -+#include "winbase.h" -+#include "winternl.h" -+ -+struct key_funcs * gcrypt_lib_init( DWORD reason ) -+{ -+ return NULL; -+} -+#endif -diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c -index 66845ffc8cf..64825f5b99b 100644 ---- a/dlls/bcrypt/gnutls.c -+++ b/dlls/bcrypt/gnutls.c -@@ -1894,7 +1894,8 @@ static const struct key_funcs key_funcs = - key_export_ecc, - key_import_dsa_capi, - key_import_ecc, -- key_import_rsa -+ key_import_rsa, -+ NULL - }; - - struct key_funcs * gnutls_lib_init( DWORD reason ) -diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c -index fb5ac03b039..894473d5346 100644 ---- a/dlls/bcrypt/tests/bcrypt.c -+++ b/dlls/bcrypt/tests/bcrypt.c -@@ -2248,7 +2248,7 @@ static void test_ECDH(void) - goto raw_secret_end; - } - -- todo_wine ok(status == STATUS_SUCCESS, "got %08x\n", status); -+ ok(status == STATUS_SUCCESS, "got %08x\n", status); - - if (status != STATUS_SUCCESS) - { -diff --git a/dlls/bcrypt/unixlib.c b/dlls/bcrypt/unixlib.c -index 1937a8172a4..e684a608eb5 100644 ---- a/dlls/bcrypt/unixlib.c -+++ b/dlls/bcrypt/unixlib.c -@@ -142,6 +142,12 @@ static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *input, ULONG input - return STATUS_NOT_IMPLEMENTED; - } - -+static NTSTATUS CDECL key_compute_secret_ecc (unsigned char *privkey_in, struct key *pubkey_in, struct secret *secret) -+{ -+ FIXME( "not implemented\n" ); -+ return STATUS_NOT_IMPLEMENTED; -+} -+ - static struct key_funcs key_funcs = - { - key_set_property, -@@ -164,17 +170,21 @@ static struct key_funcs key_funcs = - key_import_dsa_capi, - key_import_ecc, - key_import_rsa, -+ key_compute_secret_ecc, - }; - - NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) - { - struct key_funcs *gnutls_funcs = gnutls_lib_init(reason); -+ struct key_funcs *gcrypt_funcs = gcrypt_lib_init(reason); - - if (reason == DLL_PROCESS_ATTACH) - { - #define RESOLVE_FUNC(name) \ - if (gnutls_funcs && gnutls_funcs->key_##name) \ -- key_funcs.key_##name = gnutls_funcs->key_##name; -+ key_funcs.key_##name = gnutls_funcs->key_##name; \ -+ if (gcrypt_funcs && gcrypt_funcs->key_##name) \ -+ key_funcs.key_##name = gcrypt_funcs->key_##name; - - RESOLVE_FUNC(set_property) - RESOLVE_FUNC(symmetric_init) -@@ -196,6 +206,7 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p - RESOLVE_FUNC(import_dsa_capi) - RESOLVE_FUNC(import_ecc) - RESOLVE_FUNC(import_rsa) -+ RESOLVE_FUNC(compute_secret_ecc) - - #undef RESOLVE_FUNC - --- -2.33.0 - diff --git a/patches/bcrypt-ECDHSecretAgreement/0003-bcrypt-Implement-BCRYPT_KDF_HASH.patch b/patches/bcrypt-ECDHSecretAgreement/0003-bcrypt-Implement-BCRYPT_KDF_HASH.patch deleted file mode 100644 index b9385c4c..00000000 --- a/patches/bcrypt-ECDHSecretAgreement/0003-bcrypt-Implement-BCRYPT_KDF_HASH.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 305131e59c071ca84e4447ab053b04bf4023fee8 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 7 Jan 2020 14:22:49 -0600 -Subject: [PATCH] bcrypt: Implement BCRYPT_KDF_HASH. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47699 -Signed-off-by: Derek Lesho ---- - dlls/bcrypt/bcrypt_main.c | 108 ++++++++++++++++++++++++++++++++++++- - dlls/bcrypt/tests/bcrypt.c | 3 +- - 2 files changed, 108 insertions(+), 3 deletions(-) - -diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c -index 0655c5dcfe81..70e914bd41f1 100644 ---- a/dlls/bcrypt/bcrypt_main.c -+++ b/dlls/bcrypt/bcrypt_main.c -@@ -1993,7 +1993,113 @@ NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCrypt - if (!secret || secret->hdr.magic != MAGIC_SECRET) return STATUS_INVALID_HANDLE; - if (!kdf) return STATUS_INVALID_PARAMETER; - -- if (!(lstrcmpW( kdf, BCRYPT_KDF_RAW_SECRET ))) -+ if (flags) FIXME("flags ignored: %08x\n", flags); -+ -+ if (!(lstrcmpW( kdf, BCRYPT_KDF_HASH ))) -+ { -+ unsigned int i; -+ BCryptBuffer *hash_algorithm = NULL; -+ BCryptBuffer *secret_prepend = NULL; -+ BCryptBuffer *secret_append = NULL; -+ enum alg_id hash_alg_id; -+ ULONG hash_length; -+ struct hash_impl hash; -+ NTSTATUS status; -+ -+ if (parameter) -+ { -+ for (i = 0; i < parameter->cBuffers; i++) -+ { -+ BCryptBuffer *cur_buffer = ¶meter->pBuffers[i]; -+ switch(cur_buffer->BufferType) -+ { -+ case KDF_HASH_ALGORITHM: -+ if (hash_algorithm) -+ FIXME("Duplicate KDF_HASH_ALGORITHM, untested\n"); -+ hash_algorithm = cur_buffer; -+ break; -+ case KDF_SECRET_PREPEND: -+ if (secret_prepend) -+ FIXME("Multiple prefixes unsupported\n"); -+ secret_prepend = cur_buffer; -+ break; -+ case KDF_SECRET_APPEND: -+ if (secret_append) -+ FIXME("Multiple suffixes unsupported\n"); -+ secret_append = cur_buffer; -+ break; -+ default: -+ FIXME("Unsupported BCRYPT_KDF_HASH parameter type %x\n", cur_buffer->BufferType); -+ break; -+ } -+ } -+ } -+ -+ if (!(hash_algorithm)) -+ hash_alg_id = ALG_ID_SHA1; -+ else -+ { -+ for (i = 0; i < ARRAY_SIZE( builtin_algorithms ); i++) -+ { -+ if (!lstrcmpW( hash_algorithm->pvBuffer, builtin_algorithms[i].name)) -+ { -+ hash_alg_id = i; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(builtin_algorithms)) -+ { -+ WARN("Algorithm %s not found\n", debugstr_w(hash_algorithm->pvBuffer)); -+ return STATUS_NOT_SUPPORTED; -+ } -+ if (builtin_algorithms[hash_alg_id].class != BCRYPT_HASH_INTERFACE) -+ { -+ return STATUS_NOT_SUPPORTED; -+ } -+ } -+ -+ hash_length = builtin_algorithms[hash_alg_id].hash_length; -+ -+ if (!derived) -+ { -+ *result = hash_length; -+ return STATUS_SUCCESS; -+ } -+ -+ if ((status = hash_init(&hash, hash_alg_id))) -+ { -+ return status; -+ } -+ -+ if (secret_prepend) -+ { -+ hash_update(&hash, hash_alg_id, secret_prepend->pvBuffer, secret_prepend->cbBuffer); -+ } -+ -+ hash_update(&hash, hash_alg_id, secret->data, secret->len); -+ -+ if (secret_append) -+ { -+ hash_update(&hash, hash_alg_id, secret_append->pvBuffer, secret_append->cbBuffer); -+ } -+ -+ if (derived_size >= hash_length) -+ { -+ hash_finish(&hash, hash_alg_id, derived, derived_size); -+ *result = hash_length; -+ } -+ else -+ { -+ UCHAR *output = heap_alloc(hash_length); -+ hash_finish(&hash, hash_alg_id, output, hash_length); -+ memcpy(derived, output, derived_size); -+ heap_free(output); -+ *result = derived_size; -+ } -+ -+ return STATUS_SUCCESS; -+ } -+ else if (!(lstrcmpW( kdf, BCRYPT_KDF_RAW_SECRET ))) - { - ULONG n; - ULONG secret_length = secret->len; -diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c -index 6be406dee21f..b13432523d15 100644 ---- a/dlls/bcrypt/tests/bcrypt.c -+++ b/dlls/bcrypt/tests/bcrypt.c -@@ -2180,7 +2180,7 @@ static void test_ECDH(void) - raw_secret_end: - - status = pBCryptDeriveKey(secret, BCRYPT_KDF_HASH, &hash_params, NULL, 0, &size, 0); -- todo_wine ok (status == STATUS_SUCCESS, "got %08x\n", status); -+ ok (status == STATUS_SUCCESS, "got %08x\n", status); - - if (status != STATUS_SUCCESS) - { -@@ -2716,7 +2716,6 @@ static void test_SecretAgreement(void) - ok(status == STATUS_INVALID_PARAMETER, "got %08x\n", status); - - status = pBCryptDeriveKey(secret, L"HASH", NULL, NULL, 0, &size, 0); -- todo_wine - ok(status == STATUS_SUCCESS, "got %08x\n", status); - - status = pBCryptDestroyHash(secret); --- -2.29.2 - diff --git a/patches/bcrypt-ECDHSecretAgreement/definition b/patches/bcrypt-ECDHSecretAgreement/definition deleted file mode 100644 index 862b8b44..00000000 --- a/patches/bcrypt-ECDHSecretAgreement/definition +++ /dev/null @@ -1,6 +0,0 @@ -Fixes: [47699] Multiple games fail to connect to online services (missing BCryptSecretAgreement / BCryptDeriveKey implementation) -# Needs to be moved to the unix lib, but that's a nontrivial amount of work, and -# using gcrypt is the wrong way forward (we should expose the missing APIs from -# gnutls instead). -# Temporarily disabled pending a rebase from author. -Disabled: true \ No newline at end of file diff --git a/staging/upstream-commit b/staging/upstream-commit index 9d8684b8..16f6eef1 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -fcddf19498fca9b51baea705f5748b998f4560b9 +1e4db62e0ba0b8595748c94b032dfb0064207de1