opengl32: Preserve the remainder of the version string when limiting the version...
[wine.git] / dlls / bcrypt / gnutls.c
blobbc0e036a53d545a6a9707eae077db7f129e34d7c
1 /*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 * Copyright 2018 Hans Leidekker for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include "config.h"
27 #ifdef HAVE_GNUTLS_CIPHER_INIT
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <sys/types.h>
33 #include <dlfcn.h>
34 #include <gnutls/gnutls.h>
35 #include <gnutls/crypto.h>
36 #include <gnutls/abstract.h>
38 #include "ntstatus.h"
39 #define WIN32_NO_STATUS
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winternl.h"
43 #include "ntsecapi.h"
44 #include "wincrypt.h"
45 #include "bcrypt.h"
47 #include "bcrypt_internal.h"
49 #include "wine/debug.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
52 WINE_DECLARE_DEBUG_CHANNEL(winediag);
54 #if GNUTLS_VERSION_MAJOR < 3
55 #define GNUTLS_CIPHER_AES_192_CBC 92
56 #define GNUTLS_CIPHER_AES_128_GCM 93
57 #define GNUTLS_CIPHER_AES_256_GCM 94
58 #define GNUTLS_PK_ECC 4
60 #define GNUTLS_CURVE_TO_BITS(curve) (unsigned int)(((unsigned int)1<<31)|((unsigned int)(curve)))
62 typedef enum
64 GNUTLS_ECC_CURVE_INVALID,
65 GNUTLS_ECC_CURVE_SECP224R1,
66 GNUTLS_ECC_CURVE_SECP256R1,
67 GNUTLS_ECC_CURVE_SECP384R1,
68 GNUTLS_ECC_CURVE_SECP521R1,
69 } gnutls_ecc_curve_t;
70 #endif
72 #if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 6)
73 #define GNUTLS_CIPHER_AES_128_CFB8 29
74 #define GNUTLS_CIPHER_AES_192_CFB8 30
75 #define GNUTLS_CIPHER_AES_256_CFB8 31
77 #define GNUTLS_PK_RSA_PSS 6
78 #define GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS (1 << 7)
79 typedef struct gnutls_x509_spki_st *gnutls_x509_spki_t;
80 #endif
82 union key_data
84 gnutls_cipher_hd_t cipher;
85 struct
87 gnutls_privkey_t privkey;
88 gnutls_pubkey_t pubkey;
89 } a;
91 C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
93 static union key_data *key_data( struct key *key )
95 return (union key_data *)key->private;
98 /* Not present in gnutls version < 3.0 */
99 static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
100 static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
101 static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign)(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
102 static int (*pgnutls_pubkey_import_ecc_raw)(gnutls_pubkey_t, gnutls_ecc_curve_t,
103 const gnutls_datum_t *, const gnutls_datum_t *);
104 static int (*pgnutls_pubkey_export_ecc_raw)(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
105 gnutls_datum_t *x, gnutls_datum_t *y);
106 static int (*pgnutls_privkey_import_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t, const gnutls_datum_t *,
107 const gnutls_datum_t *, const gnutls_datum_t *);
108 static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t, gnutls_sign_algorithm_t, unsigned int,
109 const gnutls_datum_t *, const gnutls_datum_t *);
110 static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t, unsigned int flags, const gnutls_datum_t *,
111 gnutls_datum_t *);
113 /* Not present in gnutls version < 2.11.0 */
114 static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
116 /* Not present in gnutls version < 2.12.0 */
117 static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
118 const gnutls_datum_t *, const gnutls_datum_t *);
119 static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
120 static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *,
121 gnutls_datum_t *);
123 /* Not present in gnutls version < 3.3.0 */
124 static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
125 gnutls_datum_t *);
126 static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
127 static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
128 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
129 static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
130 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
131 gnutls_datum_t *);
132 static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
133 gnutls_datum_t *, gnutls_datum_t *);
134 static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int);
135 static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
136 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
137 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
139 /* Not present in gnutls version < 3.6.0 */
140 static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
141 static int (*pgnutls_x509_spki_init)(gnutls_x509_spki_t *);
142 static void (*pgnutls_x509_spki_deinit)(gnutls_x509_spki_t);
143 static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, unsigned int);
144 static int (*pgnutls_pubkey_set_spki)(gnutls_pubkey_t, const gnutls_x509_spki_t, unsigned int);
145 static int (*pgnutls_privkey_set_spki)(gnutls_privkey_t, const gnutls_x509_spki_t, unsigned int);
147 static void *libgnutls_handle;
148 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
149 MAKE_FUNCPTR(gnutls_cipher_decrypt2);
150 MAKE_FUNCPTR(gnutls_cipher_deinit);
151 MAKE_FUNCPTR(gnutls_cipher_encrypt2);
152 MAKE_FUNCPTR(gnutls_cipher_init);
153 MAKE_FUNCPTR(gnutls_global_deinit);
154 MAKE_FUNCPTR(gnutls_global_init);
155 MAKE_FUNCPTR(gnutls_global_set_log_function);
156 MAKE_FUNCPTR(gnutls_global_set_log_level);
157 MAKE_FUNCPTR(gnutls_perror);
158 MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
159 MAKE_FUNCPTR(gnutls_privkey_deinit);
160 MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
161 MAKE_FUNCPTR(gnutls_privkey_init);
162 MAKE_FUNCPTR(gnutls_privkey_sign_hash);
163 MAKE_FUNCPTR(gnutls_pubkey_deinit);
164 MAKE_FUNCPTR(gnutls_pubkey_encrypt_data);
165 MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
166 MAKE_FUNCPTR(gnutls_pubkey_init);
167 #undef MAKE_FUNCPTR
169 static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
171 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
174 static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
176 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
179 static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
180 const gnutls_datum_t *x, const gnutls_datum_t *y)
182 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
185 static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
186 gnutls_datum_t *x, gnutls_datum_t *y)
188 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
191 static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
192 gnutls_datum_t *g, gnutls_datum_t *y)
194 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
197 static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
199 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
202 static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
203 gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
204 gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
206 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
209 static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
210 gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
212 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
215 static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
216 const gnutls_datum_t *x, const gnutls_datum_t *y,
217 const gnutls_datum_t *k)
219 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
222 static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
223 gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
225 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
228 static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
230 return GNUTLS_SIGN_UNKNOWN;
233 static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
234 unsigned int flags, const gnutls_datum_t *hash,
235 const gnutls_datum_t *signature)
237 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
240 static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
242 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
245 static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
246 const gnutls_datum_t *g, const gnutls_datum_t *y)
248 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
251 static int compat_gnutls_privkey_generate(gnutls_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits,
252 unsigned int flags)
254 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
257 static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
259 return GNUTLS_E_INTERNAL_ERROR;
262 static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
263 const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
264 const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
266 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
269 static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
270 gnutls_datum_t *plain_text)
272 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
275 static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
276 gnutls_datum_t *plain_text)
278 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
281 static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t *spki)
283 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
286 static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
290 static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
291 unsigned int salt_size)
295 static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
297 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
300 static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
302 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
305 static void gnutls_log( int level, const char *msg )
307 TRACE( "<%d> %s", level, msg );
310 static NTSTATUS gnutls_process_attach( void *args )
312 const char *env_str;
313 int ret;
315 if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
317 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
319 else
321 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
322 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
325 if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
327 ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
328 return STATUS_DLL_NOT_FOUND;
331 #define LOAD_FUNCPTR(f) \
332 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
334 ERR( "failed to load %s\n", #f ); \
335 goto fail; \
338 LOAD_FUNCPTR(gnutls_cipher_decrypt2)
339 LOAD_FUNCPTR(gnutls_cipher_deinit)
340 LOAD_FUNCPTR(gnutls_cipher_encrypt2)
341 LOAD_FUNCPTR(gnutls_cipher_init)
342 LOAD_FUNCPTR(gnutls_global_deinit)
343 LOAD_FUNCPTR(gnutls_global_init)
344 LOAD_FUNCPTR(gnutls_global_set_log_function)
345 LOAD_FUNCPTR(gnutls_global_set_log_level)
346 LOAD_FUNCPTR(gnutls_perror)
347 LOAD_FUNCPTR(gnutls_privkey_deinit);
348 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
349 LOAD_FUNCPTR(gnutls_privkey_init);
350 LOAD_FUNCPTR(gnutls_privkey_sign_hash);
351 LOAD_FUNCPTR(gnutls_pubkey_deinit);
352 LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
353 LOAD_FUNCPTR(gnutls_pubkey_init);
354 #undef LOAD_FUNCPTR
356 #define LOAD_FUNCPTR_OPT(f) \
357 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
359 WARN( "failed to load %s\n", #f ); \
360 p##f = compat_##f; \
363 LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
364 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
365 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
366 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
367 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
368 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
369 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
370 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
371 LOAD_FUNCPTR_OPT(gnutls_privkey_generate)
372 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
373 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
374 LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki)
375 LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data)
376 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
377 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
378 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
379 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
380 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
381 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
382 LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki)
383 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
384 LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
385 LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
386 LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
388 #undef LOAD_FUNCPTR_OPT
390 if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
392 pgnutls_perror( ret );
393 goto fail;
396 if (TRACE_ON( bcrypt ))
398 pgnutls_global_set_log_level( 4 );
399 pgnutls_global_set_log_function( gnutls_log );
402 return STATUS_SUCCESS;
404 fail:
405 dlclose( libgnutls_handle );
406 libgnutls_handle = NULL;
407 return STATUS_DLL_NOT_FOUND;
410 static NTSTATUS gnutls_process_detach( void *args )
412 if (libgnutls_handle)
414 pgnutls_global_deinit();
415 dlclose( libgnutls_handle );
416 libgnutls_handle = NULL;
418 return STATUS_SUCCESS;
421 struct buffer
423 BYTE *buffer;
424 DWORD length;
425 DWORD pos;
426 BOOL error;
429 static void buffer_init( struct buffer *buffer )
431 buffer->buffer = NULL;
432 buffer->length = 0;
433 buffer->pos = 0;
434 buffer->error = FALSE;
437 static void buffer_free( struct buffer *buffer )
439 free( buffer->buffer );
442 static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
444 if (!len) return;
446 if (buffer->pos + len > buffer->length)
448 DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
449 BYTE *new_buffer;
451 if (!(new_buffer = realloc( buffer->buffer, new_length )))
453 ERR( "out of memory\n" );
454 buffer->error = TRUE;
455 return;
458 buffer->buffer = new_buffer;
459 buffer->length = new_length;
462 memcpy( &buffer->buffer[buffer->pos], data, len );
463 buffer->pos += len;
466 static void buffer_append_byte( struct buffer *buffer, BYTE value )
468 buffer_append( buffer, &value, sizeof(value) );
471 static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
473 DWORD num_bytes;
475 if (length < 128)
477 buffer_append_byte( buffer, length );
478 return;
481 if (length <= 0xff) num_bytes = 1;
482 else if (length <= 0xffff) num_bytes = 2;
483 else if (length <= 0xffffff) num_bytes = 3;
484 else num_bytes = 4;
486 buffer_append_byte( buffer, 0x80 | num_bytes );
487 while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
490 static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
492 DWORD leading_zero = (*data & 0x80) != 0;
494 buffer_append_byte( buffer, 0x02 ); /* tag */
495 buffer_append_asn1_length( buffer, len + leading_zero );
496 if (leading_zero) buffer_append_byte( buffer, 0 );
497 buffer_append( buffer, data, len );
500 static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
502 if (content->error)
504 buffer->error = TRUE;
505 return;
508 buffer_append_byte( buffer, 0x30 ); /* tag */
509 buffer_append_asn1_length( buffer, content->pos );
510 buffer_append( buffer, content->buffer, content->pos );
513 static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
515 struct buffer value;
517 buffer_init( &value );
518 buffer_append_asn1_integer( &value, r, r_len );
519 buffer_append_asn1_integer( &value, s, s_len );
520 buffer_append_asn1_sequence( buffer, &value );
521 buffer_free( &value );
524 static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
526 switch (key->alg_id)
528 case ALG_ID_3DES:
529 WARN( "handle block size\n" );
530 switch (key->u.s.mode)
532 case CHAIN_MODE_CBC:
533 return GNUTLS_CIPHER_3DES_CBC;
534 default:
535 break;
537 FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
538 return GNUTLS_CIPHER_UNKNOWN;
540 case ALG_ID_AES:
541 WARN( "handle block size\n" );
542 switch (key->u.s.mode)
544 case CHAIN_MODE_GCM:
545 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
546 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
547 break;
548 case CHAIN_MODE_ECB: /* can be emulated with CBC + empty IV */
549 case CHAIN_MODE_CBC:
550 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
551 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
552 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
553 break;
554 case CHAIN_MODE_CFB:
555 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
556 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
557 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
558 break;
559 default:
560 break;
562 FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
563 return GNUTLS_CIPHER_UNKNOWN;
565 default:
566 FIXME( "algorithm %u not supported\n", key->alg_id );
567 return GNUTLS_CIPHER_UNKNOWN;
571 static NTSTATUS key_symmetric_vector_reset( void *args )
573 struct key *key = args;
575 if (!key_data(key)->cipher) return STATUS_SUCCESS;
576 TRACE( "invalidating cipher handle\n" );
577 pgnutls_cipher_deinit( key_data(key)->cipher );
578 key_data(key)->cipher = NULL;
579 return STATUS_SUCCESS;
582 static NTSTATUS init_cipher_handle( struct key *key )
584 gnutls_cipher_algorithm_t cipher;
585 gnutls_datum_t secret, vector;
586 int ret;
588 if (key_data(key)->cipher) return STATUS_SUCCESS;
589 if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
591 secret.data = key->u.s.secret;
592 secret.size = key->u.s.secret_len;
594 vector.data = key->u.s.vector;
595 vector.size = key->u.s.vector_len;
597 if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
599 pgnutls_perror( ret );
600 return STATUS_INTERNAL_ERROR;
603 return STATUS_SUCCESS;
606 static NTSTATUS key_symmetric_set_auth_data( void *args )
608 const struct key_symmetric_set_auth_data_params *params = args;
609 NTSTATUS status;
610 int ret;
612 if (!params->auth_data) return STATUS_SUCCESS;
613 if ((status = init_cipher_handle( params->key ))) return status;
615 if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
617 pgnutls_perror( ret );
618 return STATUS_INTERNAL_ERROR;
620 return STATUS_SUCCESS;
623 static NTSTATUS key_symmetric_encrypt( void *args )
625 const struct key_symmetric_encrypt_params *params = args;
626 NTSTATUS status;
627 int ret;
629 if ((status = init_cipher_handle( params->key ))) return status;
631 if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
632 params->output, params->output_len )))
634 pgnutls_perror( ret );
635 return STATUS_INTERNAL_ERROR;
637 return STATUS_SUCCESS;
640 static NTSTATUS key_symmetric_decrypt( void *args )
642 const struct key_symmetric_decrypt_params *params = args;
643 NTSTATUS status;
644 int ret;
646 if ((status = init_cipher_handle( params->key ))) return status;
648 if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
649 params->output, params->output_len )))
651 pgnutls_perror( ret );
652 return STATUS_INTERNAL_ERROR;
654 return STATUS_SUCCESS;
657 static NTSTATUS key_symmetric_get_tag( void *args )
659 const struct key_symmetric_get_tag_params *params = args;
660 NTSTATUS status;
661 int ret;
663 if ((status = init_cipher_handle( params->key ))) return status;
665 if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
667 pgnutls_perror( ret );
668 return STATUS_INTERNAL_ERROR;
670 return STATUS_SUCCESS;
673 static NTSTATUS key_symmetric_destroy( void *args )
675 struct key *key = args;
677 if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
678 return STATUS_SUCCESS;
681 static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
683 ULONG size = d->size;
684 UCHAR *src = d->data;
685 ULONG offset = 0;
687 assert( size <= buflen + 1 );
688 if (size == buflen + 1)
690 assert( !src[0] );
691 src++;
692 size--;
694 if (zero_pad)
696 offset = buflen - size;
697 if (buffer) memset( buffer, 0, offset );
698 size = buflen;
701 if (buffer) memcpy( buffer + offset, src, size - offset );
702 return size;
705 #define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
706 static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
708 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
709 gnutls_datum_t m, e;
710 ULONG size = key->u.a.bitlen / 8;
711 UCHAR *dst;
712 int ret;
714 if (key_data(key)->a.pubkey)
715 ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
716 else
717 return STATUS_INVALID_PARAMETER;
719 if (ret)
721 pgnutls_perror( ret );
722 return STATUS_INTERNAL_ERROR;
725 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
726 if (len >= *ret_len && buf)
728 dst = (UCHAR *)(rsa_blob + 1);
729 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
731 dst += rsa_blob->cbPublicExp;
732 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
734 rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
735 rsa_blob->BitLength = key->u.a.bitlen;
736 rsa_blob->cbPrime1 = 0;
737 rsa_blob->cbPrime2 = 0;
740 free( e.data ); free( m.data );
741 return STATUS_SUCCESS;
744 static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
746 BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
747 gnutls_ecc_curve_t curve;
748 gnutls_datum_t x, y;
749 DWORD magic, size;
750 UCHAR *dst;
751 int ret;
753 switch (key->alg_id)
755 case ALG_ID_ECDH_P256:
756 magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
757 size = 32;
758 break;
760 case ALG_ID_ECDH_P384:
761 magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
762 size = 48;
763 break;
765 case ALG_ID_ECDSA_P256:
766 magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
767 size = 32;
768 break;
770 case ALG_ID_ECDSA_P384:
771 magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
772 size = 48;
773 break;
775 default:
776 FIXME( "algorithm %u not supported\n", key->alg_id );
777 return STATUS_NOT_IMPLEMENTED;
780 if (key_data(key)->a.pubkey)
781 ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
782 else
783 return STATUS_INVALID_PARAMETER;
785 if (ret)
787 pgnutls_perror( ret );
788 return STATUS_INTERNAL_ERROR;
791 if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1)
793 FIXME( "curve %u not supported\n", curve );
794 free( x.data ); free( y.data );
795 return STATUS_NOT_IMPLEMENTED;
798 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
799 if (len >= *ret_len && buf)
801 ecc_blob->dwMagic = magic;
802 ecc_blob->cbKey = size;
804 dst = (UCHAR *)(ecc_blob + 1);
805 dst += export_gnutls_datum( dst, size, &x, 1 );
806 export_gnutls_datum( dst, size, &y, 1 );
809 free( x.data ); free( y.data );
810 return STATUS_SUCCESS;
813 static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
815 BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
816 gnutls_datum_t p, q, g, y;
817 ULONG size = key->u.a.bitlen / 8;
818 NTSTATUS status = STATUS_SUCCESS;
819 UCHAR *dst;
820 int ret;
822 if (key->u.a.bitlen > 1024)
824 FIXME( "bitlen > 1024 not supported\n" );
825 return STATUS_NOT_IMPLEMENTED;
828 if (key_data(key)->a.pubkey)
829 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
830 else
831 return STATUS_INVALID_PARAMETER;
833 if (ret)
835 pgnutls_perror( ret );
836 return STATUS_INTERNAL_ERROR;
839 if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
841 status = STATUS_INVALID_PARAMETER;
842 goto done;
845 *ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
846 if (len >= *ret_len && buf)
848 dst = (UCHAR *)(dsa_blob + 1);
849 dst += export_gnutls_datum( dst, size, &p, 1 );
850 dst += export_gnutls_datum( dst, size, &g, 1 );
851 export_gnutls_datum( dst, size, &y, 1 );
853 dst = dsa_blob->q;
854 export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
856 dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
857 dsa_blob->cbKey = size;
858 memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
859 memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
862 done:
863 free( p.data ); free( q.data ); free( g.data ); free( y.data );
864 return status;
867 static void reverse_bytes( UCHAR *buf, ULONG len )
869 unsigned int i;
870 UCHAR tmp;
872 for (i = 0; i < len / 2; ++i)
874 tmp = buf[i];
875 buf[i] = buf[len - i - 1];
876 buf[len - i - 1] = tmp;
880 #define Q_SIZE 20
881 static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
883 BLOBHEADER *hdr = (BLOBHEADER *)buf;
884 DSSPUBKEY *dsskey;
885 gnutls_datum_t p, q, g, y;
886 ULONG size = key->u.a.bitlen / 8;
887 NTSTATUS status = STATUS_SUCCESS;
888 UCHAR *dst;
889 int ret;
891 if (key->u.a.bitlen > 1024)
893 FIXME( "bitlen > 1024 not supported\n" );
894 return STATUS_NOT_IMPLEMENTED;
897 if (key_data(key)->a.pubkey)
898 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
899 else if (key_data(key)->a.privkey)
900 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
901 else
902 return STATUS_INVALID_PARAMETER;
904 if (ret)
906 pgnutls_perror( ret );
907 return STATUS_INTERNAL_ERROR;
910 if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
912 status = STATUS_INVALID_PARAMETER;
913 goto done;
916 *ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
917 EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
918 if (len >= *ret_len && buf)
920 hdr->bType = PUBLICKEYBLOB;
921 hdr->bVersion = 2;
922 hdr->reserved = 0;
923 hdr->aiKeyAlg = CALG_DSS_SIGN;
925 dsskey = (DSSPUBKEY *)(hdr + 1);
926 dsskey->magic = MAGIC_DSS1;
927 dsskey->bitlen = key->u.a.bitlen;
929 dst = (UCHAR *)(dsskey + 1);
930 export_gnutls_datum( dst, size, &p, 1 );
931 reverse_bytes( dst, size );
932 dst += size;
934 export_gnutls_datum( dst, Q_SIZE, &q, 1 );
935 reverse_bytes( dst, Q_SIZE );
936 dst += Q_SIZE;
938 export_gnutls_datum( dst, size, &g, 1 );
939 reverse_bytes( dst, size );
940 dst += size;
942 export_gnutls_datum( dst, size, &y, 1 );
943 reverse_bytes( dst, size );
944 dst += size;
946 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
949 done:
950 free( p.data ); free( q.data ); free( g.data ); free( y.data );
951 return status;
954 static NTSTATUS key_asymmetric_generate( void *args )
956 struct key *key = args;
957 gnutls_pk_algorithm_t pk_alg;
958 gnutls_privkey_t privkey;
959 gnutls_pubkey_t pubkey;
960 unsigned int bitlen;
961 int ret;
963 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
964 if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
966 switch (key->alg_id)
968 case ALG_ID_RSA:
969 case ALG_ID_RSA_SIGN:
970 pk_alg = GNUTLS_PK_RSA;
971 bitlen = key->u.a.bitlen;
972 break;
974 case ALG_ID_DSA:
975 pk_alg = GNUTLS_PK_DSA;
976 bitlen = key->u.a.bitlen;
977 break;
979 case ALG_ID_ECDH_P256:
980 case ALG_ID_ECDSA_P256:
981 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
982 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
983 break;
985 case ALG_ID_ECDH_P384:
986 case ALG_ID_ECDSA_P384:
987 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
988 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
989 break;
991 default:
992 FIXME( "algorithm %u not supported\n", key->alg_id );
993 return STATUS_NOT_SUPPORTED;
996 if ((ret = pgnutls_privkey_init( &privkey )))
998 pgnutls_perror( ret );
999 return STATUS_INTERNAL_ERROR;
1001 if ((ret = pgnutls_pubkey_init( &pubkey )))
1003 pgnutls_perror( ret );
1004 pgnutls_privkey_deinit( privkey );
1005 return STATUS_INTERNAL_ERROR;
1008 if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
1010 pgnutls_perror( ret );
1011 pgnutls_privkey_deinit( privkey );
1012 pgnutls_pubkey_deinit( pubkey );
1013 return STATUS_INTERNAL_ERROR;
1015 if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1017 pgnutls_perror( ret );
1018 pgnutls_privkey_deinit( privkey );
1019 pgnutls_pubkey_deinit( pubkey );
1020 return STATUS_INTERNAL_ERROR;
1023 key_data(key)->a.privkey = privkey;
1024 key_data(key)->a.pubkey = pubkey;
1025 return STATUS_SUCCESS;
1028 static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1030 BCRYPT_ECCKEY_BLOB *ecc_blob;
1031 gnutls_ecc_curve_t curve;
1032 gnutls_datum_t x, y, d;
1033 DWORD magic, size;
1034 UCHAR *dst;
1035 int ret;
1037 switch (key->alg_id)
1039 case ALG_ID_ECDH_P256:
1040 magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1041 size = 32;
1042 break;
1044 case ALG_ID_ECDH_P384:
1045 magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1046 size = 48;
1047 break;
1049 case ALG_ID_ECDSA_P256:
1050 magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1051 size = 32;
1052 break;
1054 case ALG_ID_ECDSA_P384:
1055 magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1056 size = 48;
1057 break;
1059 default:
1060 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1061 return STATUS_NOT_IMPLEMENTED;
1064 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1066 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1068 pgnutls_perror( ret );
1069 return STATUS_INTERNAL_ERROR;
1072 if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1)
1074 FIXME( "curve %u not supported\n", curve );
1075 free( x.data ); free( y.data ); free( d.data );
1076 return STATUS_NOT_IMPLEMENTED;
1079 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1080 if (len >= *ret_len && buf)
1082 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1083 ecc_blob->dwMagic = magic;
1084 ecc_blob->cbKey = size;
1086 dst = (UCHAR *)(ecc_blob + 1);
1087 dst += export_gnutls_datum( dst, size, &x, 1 );
1088 dst += export_gnutls_datum( dst, size, &y, 1 );
1089 export_gnutls_datum( dst, size, &d, 1 );
1092 free( x.data ); free( y.data ); free( d.data );
1093 return STATUS_SUCCESS;
1096 static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1098 BCRYPT_ECCKEY_BLOB *ecc_blob;
1099 gnutls_ecc_curve_t curve;
1100 gnutls_privkey_t handle;
1101 gnutls_datum_t x, y, k;
1102 int ret;
1104 switch (key->alg_id)
1106 case ALG_ID_ECDH_P256:
1107 case ALG_ID_ECDSA_P256:
1108 curve = GNUTLS_ECC_CURVE_SECP256R1;
1109 break;
1111 case ALG_ID_ECDH_P384:
1112 case ALG_ID_ECDSA_P384:
1113 curve = GNUTLS_ECC_CURVE_SECP384R1;
1114 break;
1116 default:
1117 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1118 return STATUS_NOT_IMPLEMENTED;
1121 if ((ret = pgnutls_privkey_init( &handle )))
1123 pgnutls_perror( ret );
1124 return STATUS_INTERNAL_ERROR;
1127 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1128 x.data = (unsigned char *)(ecc_blob + 1);
1129 x.size = ecc_blob->cbKey;
1130 y.data = x.data + ecc_blob->cbKey;
1131 y.size = ecc_blob->cbKey;
1132 k.data = y.data + ecc_blob->cbKey;
1133 k.size = ecc_blob->cbKey;
1135 if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1137 pgnutls_perror( ret );
1138 pgnutls_privkey_deinit( handle );
1139 return STATUS_INTERNAL_ERROR;
1142 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1143 key_data(key)->a.privkey = handle;
1144 return STATUS_SUCCESS;
1147 static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1149 BCRYPT_RSAKEY_BLOB *rsa_blob;
1150 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1151 ULONG size = key->u.a.bitlen / 8;
1152 BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1153 UCHAR *dst;
1154 int ret;
1156 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1158 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1160 pgnutls_perror( ret );
1161 return STATUS_INTERNAL_ERROR;
1164 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1165 EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1167 if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1168 EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1170 if (len >= *ret_len && buf)
1172 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1173 rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1174 rsa_blob->BitLength = key->u.a.bitlen;
1176 dst = (UCHAR *)(rsa_blob + 1);
1177 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1179 dst += rsa_blob->cbPublicExp;
1180 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1182 dst += rsa_blob->cbModulus;
1183 rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1185 dst += rsa_blob->cbPrime1;
1186 rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1188 if (full)
1190 dst += rsa_blob->cbPrime2;
1191 export_gnutls_datum( dst, size / 2, &e1, 1 );
1193 dst += rsa_blob->cbPrime1;
1194 export_gnutls_datum( dst, size / 2, &e2, 1 );
1196 dst += rsa_blob->cbPrime2;
1197 export_gnutls_datum( dst, size / 2, &u, 1 );
1199 dst += rsa_blob->cbPrime1;
1200 export_gnutls_datum( dst, size, &d, 1 );
1204 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1205 free( e1.data ); free( e2.data );
1206 return STATUS_SUCCESS;
1209 static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1211 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1212 gnutls_datum_t m, e, p, q;
1213 gnutls_privkey_t handle;
1214 int ret;
1216 if ((ret = pgnutls_privkey_init( &handle )))
1218 pgnutls_perror( ret );
1219 return STATUS_INTERNAL_ERROR;
1222 e.data = (unsigned char *)(rsa_blob + 1);
1223 e.size = rsa_blob->cbPublicExp;
1224 m.data = e.data + e.size;
1225 m.size = rsa_blob->cbModulus;
1226 p.data = m.data + m.size;
1227 p.size = rsa_blob->cbPrime1;
1228 q.data = p.data + p.size;
1229 q.size = rsa_blob->cbPrime2;
1231 if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1233 pgnutls_perror( ret );
1234 pgnutls_privkey_deinit( handle );
1235 return STATUS_INTERNAL_ERROR;
1238 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1239 key_data(key)->a.privkey = handle;
1240 return STATUS_SUCCESS;
1243 static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1245 BLOBHEADER *hdr;
1246 DSSPUBKEY *pubkey;
1247 gnutls_datum_t p, q, g, y, x;
1248 ULONG size = key->u.a.bitlen / 8;
1249 UCHAR *dst;
1250 int ret;
1252 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1254 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1256 pgnutls_perror( ret );
1257 return STATUS_INTERNAL_ERROR;
1260 if (q.size > 21 || x.size > 21)
1262 ERR( "can't export key in this format\n" );
1263 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1264 return STATUS_NOT_SUPPORTED;
1267 *ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1268 EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1269 if (len >= *ret_len && buf)
1271 hdr = (BLOBHEADER *)buf;
1272 hdr->bType = PRIVATEKEYBLOB;
1273 hdr->bVersion = 2;
1274 hdr->reserved = 0;
1275 hdr->aiKeyAlg = CALG_DSS_SIGN;
1277 pubkey = (DSSPUBKEY *)(hdr + 1);
1278 pubkey->magic = MAGIC_DSS2;
1279 pubkey->bitlen = key->u.a.bitlen;
1281 dst = (UCHAR *)(pubkey + 1);
1282 export_gnutls_datum( dst, size, &p, 1 );
1283 reverse_bytes( dst, size );
1284 dst += size;
1286 export_gnutls_datum( dst, 20, &q, 1 );
1287 reverse_bytes( dst, 20 );
1288 dst += 20;
1290 export_gnutls_datum( dst, size, &g, 1 );
1291 reverse_bytes( dst, size );
1292 dst += size;
1294 export_gnutls_datum( dst, 20, &x, 1 );
1295 reverse_bytes( dst, 20 );
1296 dst += 20;
1298 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1301 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1302 return STATUS_SUCCESS;
1305 static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1307 BLOBHEADER *hdr = (BLOBHEADER *)buf;
1308 DSSPUBKEY *pubkey;
1309 gnutls_privkey_t handle;
1310 gnutls_datum_t p, q, g, x;
1311 unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1312 int i, ret, size;
1314 if ((ret = pgnutls_privkey_init( &handle )))
1316 pgnutls_perror( ret );
1317 return STATUS_INTERNAL_ERROR;
1320 pubkey = (DSSPUBKEY *)(hdr + 1);
1321 if ((size = pubkey->bitlen / 8) > sizeof(p_data))
1323 FIXME( "size %u not supported\n", size );
1324 pgnutls_privkey_deinit( handle );
1325 return STATUS_NOT_SUPPORTED;
1327 data = (unsigned char *)(pubkey + 1);
1329 p.data = p_data;
1330 p.size = size;
1331 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1332 data += p.size;
1334 q.data = q_data;
1335 q.size = sizeof(q_data);
1336 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1337 data += q.size;
1339 g.data = g_data;
1340 g.size = size;
1341 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1342 data += g.size;
1344 x.data = x_data;
1345 x.size = sizeof(x_data);
1346 for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1347 data += x.size;
1349 if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1351 pgnutls_perror( ret );
1352 pgnutls_privkey_deinit( handle );
1353 return STATUS_INTERNAL_ERROR;
1356 memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1358 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1359 key_data(key)->a.privkey = handle;
1360 return STATUS_SUCCESS;
1363 static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1365 BCRYPT_ECCKEY_BLOB *ecc_blob;
1366 gnutls_ecc_curve_t curve;
1367 gnutls_datum_t x, y;
1368 gnutls_pubkey_t handle;
1369 int ret;
1371 switch (key->alg_id)
1373 case ALG_ID_ECDH_P256:
1374 case ALG_ID_ECDSA_P256:
1375 curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1377 case ALG_ID_ECDH_P384:
1378 case ALG_ID_ECDSA_P384:
1379 curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1381 default:
1382 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1383 return STATUS_NOT_IMPLEMENTED;
1386 if ((ret = pgnutls_pubkey_init( &handle )))
1388 pgnutls_perror( ret );
1389 return STATUS_INTERNAL_ERROR;
1392 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1393 x.data = buf + sizeof(*ecc_blob);
1394 x.size = ecc_blob->cbKey;
1395 y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1396 y.size = ecc_blob->cbKey;
1398 if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1400 pgnutls_perror( ret );
1401 pgnutls_pubkey_deinit( handle );
1402 return STATUS_INTERNAL_ERROR;
1405 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1406 key_data(key)->a.pubkey = handle;
1407 return STATUS_SUCCESS;
1410 static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1412 BCRYPT_RSAKEY_BLOB *rsa_blob;
1413 gnutls_pubkey_t handle;
1414 gnutls_datum_t m, e;
1415 int ret;
1417 if ((ret = pgnutls_pubkey_init( &handle )))
1419 pgnutls_perror( ret );
1420 return STATUS_INTERNAL_ERROR;
1423 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1424 e.data = buf + sizeof(*rsa_blob);
1425 e.size = rsa_blob->cbPublicExp;
1426 m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1427 m.size = rsa_blob->cbModulus;
1429 if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1431 pgnutls_perror( ret );
1432 pgnutls_pubkey_deinit( handle );
1433 return STATUS_INTERNAL_ERROR;
1436 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1437 key_data(key)->a.pubkey = handle;
1438 return STATUS_SUCCESS;
1441 static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1443 BCRYPT_DSA_KEY_BLOB *dsa_blob;
1444 gnutls_datum_t p, q, g, y;
1445 gnutls_pubkey_t handle;
1446 int ret;
1448 if ((ret = pgnutls_pubkey_init( &handle )))
1450 pgnutls_perror( ret );
1451 return STATUS_INTERNAL_ERROR;
1454 dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1455 p.data = buf + sizeof(*dsa_blob);
1456 p.size = dsa_blob->cbKey;
1457 q.data = dsa_blob->q;
1458 q.size = sizeof(dsa_blob->q);
1459 g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1460 g.size = dsa_blob->cbKey;
1461 y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1462 y.size = dsa_blob->cbKey;
1464 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1466 pgnutls_perror( ret );
1467 pgnutls_pubkey_deinit( handle );
1468 return STATUS_INTERNAL_ERROR;
1471 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1472 key_data(key)->a.pubkey = handle;
1473 return STATUS_SUCCESS;
1476 static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1478 BLOBHEADER *hdr;
1479 DSSPUBKEY *pubkey;
1480 gnutls_datum_t p, q, g, y;
1481 gnutls_pubkey_t handle;
1482 unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1483 int i, ret, size;
1485 if ((ret = pgnutls_pubkey_init( &handle )))
1487 pgnutls_perror( ret );
1488 return STATUS_INTERNAL_ERROR;
1491 hdr = (BLOBHEADER *)buf;
1492 pubkey = (DSSPUBKEY *)(hdr + 1);
1493 size = pubkey->bitlen / 8;
1494 data = (unsigned char *)(pubkey + 1);
1496 p.data = p_data;
1497 p.size = size;
1498 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1499 data += p.size;
1501 q.data = q_data;
1502 q.size = sizeof(q_data);
1503 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1504 data += q.size;
1506 g.data = g_data;
1507 g.size = size;
1508 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1509 data += g.size;
1511 y.data = y_data;
1512 y.size = sizeof(y_data);
1513 for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1515 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1517 pgnutls_perror( ret );
1518 pgnutls_pubkey_deinit( handle );
1519 return STATUS_INTERNAL_ERROR;
1522 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1523 key_data(key)->a.pubkey = handle;
1524 return STATUS_SUCCESS;
1527 static NTSTATUS key_asymmetric_export( void *args )
1529 const struct key_asymmetric_export_params *params = args;
1530 struct key *key = params->key;
1531 unsigned flags = params->flags;
1533 switch (key->alg_id)
1535 case ALG_ID_ECDH_P256:
1536 case ALG_ID_ECDH_P384:
1537 case ALG_ID_ECDSA_P256:
1538 case ALG_ID_ECDSA_P384:
1539 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1540 return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1541 return key_export_ecc( key, params->buf, params->len, params->ret_len );
1543 case ALG_ID_RSA:
1544 case ALG_ID_RSA_SIGN:
1545 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1546 return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1547 return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1549 case ALG_ID_DSA:
1550 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1552 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1553 return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1554 return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1556 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1557 return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1558 return STATUS_NOT_IMPLEMENTED;
1560 default:
1561 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1562 return STATUS_NOT_IMPLEMENTED;
1566 static NTSTATUS key_asymmetric_import( void *args )
1568 const struct key_asymmetric_import_params *params = args;
1569 struct key *key = params->key;
1570 unsigned flags = params->flags;
1571 gnutls_pubkey_t pubkey;
1572 NTSTATUS ret;
1574 switch (key->alg_id)
1576 case ALG_ID_ECDH_P256:
1577 case ALG_ID_ECDH_P384:
1578 case ALG_ID_ECDSA_P256:
1579 case ALG_ID_ECDSA_P384:
1580 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1581 return key_import_ecc_public( key, params->buf, params->len );
1582 ret = key_import_ecc( key, params->buf, params->len );
1583 break;
1585 case ALG_ID_RSA:
1586 case ALG_ID_RSA_SIGN:
1587 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1588 return key_import_rsa_public( key, params->buf, params->len );
1589 ret = key_import_rsa( key, params->buf, params->len );
1590 break;
1592 case ALG_ID_DSA:
1593 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1595 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1596 return key_import_dsa_capi_public( key, params->buf, params->len );
1597 return key_import_dsa_public( key, params->buf, params->len );
1599 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1601 ret = key_import_dsa_capi( key, params->buf, params->len );
1602 break;
1604 FIXME( "DSA private key not supported\n" );
1605 return STATUS_NOT_IMPLEMENTED;
1607 default:
1608 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1609 return STATUS_NOT_IMPLEMENTED;
1612 if (ret) return ret;
1614 if ((ret = pgnutls_pubkey_init( &pubkey )))
1616 pgnutls_perror( ret );
1617 return STATUS_INTERNAL_ERROR;
1620 if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 ))
1622 /* Imported private key may be legitimately missing public key, so ignore the failure here. */
1623 pgnutls_pubkey_deinit( pubkey );
1625 else
1627 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1628 key_data(key)->a.pubkey = pubkey;
1630 return STATUS_SUCCESS;
1633 static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
1634 gnutls_datum_t *gnutls_signature )
1636 struct buffer buffer;
1637 DWORD r_len = signature_len / 2;
1638 DWORD s_len = r_len;
1639 BYTE *r = signature;
1640 BYTE *s = signature + r_len;
1642 buffer_init( &buffer );
1643 buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
1644 if (buffer.error)
1646 buffer_free( &buffer );
1647 return STATUS_NO_MEMORY;
1650 gnutls_signature->data = buffer.buffer;
1651 gnutls_signature->size = buffer.pos;
1652 return STATUS_SUCCESS;
1655 static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
1656 gnutls_datum_t *gnutls_signature )
1658 gnutls_signature->data = signature;
1659 gnutls_signature->size = signature_len;
1660 return STATUS_SUCCESS;
1663 static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
1664 gnutls_datum_t *gnutls_signature )
1666 switch (key->alg_id)
1668 case ALG_ID_ECDSA_P256:
1669 case ALG_ID_ECDSA_P384:
1670 case ALG_ID_DSA:
1671 return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
1673 case ALG_ID_RSA:
1674 case ALG_ID_RSA_SIGN:
1675 return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
1677 default:
1678 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1679 return STATUS_NOT_IMPLEMENTED;
1683 static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
1685 if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
1686 if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
1687 if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
1688 if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
1689 if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
1690 if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
1691 return GNUTLS_DIG_UNKNOWN;
1694 static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
1696 gnutls_x509_spki_t spki;
1697 int ret;
1699 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
1701 pgnutls_perror( ret );
1702 return STATUS_INTERNAL_ERROR;
1704 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
1705 ret = pgnutls_pubkey_set_spki( key, spki, 0 );
1706 pgnutls_x509_spki_deinit( spki );
1707 if (ret < 0)
1709 pgnutls_perror( ret );
1710 return STATUS_INTERNAL_ERROR;
1712 return STATUS_SUCCESS;
1715 static NTSTATUS key_asymmetric_verify( void *args )
1717 #ifdef GNUTLS_VERIFY_ALLOW_BROKEN
1718 static const unsigned int verify_flags = GNUTLS_VERIFY_ALLOW_BROKEN;
1719 #else
1720 static const unsigned int verify_flags = 0;
1721 #endif
1722 const struct key_asymmetric_verify_params *params = args;
1723 struct key *key = params->key;
1724 unsigned flags = params->flags;
1725 gnutls_digest_algorithm_t hash_alg;
1726 gnutls_sign_algorithm_t sign_alg;
1727 gnutls_datum_t gnutls_hash, gnutls_signature;
1728 gnutls_pk_algorithm_t pk_alg;
1729 NTSTATUS status;
1730 int ret;
1732 switch (key->alg_id)
1734 case ALG_ID_ECDSA_P256:
1735 case ALG_ID_ECDSA_P384:
1737 if (flags) FIXME( "flags %#x not supported\n", flags );
1739 /* only the hash size must match, not the actual hash function */
1740 switch (params->hash_len)
1742 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1743 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1744 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1746 default:
1747 FIXME( "hash size %u not yet supported\n", params->hash_len );
1748 return STATUS_INVALID_SIGNATURE;
1750 pk_alg = GNUTLS_PK_ECC;
1751 break;
1753 case ALG_ID_RSA:
1754 case ALG_ID_RSA_SIGN:
1756 if (flags & BCRYPT_PAD_PKCS1)
1758 BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
1760 if (!info) return STATUS_INVALID_PARAMETER;
1761 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1762 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1764 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1765 return STATUS_NOT_SUPPORTED;
1767 pk_alg = GNUTLS_PK_RSA;
1769 else if (flags & BCRYPT_PAD_PSS)
1771 BCRYPT_PSS_PADDING_INFO *info = params->padding;
1773 if (!info) return STATUS_INVALID_PARAMETER;
1774 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1775 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1777 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1778 return STATUS_NOT_SUPPORTED;
1780 if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
1781 pk_alg = GNUTLS_PK_RSA_PSS;
1783 else return STATUS_INVALID_PARAMETER;
1784 break;
1786 case ALG_ID_DSA:
1788 if (flags) FIXME( "flags %#x not supported\n", flags );
1789 if (params->hash_len != 20)
1791 FIXME( "hash size %u not supported\n", params->hash_len );
1792 return STATUS_INVALID_PARAMETER;
1794 hash_alg = GNUTLS_DIG_SHA1;
1795 pk_alg = GNUTLS_PK_DSA;
1796 break;
1798 default:
1799 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1800 return STATUS_NOT_IMPLEMENTED;
1803 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
1805 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
1806 return STATUS_NOT_IMPLEMENTED;
1809 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
1810 return status;
1812 gnutls_hash.data = params->hash;
1813 gnutls_hash.size = params->hash_len;
1815 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, verify_flags, &gnutls_hash, &gnutls_signature );
1816 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
1817 return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
1820 static unsigned int get_signature_length( enum alg_id id )
1822 switch (id)
1824 case ALG_ID_ECDSA_P256: return 64;
1825 case ALG_ID_ECDSA_P384: return 96;
1826 case ALG_ID_DSA: return 40;
1827 default:
1828 FIXME( "unhandled algorithm %u\n", id );
1829 return 0;
1833 static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
1834 UCHAR *output, ULONG output_len, ULONG *ret_len )
1836 switch (type)
1838 case ALG_ID_RSA:
1839 case ALG_ID_RSA_SIGN:
1841 *ret_len = signature.size;
1842 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
1843 if (output) memcpy( output, signature.data, signature.size );
1844 return STATUS_SUCCESS;
1846 case ALG_ID_ECDSA_P256:
1847 case ALG_ID_ECDSA_P384:
1848 case ALG_ID_DSA:
1850 int err;
1851 unsigned int sig_len = get_signature_length( type );
1852 gnutls_datum_t r, s; /* format as r||s */
1854 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
1856 pgnutls_perror( err );
1857 return STATUS_INTERNAL_ERROR;
1860 *ret_len = sig_len;
1861 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
1863 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
1865 ERR( "we didn't get a correct signature\n" );
1866 return STATUS_INTERNAL_ERROR;
1869 if (output)
1871 export_gnutls_datum( output, sig_len / 2, &r, 1 );
1872 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
1875 free( r.data ); free( s.data );
1876 return STATUS_SUCCESS;
1878 default:
1879 return STATUS_INTERNAL_ERROR;
1883 static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
1885 gnutls_x509_spki_t spki;
1886 int ret;
1888 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
1890 pgnutls_perror( ret );
1891 return STATUS_INTERNAL_ERROR;
1893 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
1894 ret = pgnutls_privkey_set_spki( key, spki, 0 );
1895 pgnutls_x509_spki_deinit( spki );
1896 if (ret < 0)
1898 pgnutls_perror( ret );
1899 return STATUS_INTERNAL_ERROR;
1901 return STATUS_SUCCESS;
1904 static NTSTATUS key_asymmetric_sign( void *args )
1906 const struct key_asymmetric_sign_params *params = args;
1907 struct key *key = params->key;
1908 unsigned int flags = params->flags, gnutls_flags = 0;
1909 gnutls_datum_t hash, signature;
1910 gnutls_digest_algorithm_t hash_alg;
1911 NTSTATUS status;
1912 int ret;
1914 if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
1916 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1917 switch (params->input_len)
1919 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1920 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1921 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1922 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
1924 default:
1925 FIXME( "hash size %u not yet supported\n", params->input_len );
1926 return STATUS_INVALID_PARAMETER;
1929 if (flags == BCRYPT_PAD_PKCS1)
1931 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1932 if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
1934 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
1935 return STATUS_INVALID_PARAMETER;
1939 else if (key->alg_id == ALG_ID_DSA)
1941 if (flags) FIXME( "flags %#x not supported\n", flags );
1942 if (params->input_len != 20)
1944 FIXME( "hash size %u not supported\n", params->input_len );
1945 return STATUS_INVALID_PARAMETER;
1947 hash_alg = GNUTLS_DIG_SHA1;
1949 else if (flags == BCRYPT_PAD_PKCS1)
1951 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1953 if (!pad || !pad->pszAlgId)
1955 WARN( "padding info not found\n" );
1956 return STATUS_INVALID_PARAMETER;
1958 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1960 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1961 return STATUS_NOT_SUPPORTED;
1964 else if (flags == BCRYPT_PAD_PSS)
1966 BCRYPT_PSS_PADDING_INFO *pad = params->padding;
1968 if (!pad || !pad->pszAlgId)
1970 WARN( "padding info not found\n" );
1971 return STATUS_INVALID_PARAMETER;
1973 if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
1975 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
1976 return STATUS_NOT_SUPPORTED;
1978 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1980 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1981 return STATUS_NOT_SUPPORTED;
1984 if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
1985 gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
1987 else if (!flags)
1989 WARN( "invalid flags %#x\n", flags );
1990 return STATUS_INVALID_PARAMETER;
1992 else
1994 FIXME( "flags %#x not implemented\n", flags );
1995 return STATUS_NOT_IMPLEMENTED;
1998 if (!params->output)
2000 *params->ret_len = key->u.a.bitlen / 8;
2001 return STATUS_SUCCESS;
2003 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2005 hash.data = params->input;
2006 hash.size = params->input_len;
2008 signature.data = NULL;
2009 signature.size = 0;
2011 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2013 pgnutls_perror( ret );
2014 return STATUS_INTERNAL_ERROR;
2017 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2018 free( signature.data );
2019 return status;
2022 static NTSTATUS key_asymmetric_destroy( void *args )
2024 struct key *key = args;
2026 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2027 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2028 return STATUS_SUCCESS;
2031 static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2033 gnutls_privkey_t privkey;
2034 int ret;
2036 if ((ret = pgnutls_privkey_init( &privkey )))
2038 pgnutls_perror( ret );
2039 return STATUS_INTERNAL_ERROR;
2042 switch (key_orig->alg_id)
2044 case ALG_ID_RSA:
2045 case ALG_ID_RSA_SIGN:
2047 gnutls_datum_t m, e, d, p, q, u, e1, e2;
2048 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2050 pgnutls_perror( ret );
2051 return STATUS_INTERNAL_ERROR;
2053 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2054 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2055 free( e1.data ); free( e2.data );
2056 if (ret)
2058 pgnutls_perror( ret );
2059 return STATUS_INTERNAL_ERROR;
2061 break;
2063 case ALG_ID_DSA:
2065 gnutls_datum_t p, q, g, y, x;
2066 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
2068 pgnutls_perror( ret );
2069 return STATUS_INTERNAL_ERROR;
2071 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2072 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2073 if (ret)
2075 pgnutls_perror( ret );
2076 return STATUS_INTERNAL_ERROR;
2078 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2079 break;
2081 case ALG_ID_ECDH_P256:
2082 case ALG_ID_ECDH_P384:
2083 case ALG_ID_ECDSA_P256:
2084 case ALG_ID_ECDSA_P384:
2086 gnutls_ecc_curve_t curve;
2087 gnutls_datum_t x, y, k;
2088 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
2090 pgnutls_perror( ret );
2091 return STATUS_INTERNAL_ERROR;
2093 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2094 free( x.data ); free( y.data ); free( k.data );
2095 if (ret)
2097 pgnutls_perror( ret );
2098 return STATUS_INTERNAL_ERROR;
2100 break;
2102 default:
2103 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2104 return STATUS_INTERNAL_ERROR;
2107 key_data(key_copy)->a.privkey = privkey;
2108 return STATUS_SUCCESS;
2111 static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2113 gnutls_pubkey_t pubkey;
2114 int ret;
2116 if ((ret = pgnutls_pubkey_init( &pubkey )))
2118 pgnutls_perror( ret );
2119 return STATUS_INTERNAL_ERROR;
2122 switch (key_orig->alg_id)
2124 case ALG_ID_RSA:
2125 case ALG_ID_RSA_SIGN:
2127 gnutls_datum_t m, e;
2128 if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e )))
2130 pgnutls_perror( ret );
2131 return STATUS_INTERNAL_ERROR;
2133 ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2134 free( m.data ); free( e.data );
2135 if (ret)
2137 pgnutls_perror( ret );
2138 return STATUS_INTERNAL_ERROR;
2140 break;
2142 case ALG_ID_DSA:
2144 gnutls_datum_t p, q, g, y;
2145 if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y )))
2147 pgnutls_perror( ret );
2148 return STATUS_INTERNAL_ERROR;
2150 ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2151 free( p.data ); free( q.data ); free( g.data ); free( y.data );
2152 if (ret)
2154 pgnutls_perror( ret );
2155 return STATUS_INTERNAL_ERROR;
2157 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2158 break;
2160 case ALG_ID_ECDH_P256:
2161 case ALG_ID_ECDH_P384:
2162 case ALG_ID_ECDSA_P256:
2163 case ALG_ID_ECDSA_P384:
2165 gnutls_ecc_curve_t curve;
2166 gnutls_datum_t x, y;
2167 if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y )))
2169 pgnutls_perror( ret );
2170 return STATUS_INTERNAL_ERROR;
2172 ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2173 free( x.data ); free( y.data );
2174 if (ret)
2176 pgnutls_perror( ret );
2177 return STATUS_INTERNAL_ERROR;
2179 break;
2181 default:
2182 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2183 return STATUS_INTERNAL_ERROR;
2186 key_data(key_copy)->a.pubkey = pubkey;
2187 return STATUS_SUCCESS;
2190 static NTSTATUS key_asymmetric_duplicate( void *args )
2192 const struct key_asymmetric_duplicate_params *params = args;
2193 NTSTATUS status;
2195 if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2196 return status;
2198 if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2199 return status;
2201 return STATUS_SUCCESS;
2204 static NTSTATUS key_asymmetric_decrypt( void *args )
2206 const struct key_asymmetric_decrypt_params *params = args;
2207 gnutls_datum_t e, d = { 0 };
2208 NTSTATUS status = STATUS_SUCCESS;
2209 int ret;
2211 e.data = params->input;
2212 e.size = params->input_len;
2213 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2215 pgnutls_perror( ret );
2216 return STATUS_INTERNAL_ERROR;
2219 *params->ret_len = d.size;
2220 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2221 else status = STATUS_BUFFER_TOO_SMALL;
2223 free( d.data );
2224 return status;
2227 static NTSTATUS key_asymmetric_encrypt( void *args )
2229 const struct key_asymmetric_encrypt_params *params = args;
2230 gnutls_datum_t d, e = { 0 };
2231 NTSTATUS status = STATUS_SUCCESS;
2232 int ret;
2234 if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2236 d.data = params->input;
2237 d.size = params->input_len;
2238 if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2240 pgnutls_perror( ret );
2241 return STATUS_INTERNAL_ERROR;
2244 *params->ret_len = e.size;
2245 if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2246 else if (params->output_len == 0) status = STATUS_SUCCESS;
2247 else status = STATUS_BUFFER_TOO_SMALL;
2249 free( e.data );
2250 return status;
2253 const unixlib_entry_t __wine_unix_call_funcs[] =
2255 gnutls_process_attach,
2256 gnutls_process_detach,
2257 key_symmetric_vector_reset,
2258 key_symmetric_set_auth_data,
2259 key_symmetric_encrypt,
2260 key_symmetric_decrypt,
2261 key_symmetric_get_tag,
2262 key_symmetric_destroy,
2263 key_asymmetric_generate,
2264 key_asymmetric_decrypt,
2265 key_asymmetric_encrypt,
2266 key_asymmetric_duplicate,
2267 key_asymmetric_sign,
2268 key_asymmetric_verify,
2269 key_asymmetric_destroy,
2270 key_asymmetric_export,
2271 key_asymmetric_import
2274 #ifdef _WIN64
2276 typedef ULONG PTR32;
2278 struct key_symmetric32
2280 enum chain_mode mode;
2281 ULONG block_size;
2282 PTR32 vector;
2283 ULONG vector_len;
2284 PTR32 secret;
2285 ULONG secret_len;
2286 ULONG __cs[6];
2289 struct key_asymmetric32
2291 ULONG bitlen; /* ignored for ECC keys */
2292 ULONG flags;
2293 DSSSEED dss_seed;
2296 struct key32
2298 struct object hdr;
2299 enum alg_id alg_id;
2300 UINT64 private[2]; /* private data for backend */
2301 union
2303 struct key_symmetric32 s;
2304 struct key_asymmetric32 a;
2305 } u;
2308 union padding
2310 BCRYPT_PKCS1_PADDING_INFO pkcs1;
2311 BCRYPT_PSS_PADDING_INFO pss;
2314 union padding32
2316 struct
2318 PTR32 pszAlgId;
2319 } pkcs1;
2320 struct
2322 PTR32 pszAlgId;
2323 ULONG cbSalt;
2324 } pss;
2327 static union padding *get_padding( union padding32 *padding32, union padding *padding, ULONG flags)
2329 if (!padding32) return NULL;
2331 switch (flags)
2333 case BCRYPT_PAD_PKCS1:
2334 padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
2335 return padding;
2336 case BCRYPT_PAD_PSS:
2337 padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
2338 padding->pss.cbSalt = padding32->pss.cbSalt;
2339 return padding;
2340 default:
2341 break;
2343 return NULL;
2346 static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
2348 key->hdr = key32->hdr;
2349 key->alg_id = key32->alg_id;
2350 key->private[0] = key32->private[0];
2351 key->private[1] = key32->private[1];
2352 key->u.s.mode = key32->u.s.mode;
2353 key->u.s.block_size = key32->u.s.block_size;
2354 key->u.s.vector = ULongToPtr(key32->u.s.vector);
2355 key->u.s.vector_len = key32->u.s.vector_len;
2356 key->u.s.secret = ULongToPtr(key32->u.s.secret);
2357 key->u.s.secret_len = key32->u.s.secret_len;
2358 return key;
2361 static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2363 key->hdr = key32->hdr;
2364 key->alg_id = key32->alg_id;
2365 key->private[0] = key32->private[0];
2366 key->private[1] = key32->private[1];
2367 key->u.a.bitlen = key32->u.a.bitlen;
2368 key->u.a.flags = key32->u.a.flags;
2369 key->u.a.dss_seed = key32->u.a.dss_seed;
2370 return key;
2373 static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2375 key32->private[0] = key->private[0];
2376 key32->private[1] = key->private[1];
2379 static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2381 key32->private[0] = key->private[0];
2382 key32->private[1] = key->private[1];
2383 key32->u.a.flags = key->u.a.flags;
2384 key32->u.a.dss_seed = key->u.a.dss_seed;
2387 static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
2389 NTSTATUS ret;
2390 struct key key;
2391 struct key32 *key32 = args;
2393 ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
2394 put_symmetric_key32( &key, key32 );
2395 return ret;
2398 static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
2400 struct
2402 PTR32 key;
2403 PTR32 auth_data;
2404 ULONG len;
2405 } const *params32 = args;
2407 NTSTATUS ret;
2408 struct key key;
2409 struct key32 *key32 = ULongToPtr( params32->key );
2410 struct key_symmetric_set_auth_data_params params =
2412 get_symmetric_key( key32, &key ),
2413 ULongToPtr(params32->auth_data),
2414 params32->len
2417 ret = key_symmetric_set_auth_data( &params );
2418 put_symmetric_key32( &key, key32 );
2419 return ret;
2422 static NTSTATUS wow64_key_symmetric_encrypt( void *args )
2424 struct
2426 PTR32 key;
2427 PTR32 input;
2428 ULONG input_len;
2429 PTR32 output;
2430 ULONG output_len;
2431 } const *params32 = args;
2433 NTSTATUS ret;
2434 struct key key;
2435 struct key32 *key32 = ULongToPtr( params32->key );
2436 struct key_symmetric_encrypt_params params =
2438 get_symmetric_key( key32, &key ),
2439 ULongToPtr(params32->input),
2440 params32->input_len,
2441 ULongToPtr(params32->output),
2442 params32->output_len
2445 ret = key_symmetric_encrypt( &params );
2446 put_symmetric_key32( &key, key32 );
2447 return ret;
2450 static NTSTATUS wow64_key_symmetric_decrypt( void *args )
2452 struct
2454 PTR32 key;
2455 PTR32 input;
2456 ULONG input_len;
2457 PTR32 output;
2458 ULONG output_len;
2459 } const *params32 = args;
2461 NTSTATUS ret;
2462 struct key key;
2463 struct key32 *key32 = ULongToPtr( params32->key );
2464 struct key_symmetric_decrypt_params params =
2466 get_symmetric_key( key32, &key ),
2467 ULongToPtr(params32->input),
2468 params32->input_len,
2469 ULongToPtr(params32->output),
2470 params32->output_len
2473 ret = key_symmetric_decrypt( &params );
2474 put_symmetric_key32( &key, key32 );
2475 return ret;
2478 static NTSTATUS wow64_key_symmetric_get_tag( void *args )
2480 struct
2482 PTR32 key;
2483 PTR32 tag;
2484 ULONG len;
2485 } const *params32 = args;
2487 NTSTATUS ret;
2488 struct key key;
2489 struct key32 *key32 = ULongToPtr( params32->key );
2490 struct key_symmetric_get_tag_params params =
2492 get_symmetric_key( key32, &key ),
2493 ULongToPtr(params32->tag),
2494 params32->len
2497 ret = key_symmetric_get_tag( &params );
2498 put_symmetric_key32( &key, key32 );
2499 return ret;
2502 static NTSTATUS wow64_key_symmetric_destroy( void *args )
2504 struct key32 *key32 = args;
2505 struct key key;
2507 return key_symmetric_destroy( get_symmetric_key( key32, &key ));
2510 static NTSTATUS wow64_key_asymmetric_generate( void *args )
2512 struct key32 *key32 = args;
2513 struct key key;
2514 NTSTATUS ret;
2516 ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
2517 put_asymmetric_key32( &key, key32 );
2518 return ret;
2521 static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
2523 struct
2525 PTR32 key;
2526 PTR32 input;
2527 ULONG input_len;
2528 PTR32 output;
2529 ULONG output_len;
2530 PTR32 ret_len;
2531 } const *params32 = args;
2533 NTSTATUS ret;
2534 struct key key;
2535 struct key32 *key32 = ULongToPtr( params32->key );
2536 struct key_asymmetric_decrypt_params params =
2538 get_asymmetric_key( key32, &key ),
2539 ULongToPtr(params32->input),
2540 params32->input_len,
2541 ULongToPtr(params32->output),
2542 params32->output_len,
2543 ULongToPtr(params32->ret_len)
2546 ret = key_asymmetric_decrypt( &params );
2547 put_asymmetric_key32( &key, key32 );
2548 return ret;
2551 static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
2553 struct
2555 PTR32 key;
2556 PTR32 input;
2557 ULONG input_len;
2558 PTR32 output;
2559 ULONG output_len;
2560 PTR32 ret_len;
2561 } const *params32 = args;
2563 NTSTATUS ret;
2564 struct key key;
2565 struct key32 *key32 = ULongToPtr( params32->key );
2566 struct key_asymmetric_encrypt_params params =
2568 get_asymmetric_key( key32, &key ),
2569 ULongToPtr(params32->input),
2570 params32->input_len,
2571 ULongToPtr(params32->output),
2572 params32->output_len,
2573 ULongToPtr(params32->ret_len)
2576 ret = key_asymmetric_encrypt( &params );
2577 put_asymmetric_key32( &key, key32 );
2578 return ret;
2581 static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
2583 struct
2585 PTR32 key_orig;
2586 PTR32 key_copy;
2587 } const *params32 = args;
2589 NTSTATUS ret;
2590 struct key key_orig, key_copy;
2591 struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
2592 struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
2593 struct key_asymmetric_duplicate_params params =
2595 get_asymmetric_key( key_orig32, &key_orig ),
2596 get_asymmetric_key( key_copy32, &key_copy )
2599 ret = key_asymmetric_duplicate( &params );
2600 put_asymmetric_key32( &key_copy, key_copy32 );
2601 return ret;
2604 static NTSTATUS wow64_key_asymmetric_sign( void *args )
2606 struct
2608 PTR32 key;
2609 PTR32 padding;
2610 PTR32 input;
2611 ULONG input_len;
2612 PTR32 output;
2613 ULONG output_len;
2614 PTR32 ret_len;
2615 ULONG flags;
2616 } const *params32 = args;
2618 NTSTATUS ret;
2619 struct key key;
2620 union padding padding;
2621 struct key32 *key32 = ULongToPtr( params32->key );
2622 struct key_asymmetric_sign_params params =
2624 get_asymmetric_key( key32, &key ),
2625 get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
2626 ULongToPtr(params32->input),
2627 params32->input_len,
2628 ULongToPtr(params32->output),
2629 params32->output_len,
2630 ULongToPtr(params32->ret_len),
2631 params32->flags
2634 ret = key_asymmetric_sign( &params );
2635 put_asymmetric_key32( &key, key32 );
2636 return ret;
2639 static NTSTATUS wow64_key_asymmetric_verify( void *args )
2641 struct
2643 PTR32 key;
2644 PTR32 padding;
2645 PTR32 hash;
2646 ULONG hash_len;
2647 PTR32 signature;
2648 ULONG signature_len;
2649 ULONG flags;
2650 } const *params32 = args;
2652 NTSTATUS ret;
2653 struct key key;
2654 union padding padding;
2655 struct key32 *key32 = ULongToPtr( params32->key );
2656 struct key_asymmetric_verify_params params =
2658 get_asymmetric_key( key32, &key ),
2659 get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
2660 ULongToPtr(params32->hash),
2661 params32->hash_len,
2662 ULongToPtr(params32->signature),
2663 params32->signature_len,
2664 params32->flags
2667 ret = key_asymmetric_verify( &params );
2668 put_asymmetric_key32( &key, key32 );
2669 return ret;
2672 static NTSTATUS wow64_key_asymmetric_destroy( void *args )
2674 struct key32 *key32 = args;
2675 struct key key;
2677 return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
2680 static NTSTATUS wow64_key_asymmetric_export( void *args )
2682 struct
2684 PTR32 key;
2685 ULONG flags;
2686 PTR32 buf;
2687 ULONG len;
2688 PTR32 ret_len;
2689 } const *params32 = args;
2691 NTSTATUS ret;
2692 struct key key;
2693 struct key32 *key32 = ULongToPtr( params32->key );
2694 struct key_asymmetric_export_params params =
2696 get_asymmetric_key( key32, &key ),
2697 params32->flags,
2698 ULongToPtr(params32->buf),
2699 params32->len,
2700 ULongToPtr(params32->ret_len),
2703 ret = key_asymmetric_export( &params );
2704 put_asymmetric_key32( &key, key32 );
2705 return ret;
2708 static NTSTATUS wow64_key_asymmetric_import( void *args )
2710 struct
2712 PTR32 key;
2713 ULONG flags;
2714 PTR32 buf;
2715 ULONG len;
2716 } const *params32 = args;
2718 NTSTATUS ret;
2719 struct key key;
2720 struct key32 *key32 = ULongToPtr( params32->key );
2721 struct key_asymmetric_import_params params =
2723 get_asymmetric_key( key32, &key ),
2724 params32->flags,
2725 ULongToPtr(params32->buf),
2726 params32->len
2729 ret = key_asymmetric_import( &params );
2730 put_asymmetric_key32( &key, key32 );
2731 return ret;
2734 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
2736 gnutls_process_attach,
2737 gnutls_process_detach,
2738 wow64_key_symmetric_vector_reset,
2739 wow64_key_symmetric_set_auth_data,
2740 wow64_key_symmetric_encrypt,
2741 wow64_key_symmetric_decrypt,
2742 wow64_key_symmetric_get_tag,
2743 wow64_key_symmetric_destroy,
2744 wow64_key_asymmetric_generate,
2745 wow64_key_asymmetric_decrypt,
2746 wow64_key_asymmetric_encrypt,
2747 wow64_key_asymmetric_duplicate,
2748 wow64_key_asymmetric_sign,
2749 wow64_key_asymmetric_verify,
2750 wow64_key_asymmetric_destroy,
2751 wow64_key_asymmetric_export,
2752 wow64_key_asymmetric_import
2755 #endif /* _WIN64 */
2757 #endif /* HAVE_GNUTLS_CIPHER_INIT */