bcrypt: Add PSS compatibility defines.
[wine.git] / dlls / bcrypt / gnutls.c
blob70f55a6e8d693dcc6ab396acf221106713f75597
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 if (key_data(key)->a.privkey)
717 ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL );
718 else
719 return STATUS_INVALID_PARAMETER;
721 if (ret)
723 pgnutls_perror( ret );
724 return STATUS_INTERNAL_ERROR;
727 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
728 if (len >= *ret_len && buf)
730 dst = (UCHAR *)(rsa_blob + 1);
731 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
733 dst += rsa_blob->cbPublicExp;
734 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
736 rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
737 rsa_blob->BitLength = key->u.a.bitlen;
738 rsa_blob->cbPrime1 = 0;
739 rsa_blob->cbPrime2 = 0;
742 free( e.data ); free( m.data );
743 return STATUS_SUCCESS;
746 static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
748 BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
749 gnutls_ecc_curve_t curve;
750 gnutls_datum_t x, y;
751 DWORD magic, size;
752 UCHAR *dst;
753 int ret;
755 switch (key->alg_id)
757 case ALG_ID_ECDH_P256:
758 magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
759 size = 32;
760 break;
762 case ALG_ID_ECDH_P384:
763 magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
764 size = 48;
765 break;
767 case ALG_ID_ECDSA_P256:
768 magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
769 size = 32;
770 break;
772 case ALG_ID_ECDSA_P384:
773 magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
774 size = 48;
775 break;
777 default:
778 FIXME( "algorithm %u not supported\n", key->alg_id );
779 return STATUS_NOT_IMPLEMENTED;
782 if (key_data(key)->a.pubkey)
783 ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
784 else if (key_data(key)->a.privkey)
785 ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, NULL );
786 else
787 return STATUS_INVALID_PARAMETER;
789 if (ret)
791 pgnutls_perror( ret );
792 return STATUS_INTERNAL_ERROR;
795 if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1)
797 FIXME( "curve %u not supported\n", curve );
798 free( x.data ); free( y.data );
799 return STATUS_NOT_IMPLEMENTED;
802 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
803 if (len >= *ret_len && buf)
805 ecc_blob->dwMagic = magic;
806 ecc_blob->cbKey = size;
808 dst = (UCHAR *)(ecc_blob + 1);
809 dst += export_gnutls_datum( dst, size, &x, 1 );
810 export_gnutls_datum( dst, size, &y, 1 );
813 free( x.data ); free( y.data );
814 return STATUS_SUCCESS;
817 static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
819 BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
820 gnutls_datum_t p, q, g, y;
821 ULONG size = key->u.a.bitlen / 8;
822 NTSTATUS status = STATUS_SUCCESS;
823 UCHAR *dst;
824 int ret;
826 if (key->u.a.bitlen > 1024)
828 FIXME( "bitlen > 1024 not supported\n" );
829 return STATUS_NOT_IMPLEMENTED;
832 if (key_data(key)->a.pubkey)
833 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
834 else if (key_data(key)->a.privkey)
835 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
836 else
837 return STATUS_INVALID_PARAMETER;
839 if (ret)
841 pgnutls_perror( ret );
842 return STATUS_INTERNAL_ERROR;
845 if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
847 status = STATUS_INVALID_PARAMETER;
848 goto done;
851 *ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
852 if (len >= *ret_len && buf)
854 dst = (UCHAR *)(dsa_blob + 1);
855 dst += export_gnutls_datum( dst, size, &p, 1 );
856 dst += export_gnutls_datum( dst, size, &g, 1 );
857 export_gnutls_datum( dst, size, &y, 1 );
859 dst = dsa_blob->q;
860 export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
862 dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
863 dsa_blob->cbKey = size;
864 memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
865 memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
868 done:
869 free( p.data ); free( q.data ); free( g.data ); free( y.data );
870 return status;
873 static void reverse_bytes( UCHAR *buf, ULONG len )
875 unsigned int i;
876 UCHAR tmp;
878 for (i = 0; i < len / 2; ++i)
880 tmp = buf[i];
881 buf[i] = buf[len - i - 1];
882 buf[len - i - 1] = tmp;
886 #define Q_SIZE 20
887 static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
889 BLOBHEADER *hdr = (BLOBHEADER *)buf;
890 DSSPUBKEY *dsskey;
891 gnutls_datum_t p, q, g, y;
892 ULONG size = key->u.a.bitlen / 8;
893 NTSTATUS status = STATUS_SUCCESS;
894 UCHAR *dst;
895 int ret;
897 if (key->u.a.bitlen > 1024)
899 FIXME( "bitlen > 1024 not supported\n" );
900 return STATUS_NOT_IMPLEMENTED;
903 if (key_data(key)->a.pubkey)
904 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
905 else if (key_data(key)->a.privkey)
906 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
907 else
908 return STATUS_INVALID_PARAMETER;
910 if (ret)
912 pgnutls_perror( ret );
913 return STATUS_INTERNAL_ERROR;
916 if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
918 status = STATUS_INVALID_PARAMETER;
919 goto done;
922 *ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
923 EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
924 if (len >= *ret_len && buf)
926 hdr->bType = PUBLICKEYBLOB;
927 hdr->bVersion = 2;
928 hdr->reserved = 0;
929 hdr->aiKeyAlg = CALG_DSS_SIGN;
931 dsskey = (DSSPUBKEY *)(hdr + 1);
932 dsskey->magic = MAGIC_DSS1;
933 dsskey->bitlen = key->u.a.bitlen;
935 dst = (UCHAR *)(dsskey + 1);
936 export_gnutls_datum( dst, size, &p, 1 );
937 reverse_bytes( dst, size );
938 dst += size;
940 export_gnutls_datum( dst, Q_SIZE, &q, 1 );
941 reverse_bytes( dst, Q_SIZE );
942 dst += Q_SIZE;
944 export_gnutls_datum( dst, size, &g, 1 );
945 reverse_bytes( dst, size );
946 dst += size;
948 export_gnutls_datum( dst, size, &y, 1 );
949 reverse_bytes( dst, size );
950 dst += size;
952 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
955 done:
956 free( p.data ); free( q.data ); free( g.data ); free( y.data );
957 return status;
960 static NTSTATUS key_asymmetric_generate( void *args )
962 struct key *key = args;
963 gnutls_pk_algorithm_t pk_alg;
964 gnutls_privkey_t privkey;
965 gnutls_pubkey_t pubkey;
966 unsigned int bitlen;
967 int ret;
969 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
970 if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
972 switch (key->alg_id)
974 case ALG_ID_RSA:
975 case ALG_ID_RSA_SIGN:
976 pk_alg = GNUTLS_PK_RSA;
977 bitlen = key->u.a.bitlen;
978 break;
980 case ALG_ID_DSA:
981 pk_alg = GNUTLS_PK_DSA;
982 bitlen = key->u.a.bitlen;
983 break;
985 case ALG_ID_ECDH_P256:
986 case ALG_ID_ECDSA_P256:
987 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
988 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
989 break;
991 case ALG_ID_ECDH_P384:
992 case ALG_ID_ECDSA_P384:
993 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
994 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
995 break;
997 default:
998 FIXME( "algorithm %u not supported\n", key->alg_id );
999 return STATUS_NOT_SUPPORTED;
1002 if ((ret = pgnutls_privkey_init( &privkey )))
1004 pgnutls_perror( ret );
1005 return STATUS_INTERNAL_ERROR;
1007 if ((ret = pgnutls_pubkey_init( &pubkey )))
1009 pgnutls_perror( ret );
1010 pgnutls_privkey_deinit( privkey );
1011 return STATUS_INTERNAL_ERROR;
1014 if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
1016 pgnutls_perror( ret );
1017 pgnutls_privkey_deinit( privkey );
1018 pgnutls_pubkey_deinit( pubkey );
1019 return STATUS_INTERNAL_ERROR;
1021 if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1023 pgnutls_perror( ret );
1024 pgnutls_privkey_deinit( privkey );
1025 pgnutls_pubkey_deinit( pubkey );
1026 return STATUS_INTERNAL_ERROR;
1029 key_data(key)->a.privkey = privkey;
1030 key_data(key)->a.pubkey = pubkey;
1031 return STATUS_SUCCESS;
1034 static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1036 BCRYPT_ECCKEY_BLOB *ecc_blob;
1037 gnutls_ecc_curve_t curve;
1038 gnutls_datum_t x, y, d;
1039 DWORD magic, size;
1040 UCHAR *dst;
1041 int ret;
1043 switch (key->alg_id)
1045 case ALG_ID_ECDH_P256:
1046 magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1047 size = 32;
1048 break;
1050 case ALG_ID_ECDH_P384:
1051 magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1052 size = 48;
1053 break;
1055 case ALG_ID_ECDSA_P256:
1056 magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1057 size = 32;
1058 break;
1060 case ALG_ID_ECDSA_P384:
1061 magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1062 size = 48;
1063 break;
1065 default:
1066 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1067 return STATUS_NOT_IMPLEMENTED;
1070 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1072 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1074 pgnutls_perror( ret );
1075 return STATUS_INTERNAL_ERROR;
1078 if (curve != GNUTLS_ECC_CURVE_SECP256R1)
1080 FIXME( "curve %u not supported\n", curve );
1081 free( x.data ); free( y.data ); free( d.data );
1082 return STATUS_NOT_IMPLEMENTED;
1085 *ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1086 if (len >= *ret_len && buf)
1088 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1089 ecc_blob->dwMagic = magic;
1090 ecc_blob->cbKey = size;
1092 dst = (UCHAR *)(ecc_blob + 1);
1093 dst += export_gnutls_datum( dst, size, &x, 1 );
1094 dst += export_gnutls_datum( dst, size, &y, 1 );
1095 export_gnutls_datum( dst, size, &d, 1 );
1098 free( x.data ); free( y.data ); free( d.data );
1099 return STATUS_SUCCESS;
1102 static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1104 BCRYPT_ECCKEY_BLOB *ecc_blob;
1105 gnutls_ecc_curve_t curve;
1106 gnutls_privkey_t handle;
1107 gnutls_datum_t x, y, k;
1108 int ret;
1110 switch (key->alg_id)
1112 case ALG_ID_ECDH_P256:
1113 case ALG_ID_ECDSA_P256:
1114 curve = GNUTLS_ECC_CURVE_SECP256R1;
1115 break;
1117 case ALG_ID_ECDH_P384:
1118 case ALG_ID_ECDSA_P384:
1119 curve = GNUTLS_ECC_CURVE_SECP384R1;
1120 break;
1122 default:
1123 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1124 return STATUS_NOT_IMPLEMENTED;
1127 if ((ret = pgnutls_privkey_init( &handle )))
1129 pgnutls_perror( ret );
1130 return STATUS_INTERNAL_ERROR;
1133 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1134 x.data = (unsigned char *)(ecc_blob + 1);
1135 x.size = ecc_blob->cbKey;
1136 y.data = x.data + ecc_blob->cbKey;
1137 y.size = ecc_blob->cbKey;
1138 k.data = y.data + ecc_blob->cbKey;
1139 k.size = ecc_blob->cbKey;
1141 if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1143 pgnutls_perror( ret );
1144 pgnutls_privkey_deinit( handle );
1145 return STATUS_INTERNAL_ERROR;
1148 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1149 key_data(key)->a.privkey = handle;
1150 return STATUS_SUCCESS;
1153 static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1155 BCRYPT_RSAKEY_BLOB *rsa_blob;
1156 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1157 ULONG size = key->u.a.bitlen / 8;
1158 BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1159 UCHAR *dst;
1160 int ret;
1162 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1164 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1166 pgnutls_perror( ret );
1167 return STATUS_INTERNAL_ERROR;
1170 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1171 EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1173 if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1174 EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1176 if (len >= *ret_len && buf)
1178 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1179 rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1180 rsa_blob->BitLength = key->u.a.bitlen;
1182 dst = (UCHAR *)(rsa_blob + 1);
1183 rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1185 dst += rsa_blob->cbPublicExp;
1186 rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1188 dst += rsa_blob->cbModulus;
1189 rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1191 dst += rsa_blob->cbPrime1;
1192 rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1194 if (full)
1196 dst += rsa_blob->cbPrime2;
1197 export_gnutls_datum( dst, size / 2, &e1, 1 );
1199 dst += rsa_blob->cbPrime1;
1200 export_gnutls_datum( dst, size / 2, &e2, 1 );
1202 dst += rsa_blob->cbPrime2;
1203 export_gnutls_datum( dst, size / 2, &u, 1 );
1205 dst += rsa_blob->cbPrime1;
1206 export_gnutls_datum( dst, size, &d, 1 );
1210 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1211 free( e1.data ); free( e2.data );
1212 return STATUS_SUCCESS;
1215 static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1217 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1218 gnutls_datum_t m, e, p, q;
1219 gnutls_privkey_t handle;
1220 int ret;
1222 if ((ret = pgnutls_privkey_init( &handle )))
1224 pgnutls_perror( ret );
1225 return STATUS_INTERNAL_ERROR;
1228 e.data = (unsigned char *)(rsa_blob + 1);
1229 e.size = rsa_blob->cbPublicExp;
1230 m.data = e.data + e.size;
1231 m.size = rsa_blob->cbModulus;
1232 p.data = m.data + m.size;
1233 p.size = rsa_blob->cbPrime1;
1234 q.data = p.data + p.size;
1235 q.size = rsa_blob->cbPrime2;
1237 if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1239 pgnutls_perror( ret );
1240 pgnutls_privkey_deinit( handle );
1241 return STATUS_INTERNAL_ERROR;
1244 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1245 key_data(key)->a.privkey = handle;
1246 return STATUS_SUCCESS;
1249 static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1251 BLOBHEADER *hdr;
1252 DSSPUBKEY *pubkey;
1253 gnutls_datum_t p, q, g, y, x;
1254 ULONG size = key->u.a.bitlen / 8;
1255 UCHAR *dst;
1256 int ret;
1258 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1260 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1262 pgnutls_perror( ret );
1263 return STATUS_INTERNAL_ERROR;
1266 if (q.size > 21 || x.size > 21)
1268 ERR( "can't export key in this format\n" );
1269 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1270 return STATUS_NOT_SUPPORTED;
1273 *ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1274 EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1275 if (len >= *ret_len && buf)
1277 hdr = (BLOBHEADER *)buf;
1278 hdr->bType = PRIVATEKEYBLOB;
1279 hdr->bVersion = 2;
1280 hdr->reserved = 0;
1281 hdr->aiKeyAlg = CALG_DSS_SIGN;
1283 pubkey = (DSSPUBKEY *)(hdr + 1);
1284 pubkey->magic = MAGIC_DSS2;
1285 pubkey->bitlen = key->u.a.bitlen;
1287 dst = (UCHAR *)(pubkey + 1);
1288 export_gnutls_datum( dst, size, &p, 1 );
1289 reverse_bytes( dst, size );
1290 dst += size;
1292 export_gnutls_datum( dst, 20, &q, 1 );
1293 reverse_bytes( dst, 20 );
1294 dst += 20;
1296 export_gnutls_datum( dst, size, &g, 1 );
1297 reverse_bytes( dst, size );
1298 dst += size;
1300 export_gnutls_datum( dst, 20, &x, 1 );
1301 reverse_bytes( dst, 20 );
1302 dst += 20;
1304 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1307 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1308 return STATUS_SUCCESS;
1311 static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1313 BLOBHEADER *hdr = (BLOBHEADER *)buf;
1314 DSSPUBKEY *pubkey;
1315 gnutls_privkey_t handle;
1316 gnutls_datum_t p, q, g, x;
1317 unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1318 int i, ret, size;
1320 if ((ret = pgnutls_privkey_init( &handle )))
1322 pgnutls_perror( ret );
1323 return STATUS_INTERNAL_ERROR;
1326 pubkey = (DSSPUBKEY *)(hdr + 1);
1327 if ((size = pubkey->bitlen / 8) > sizeof(p_data))
1329 FIXME( "size %u not supported\n", size );
1330 pgnutls_privkey_deinit( handle );
1331 return STATUS_NOT_SUPPORTED;
1333 data = (unsigned char *)(pubkey + 1);
1335 p.data = p_data;
1336 p.size = size;
1337 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1338 data += p.size;
1340 q.data = q_data;
1341 q.size = sizeof(q_data);
1342 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1343 data += q.size;
1345 g.data = g_data;
1346 g.size = size;
1347 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1348 data += g.size;
1350 x.data = x_data;
1351 x.size = sizeof(x_data);
1352 for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1353 data += x.size;
1355 if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1357 pgnutls_perror( ret );
1358 pgnutls_privkey_deinit( handle );
1359 return STATUS_INTERNAL_ERROR;
1362 memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1364 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1365 key_data(key)->a.privkey = handle;
1366 return STATUS_SUCCESS;
1369 static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1371 BCRYPT_ECCKEY_BLOB *ecc_blob;
1372 gnutls_ecc_curve_t curve;
1373 gnutls_datum_t x, y;
1374 gnutls_pubkey_t handle;
1375 int ret;
1377 switch (key->alg_id)
1379 case ALG_ID_ECDH_P256:
1380 case ALG_ID_ECDSA_P256:
1381 curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1383 case ALG_ID_ECDH_P384:
1384 case ALG_ID_ECDSA_P384:
1385 curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1387 default:
1388 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1389 return STATUS_NOT_IMPLEMENTED;
1392 if ((ret = pgnutls_pubkey_init( &handle )))
1394 pgnutls_perror( ret );
1395 return STATUS_INTERNAL_ERROR;
1398 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1399 x.data = buf + sizeof(*ecc_blob);
1400 x.size = ecc_blob->cbKey;
1401 y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1402 y.size = ecc_blob->cbKey;
1404 if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1406 pgnutls_perror( ret );
1407 pgnutls_pubkey_deinit( handle );
1408 return STATUS_INTERNAL_ERROR;
1411 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1412 key_data(key)->a.pubkey = handle;
1413 return STATUS_SUCCESS;
1416 static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1418 BCRYPT_RSAKEY_BLOB *rsa_blob;
1419 gnutls_pubkey_t handle;
1420 gnutls_datum_t m, e;
1421 int ret;
1423 if ((ret = pgnutls_pubkey_init( &handle )))
1425 pgnutls_perror( ret );
1426 return STATUS_INTERNAL_ERROR;
1429 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1430 e.data = buf + sizeof(*rsa_blob);
1431 e.size = rsa_blob->cbPublicExp;
1432 m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1433 m.size = rsa_blob->cbModulus;
1435 if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1437 pgnutls_perror( ret );
1438 pgnutls_pubkey_deinit( handle );
1439 return STATUS_INTERNAL_ERROR;
1442 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1443 key_data(key)->a.pubkey = handle;
1444 return STATUS_SUCCESS;
1447 static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1449 BCRYPT_DSA_KEY_BLOB *dsa_blob;
1450 gnutls_datum_t p, q, g, y;
1451 gnutls_pubkey_t handle;
1452 int ret;
1454 if ((ret = pgnutls_pubkey_init( &handle )))
1456 pgnutls_perror( ret );
1457 return STATUS_INTERNAL_ERROR;
1460 dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1461 p.data = buf + sizeof(*dsa_blob);
1462 p.size = dsa_blob->cbKey;
1463 q.data = dsa_blob->q;
1464 q.size = sizeof(dsa_blob->q);
1465 g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1466 g.size = dsa_blob->cbKey;
1467 y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1468 y.size = dsa_blob->cbKey;
1470 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1472 pgnutls_perror( ret );
1473 pgnutls_pubkey_deinit( handle );
1474 return STATUS_INTERNAL_ERROR;
1477 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1478 key_data(key)->a.pubkey = handle;
1479 return STATUS_SUCCESS;
1482 static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1484 BLOBHEADER *hdr;
1485 DSSPUBKEY *pubkey;
1486 gnutls_datum_t p, q, g, y;
1487 gnutls_pubkey_t handle;
1488 unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1489 int i, ret, size;
1491 if ((ret = pgnutls_pubkey_init( &handle )))
1493 pgnutls_perror( ret );
1494 return STATUS_INTERNAL_ERROR;
1497 hdr = (BLOBHEADER *)buf;
1498 pubkey = (DSSPUBKEY *)(hdr + 1);
1499 size = pubkey->bitlen / 8;
1500 data = (unsigned char *)(pubkey + 1);
1502 p.data = p_data;
1503 p.size = size;
1504 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1505 data += p.size;
1507 q.data = q_data;
1508 q.size = sizeof(q_data);
1509 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1510 data += q.size;
1512 g.data = g_data;
1513 g.size = size;
1514 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1515 data += g.size;
1517 y.data = y_data;
1518 y.size = sizeof(y_data);
1519 for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1521 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1523 pgnutls_perror( ret );
1524 pgnutls_pubkey_deinit( handle );
1525 return STATUS_INTERNAL_ERROR;
1528 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1529 key_data(key)->a.pubkey = handle;
1530 return STATUS_SUCCESS;
1533 static NTSTATUS key_asymmetric_export( void *args )
1535 const struct key_asymmetric_export_params *params = args;
1536 struct key *key = params->key;
1537 unsigned flags = params->flags;
1539 switch (key->alg_id)
1541 case ALG_ID_ECDH_P256:
1542 case ALG_ID_ECDH_P384:
1543 case ALG_ID_ECDSA_P256:
1544 case ALG_ID_ECDSA_P384:
1545 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1546 return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1547 return key_export_ecc( key, params->buf, params->len, params->ret_len );
1549 case ALG_ID_RSA:
1550 case ALG_ID_RSA_SIGN:
1551 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1552 return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1553 return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1555 case ALG_ID_DSA:
1556 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1558 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1559 return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1560 return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1562 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1563 return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1564 return STATUS_NOT_IMPLEMENTED;
1566 default:
1567 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1568 return STATUS_NOT_IMPLEMENTED;
1572 static NTSTATUS key_asymmetric_import( void *args )
1574 const struct key_asymmetric_import_params *params = args;
1575 struct key *key = params->key;
1576 unsigned flags = params->flags;
1578 switch (key->alg_id)
1580 case ALG_ID_ECDH_P256:
1581 case ALG_ID_ECDH_P384:
1582 case ALG_ID_ECDSA_P256:
1583 case ALG_ID_ECDSA_P384:
1584 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1585 return key_import_ecc_public( key, params->buf, params->len );
1586 return key_import_ecc( key, params->buf, params->len );
1588 case ALG_ID_RSA:
1589 case ALG_ID_RSA_SIGN:
1590 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1591 return key_import_rsa_public( key, params->buf, params->len );
1592 return key_import_rsa( key, params->buf, params->len );
1594 case ALG_ID_DSA:
1595 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1597 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1598 return key_import_dsa_capi_public( key, params->buf, params->len );
1599 return key_import_dsa_public( key, params->buf, params->len );
1601 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1602 return key_import_dsa_capi( key, params->buf, params->len );
1603 FIXME( "DSA private key not supported\n" );
1604 return STATUS_NOT_IMPLEMENTED;
1606 default:
1607 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1608 return STATUS_NOT_IMPLEMENTED;
1612 static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
1613 gnutls_datum_t *gnutls_signature )
1615 struct buffer buffer;
1616 DWORD r_len = signature_len / 2;
1617 DWORD s_len = r_len;
1618 BYTE *r = signature;
1619 BYTE *s = signature + r_len;
1621 buffer_init( &buffer );
1622 buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
1623 if (buffer.error)
1625 buffer_free( &buffer );
1626 return STATUS_NO_MEMORY;
1629 gnutls_signature->data = buffer.buffer;
1630 gnutls_signature->size = buffer.pos;
1631 return STATUS_SUCCESS;
1634 static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
1635 gnutls_datum_t *gnutls_signature )
1637 gnutls_signature->data = signature;
1638 gnutls_signature->size = signature_len;
1639 return STATUS_SUCCESS;
1642 static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
1643 gnutls_datum_t *gnutls_signature )
1645 switch (key->alg_id)
1647 case ALG_ID_ECDSA_P256:
1648 case ALG_ID_ECDSA_P384:
1649 case ALG_ID_DSA:
1650 return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
1652 case ALG_ID_RSA:
1653 case ALG_ID_RSA_SIGN:
1654 return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
1656 default:
1657 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1658 return STATUS_NOT_IMPLEMENTED;
1662 static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
1664 if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
1665 if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
1666 if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
1667 if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
1668 if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
1669 if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
1670 return GNUTLS_DIG_UNKNOWN;
1673 static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
1675 gnutls_x509_spki_t spki;
1676 int ret;
1678 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
1680 pgnutls_perror( ret );
1681 return STATUS_INTERNAL_ERROR;
1683 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
1684 ret = pgnutls_pubkey_set_spki( key, spki, 0 );
1685 pgnutls_x509_spki_deinit( spki );
1686 if (ret < 0)
1688 pgnutls_perror( ret );
1689 return STATUS_INTERNAL_ERROR;
1691 return STATUS_SUCCESS;
1694 static NTSTATUS key_asymmetric_verify( void *args )
1696 const struct key_asymmetric_verify_params *params = args;
1697 struct key *key = params->key;
1698 unsigned flags = params->flags;
1699 gnutls_digest_algorithm_t hash_alg;
1700 gnutls_sign_algorithm_t sign_alg;
1701 gnutls_datum_t gnutls_hash, gnutls_signature;
1702 gnutls_pk_algorithm_t pk_alg;
1703 NTSTATUS status;
1704 int ret;
1706 switch (key->alg_id)
1708 case ALG_ID_ECDSA_P256:
1709 case ALG_ID_ECDSA_P384:
1711 if (flags) FIXME( "flags %#x not supported\n", flags );
1713 /* only the hash size must match, not the actual hash function */
1714 switch (params->hash_len)
1716 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1717 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1718 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1720 default:
1721 FIXME( "hash size %u not yet supported\n", params->hash_len );
1722 return STATUS_INVALID_SIGNATURE;
1724 pk_alg = GNUTLS_PK_ECC;
1725 break;
1727 case ALG_ID_RSA:
1728 case ALG_ID_RSA_SIGN:
1730 if (flags & BCRYPT_PAD_PKCS1)
1732 BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
1734 if (!info) return STATUS_INVALID_PARAMETER;
1735 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1736 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1738 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1739 return STATUS_NOT_SUPPORTED;
1741 pk_alg = GNUTLS_PK_RSA;
1743 else if (flags & BCRYPT_PAD_PSS)
1745 BCRYPT_PSS_PADDING_INFO *info = params->padding;
1747 if (!info) return STATUS_INVALID_PARAMETER;
1748 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1749 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1751 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1752 return STATUS_NOT_SUPPORTED;
1754 if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
1755 pk_alg = GNUTLS_PK_RSA_PSS;
1757 else return STATUS_INVALID_PARAMETER;
1758 break;
1760 case ALG_ID_DSA:
1762 if (flags) FIXME( "flags %#x not supported\n", flags );
1763 if (params->hash_len != 20)
1765 FIXME( "hash size %u not supported\n", params->hash_len );
1766 return STATUS_INVALID_PARAMETER;
1768 hash_alg = GNUTLS_DIG_SHA1;
1769 pk_alg = GNUTLS_PK_DSA;
1770 break;
1772 default:
1773 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1774 return STATUS_NOT_IMPLEMENTED;
1777 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
1779 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
1780 return STATUS_NOT_IMPLEMENTED;
1783 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
1784 return status;
1786 gnutls_hash.data = params->hash;
1787 gnutls_hash.size = params->hash_len;
1788 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
1790 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
1791 return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
1794 static unsigned int get_signature_length( enum alg_id id )
1796 switch (id)
1798 case ALG_ID_ECDSA_P256: return 64;
1799 case ALG_ID_ECDSA_P384: return 96;
1800 case ALG_ID_DSA: return 40;
1801 default:
1802 FIXME( "unhandled algorithm %u\n", id );
1803 return 0;
1807 static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
1808 UCHAR *output, ULONG output_len, ULONG *ret_len )
1810 switch (type)
1812 case ALG_ID_RSA:
1813 case ALG_ID_RSA_SIGN:
1815 *ret_len = signature.size;
1816 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
1817 if (output) memcpy( output, signature.data, signature.size );
1818 return STATUS_SUCCESS;
1820 case ALG_ID_ECDSA_P256:
1821 case ALG_ID_ECDSA_P384:
1822 case ALG_ID_DSA:
1824 int err;
1825 unsigned int sig_len = get_signature_length( type );
1826 gnutls_datum_t r, s; /* format as r||s */
1828 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
1830 pgnutls_perror( err );
1831 return STATUS_INTERNAL_ERROR;
1834 *ret_len = sig_len;
1835 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
1837 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
1839 ERR( "we didn't get a correct signature\n" );
1840 return STATUS_INTERNAL_ERROR;
1843 if (output)
1845 export_gnutls_datum( output, sig_len / 2, &r, 1 );
1846 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
1849 free( r.data ); free( s.data );
1850 return STATUS_SUCCESS;
1852 default:
1853 return STATUS_INTERNAL_ERROR;
1857 static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
1859 gnutls_x509_spki_t spki;
1860 int ret;
1862 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
1864 pgnutls_perror( ret );
1865 return STATUS_INTERNAL_ERROR;
1867 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
1868 ret = pgnutls_privkey_set_spki( key, spki, 0 );
1869 pgnutls_x509_spki_deinit( spki );
1870 if (ret < 0)
1872 pgnutls_perror( ret );
1873 return STATUS_INTERNAL_ERROR;
1875 return STATUS_SUCCESS;
1878 static NTSTATUS key_asymmetric_sign( void *args )
1880 const struct key_asymmetric_sign_params *params = args;
1881 struct key *key = params->key;
1882 unsigned int flags = params->flags, gnutls_flags = 0;
1883 gnutls_datum_t hash, signature;
1884 gnutls_digest_algorithm_t hash_alg;
1885 NTSTATUS status;
1886 int ret;
1888 if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
1890 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1891 switch (params->input_len)
1893 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1894 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1895 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1896 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
1898 default:
1899 FIXME( "hash size %u not yet supported\n", params->input_len );
1900 return STATUS_INVALID_PARAMETER;
1903 if (flags == BCRYPT_PAD_PKCS1)
1905 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1906 if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
1908 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
1909 return STATUS_INVALID_PARAMETER;
1913 else if (key->alg_id == ALG_ID_DSA)
1915 if (flags) FIXME( "flags %#x not supported\n", flags );
1916 if (params->input_len != 20)
1918 FIXME( "hash size %u not supported\n", params->input_len );
1919 return STATUS_INVALID_PARAMETER;
1921 hash_alg = GNUTLS_DIG_SHA1;
1923 else if (flags == BCRYPT_PAD_PKCS1)
1925 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1927 if (!pad || !pad->pszAlgId)
1929 WARN( "padding info not found\n" );
1930 return STATUS_INVALID_PARAMETER;
1932 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1934 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1935 return STATUS_NOT_SUPPORTED;
1938 else if (flags == BCRYPT_PAD_PSS)
1940 BCRYPT_PSS_PADDING_INFO *pad = params->padding;
1942 if (!pad || !pad->pszAlgId)
1944 WARN( "padding info not found\n" );
1945 return STATUS_INVALID_PARAMETER;
1947 if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
1949 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
1950 return STATUS_NOT_SUPPORTED;
1952 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1954 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1955 return STATUS_NOT_SUPPORTED;
1958 if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
1959 gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
1961 else if (!flags)
1963 WARN( "invalid flags %#x\n", flags );
1964 return STATUS_INVALID_PARAMETER;
1966 else
1968 FIXME( "flags %#x not implemented\n", flags );
1969 return STATUS_NOT_IMPLEMENTED;
1972 if (!params->output)
1974 *params->ret_len = key->u.a.bitlen / 8;
1975 return STATUS_SUCCESS;
1977 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1979 hash.data = params->input;
1980 hash.size = params->input_len;
1982 signature.data = NULL;
1983 signature.size = 0;
1985 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
1987 pgnutls_perror( ret );
1988 return STATUS_INTERNAL_ERROR;
1991 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
1992 free( signature.data );
1993 return status;
1996 static NTSTATUS key_asymmetric_destroy( void *args )
1998 struct key *key = args;
2000 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2001 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2002 return STATUS_SUCCESS;
2005 static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2007 gnutls_privkey_t privkey;
2008 int ret;
2010 if ((ret = pgnutls_privkey_init( &privkey )))
2012 pgnutls_perror( ret );
2013 return STATUS_INTERNAL_ERROR;
2016 switch (key_orig->alg_id)
2018 case ALG_ID_RSA:
2019 case ALG_ID_RSA_SIGN:
2021 gnutls_datum_t m, e, d, p, q, u, e1, e2;
2022 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2024 pgnutls_perror( ret );
2025 return STATUS_INTERNAL_ERROR;
2027 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2028 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2029 free( e1.data ); free( e2.data );
2030 if (ret)
2032 pgnutls_perror( ret );
2033 return STATUS_INTERNAL_ERROR;
2035 break;
2037 case ALG_ID_DSA:
2039 gnutls_datum_t p, q, g, y, x;
2040 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
2042 pgnutls_perror( ret );
2043 return STATUS_INTERNAL_ERROR;
2045 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2046 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2047 if (ret)
2049 pgnutls_perror( ret );
2050 return STATUS_INTERNAL_ERROR;
2052 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2053 break;
2055 case ALG_ID_ECDH_P256:
2056 case ALG_ID_ECDH_P384:
2057 case ALG_ID_ECDSA_P256:
2058 case ALG_ID_ECDSA_P384:
2060 gnutls_ecc_curve_t curve;
2061 gnutls_datum_t x, y, k;
2062 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
2064 pgnutls_perror( ret );
2065 return STATUS_INTERNAL_ERROR;
2067 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2068 free( x.data ); free( y.data ); free( k.data );
2069 if (ret)
2071 pgnutls_perror( ret );
2072 return STATUS_INTERNAL_ERROR;
2074 break;
2076 default:
2077 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2078 return STATUS_INTERNAL_ERROR;
2081 key_data(key_copy)->a.privkey = privkey;
2082 return STATUS_SUCCESS;
2085 static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2087 gnutls_pubkey_t pubkey;
2088 int ret;
2090 if ((ret = pgnutls_pubkey_init( &pubkey )))
2092 pgnutls_perror( ret );
2093 return STATUS_INTERNAL_ERROR;
2096 switch (key_orig->alg_id)
2098 case ALG_ID_RSA:
2099 case ALG_ID_RSA_SIGN:
2101 gnutls_datum_t m, e;
2102 if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e )))
2104 pgnutls_perror( ret );
2105 return STATUS_INTERNAL_ERROR;
2107 ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2108 free( m.data ); free( e.data );
2109 if (ret)
2111 pgnutls_perror( ret );
2112 return STATUS_INTERNAL_ERROR;
2114 break;
2116 case ALG_ID_DSA:
2118 gnutls_datum_t p, q, g, y;
2119 if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y )))
2121 pgnutls_perror( ret );
2122 return STATUS_INTERNAL_ERROR;
2124 ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2125 free( p.data ); free( q.data ); free( g.data ); free( y.data );
2126 if (ret)
2128 pgnutls_perror( ret );
2129 return STATUS_INTERNAL_ERROR;
2131 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2132 break;
2134 case ALG_ID_ECDH_P256:
2135 case ALG_ID_ECDH_P384:
2136 case ALG_ID_ECDSA_P256:
2137 case ALG_ID_ECDSA_P384:
2139 gnutls_ecc_curve_t curve;
2140 gnutls_datum_t x, y;
2141 if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y )))
2143 pgnutls_perror( ret );
2144 return STATUS_INTERNAL_ERROR;
2146 ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2147 free( x.data ); free( y.data );
2148 if (ret)
2150 pgnutls_perror( ret );
2151 return STATUS_INTERNAL_ERROR;
2153 break;
2155 default:
2156 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2157 return STATUS_INTERNAL_ERROR;
2160 key_data(key_copy)->a.pubkey = pubkey;
2161 return STATUS_SUCCESS;
2164 static NTSTATUS key_asymmetric_duplicate( void *args )
2166 const struct key_asymmetric_duplicate_params *params = args;
2167 NTSTATUS status;
2169 if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2170 return status;
2172 if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2173 return status;
2175 return STATUS_SUCCESS;
2178 static NTSTATUS key_asymmetric_decrypt( void *args )
2180 const struct key_asymmetric_decrypt_params *params = args;
2181 gnutls_datum_t e, d = { 0 };
2182 NTSTATUS status = STATUS_SUCCESS;
2183 int ret;
2185 e.data = params->input;
2186 e.size = params->input_len;
2187 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2189 pgnutls_perror( ret );
2190 return STATUS_INTERNAL_ERROR;
2193 *params->ret_len = d.size;
2194 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2195 else status = STATUS_BUFFER_TOO_SMALL;
2197 free( d.data );
2198 return status;
2201 static NTSTATUS key_asymmetric_encrypt( void *args )
2203 const struct key_asymmetric_encrypt_params *params = args;
2204 gnutls_datum_t d, e = { 0 };
2205 NTSTATUS status = STATUS_SUCCESS;
2206 int ret;
2208 d.data = params->input;
2209 d.size = params->input_len;
2210 if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2212 pgnutls_perror( ret );
2213 return STATUS_INTERNAL_ERROR;
2216 *params->ret_len = e.size;
2217 if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2218 else if (params->output_len == 0) status = STATUS_SUCCESS;
2219 else status = STATUS_BUFFER_TOO_SMALL;
2221 free( e.data );
2222 return status;
2225 const unixlib_entry_t __wine_unix_call_funcs[] =
2227 gnutls_process_attach,
2228 gnutls_process_detach,
2229 key_symmetric_vector_reset,
2230 key_symmetric_set_auth_data,
2231 key_symmetric_encrypt,
2232 key_symmetric_decrypt,
2233 key_symmetric_get_tag,
2234 key_symmetric_destroy,
2235 key_asymmetric_generate,
2236 key_asymmetric_decrypt,
2237 key_asymmetric_encrypt,
2238 key_asymmetric_duplicate,
2239 key_asymmetric_sign,
2240 key_asymmetric_verify,
2241 key_asymmetric_destroy,
2242 key_asymmetric_export,
2243 key_asymmetric_import
2246 #ifdef _WIN64
2248 typedef ULONG PTR32;
2250 struct key_symmetric32
2252 enum chain_mode mode;
2253 ULONG block_size;
2254 PTR32 vector;
2255 ULONG vector_len;
2256 PTR32 secret;
2257 ULONG secret_len;
2258 ULONG __cs[6];
2261 struct key_asymmetric32
2263 ULONG bitlen; /* ignored for ECC keys */
2264 ULONG flags;
2265 PTR32 pubkey;
2266 ULONG pubkey_len;
2267 DSSSEED dss_seed;
2270 struct key32
2272 struct object hdr;
2273 enum alg_id alg_id;
2274 UINT64 private[2]; /* private data for backend */
2275 union
2277 struct key_symmetric32 s;
2278 struct key_asymmetric32 a;
2279 } u;
2282 static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
2284 key->hdr = key32->hdr;
2285 key->alg_id = key32->alg_id;
2286 key->private[0] = key32->private[0];
2287 key->private[1] = key32->private[1];
2288 key->u.s.mode = key32->u.s.mode;
2289 key->u.s.block_size = key32->u.s.block_size;
2290 key->u.s.vector = ULongToPtr(key32->u.s.vector);
2291 key->u.s.vector_len = key32->u.s.vector_len;
2292 key->u.s.secret = ULongToPtr(key32->u.s.secret);
2293 key->u.s.secret_len = key32->u.s.secret_len;
2294 return key;
2297 static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2299 key->hdr = key32->hdr;
2300 key->alg_id = key32->alg_id;
2301 key->private[0] = key32->private[0];
2302 key->private[1] = key32->private[1];
2303 key->u.a.bitlen = key32->u.a.bitlen;
2304 key->u.a.flags = key32->u.a.flags;
2305 key->u.a.dss_seed = key32->u.a.dss_seed;
2306 return key;
2309 static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2311 key32->private[0] = key->private[0];
2312 key32->private[1] = key->private[1];
2315 static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2317 key32->private[0] = key->private[0];
2318 key32->private[1] = key->private[1];
2319 key32->u.a.flags = key->u.a.flags;
2320 key32->u.a.dss_seed = key->u.a.dss_seed;
2323 static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
2325 NTSTATUS ret;
2326 struct key key;
2327 struct key32 *key32 = args;
2329 ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
2330 put_symmetric_key32( &key, key32 );
2331 return ret;
2334 static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
2336 struct
2338 PTR32 key;
2339 PTR32 auth_data;
2340 ULONG len;
2341 } const *params32 = args;
2343 NTSTATUS ret;
2344 struct key key;
2345 struct key32 *key32 = ULongToPtr( params32->key );
2346 struct key_symmetric_set_auth_data_params params =
2348 get_symmetric_key( key32, &key ),
2349 ULongToPtr(params32->auth_data),
2350 params32->len
2353 ret = key_symmetric_set_auth_data( &params );
2354 put_symmetric_key32( &key, key32 );
2355 return ret;
2358 static NTSTATUS wow64_key_symmetric_encrypt( void *args )
2360 struct
2362 PTR32 key;
2363 PTR32 input;
2364 ULONG input_len;
2365 PTR32 output;
2366 ULONG output_len;
2367 } const *params32 = args;
2369 NTSTATUS ret;
2370 struct key key;
2371 struct key32 *key32 = ULongToPtr( params32->key );
2372 struct key_symmetric_encrypt_params params =
2374 get_symmetric_key( key32, &key ),
2375 ULongToPtr(params32->input),
2376 params32->input_len,
2377 ULongToPtr(params32->output),
2378 params32->output_len
2381 ret = key_symmetric_encrypt( &params );
2382 put_symmetric_key32( &key, key32 );
2383 return ret;
2386 static NTSTATUS wow64_key_symmetric_decrypt( void *args )
2388 struct
2390 PTR32 key;
2391 PTR32 input;
2392 ULONG input_len;
2393 PTR32 output;
2394 ULONG output_len;
2395 } const *params32 = args;
2397 NTSTATUS ret;
2398 struct key key;
2399 struct key32 *key32 = ULongToPtr( params32->key );
2400 struct key_symmetric_decrypt_params params =
2402 get_symmetric_key( key32, &key ),
2403 ULongToPtr(params32->input),
2404 params32->input_len,
2405 ULongToPtr(params32->output),
2406 params32->output_len
2409 ret = key_symmetric_decrypt( &params );
2410 put_symmetric_key32( &key, key32 );
2411 return ret;
2414 static NTSTATUS wow64_key_symmetric_get_tag( void *args )
2416 struct
2418 PTR32 key;
2419 PTR32 tag;
2420 ULONG len;
2421 } const *params32 = args;
2423 NTSTATUS ret;
2424 struct key key;
2425 struct key32 *key32 = ULongToPtr( params32->key );
2426 struct key_symmetric_get_tag_params params =
2428 get_symmetric_key( key32, &key ),
2429 ULongToPtr(params32->tag),
2430 params32->len
2433 ret = key_symmetric_get_tag( &params );
2434 put_symmetric_key32( &key, key32 );
2435 return ret;
2438 static NTSTATUS wow64_key_symmetric_destroy( void *args )
2440 struct key32 *key32 = args;
2441 struct key key;
2443 return key_symmetric_destroy( get_symmetric_key( key32, &key ));
2446 static NTSTATUS wow64_key_asymmetric_generate( void *args )
2448 struct key32 *key32 = args;
2449 struct key key;
2450 NTSTATUS ret;
2452 ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
2453 put_asymmetric_key32( &key, key32 );
2454 return ret;
2457 static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
2459 struct
2461 PTR32 key;
2462 PTR32 input;
2463 ULONG input_len;
2464 PTR32 output;
2465 ULONG output_len;
2466 PTR32 ret_len;
2467 } const *params32 = args;
2469 NTSTATUS ret;
2470 struct key key;
2471 struct key32 *key32 = ULongToPtr( params32->key );
2472 struct key_asymmetric_decrypt_params params =
2474 get_asymmetric_key( key32, &key ),
2475 ULongToPtr(params32->input),
2476 params32->input_len,
2477 ULongToPtr(params32->output),
2478 params32->output_len,
2479 ULongToPtr(params32->ret_len)
2482 ret = key_asymmetric_decrypt( &params );
2483 put_asymmetric_key32( &key, key32 );
2484 return ret;
2487 static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
2489 struct
2491 PTR32 key;
2492 PTR32 input;
2493 ULONG input_len;
2494 PTR32 output;
2495 ULONG output_len;
2496 PTR32 ret_len;
2497 } const *params32 = args;
2499 NTSTATUS ret;
2500 struct key key;
2501 struct key32 *key32 = ULongToPtr( params32->key );
2502 struct key_asymmetric_encrypt_params params =
2504 get_asymmetric_key( key32, &key ),
2505 ULongToPtr(params32->input),
2506 params32->input_len,
2507 ULongToPtr(params32->output),
2508 params32->output_len,
2509 ULongToPtr(params32->ret_len)
2512 ret = key_asymmetric_encrypt( &params );
2513 put_asymmetric_key32( &key, key32 );
2514 return ret;
2517 static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
2519 struct
2521 PTR32 key_orig;
2522 PTR32 key_copy;
2523 } const *params32 = args;
2525 NTSTATUS ret;
2526 struct key key_orig, key_copy;
2527 struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
2528 struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
2529 struct key_asymmetric_duplicate_params params =
2531 get_asymmetric_key( key_orig32, &key_orig ),
2532 get_asymmetric_key( key_copy32, &key_copy )
2535 ret = key_asymmetric_duplicate( &params );
2536 put_asymmetric_key32( &key_copy, key_copy32 );
2537 return ret;
2540 static NTSTATUS wow64_key_asymmetric_sign( void *args )
2542 struct
2544 PTR32 key;
2545 PTR32 padding;
2546 PTR32 input;
2547 ULONG input_len;
2548 PTR32 output;
2549 ULONG output_len;
2550 PTR32 ret_len;
2551 ULONG flags;
2552 } const *params32 = args;
2554 NTSTATUS ret;
2555 struct key key;
2556 BCRYPT_PKCS1_PADDING_INFO padding;
2557 struct key32 *key32 = ULongToPtr( params32->key );
2558 struct key_asymmetric_sign_params params =
2560 get_asymmetric_key( key32, &key ),
2561 NULL, /* padding */
2562 ULongToPtr(params32->input),
2563 params32->input_len,
2564 ULongToPtr(params32->output),
2565 params32->output_len,
2566 ULongToPtr(params32->ret_len),
2567 params32->flags
2570 if (params32->flags & BCRYPT_PAD_PKCS1)
2572 PTR32 *info = ULongToPtr( params32->padding );
2573 if (!info) return STATUS_INVALID_PARAMETER;
2574 padding.pszAlgId = ULongToPtr( *info );
2575 params.padding = &padding;
2578 ret = key_asymmetric_sign( &params );
2579 put_asymmetric_key32( &key, key32 );
2580 return ret;
2583 static NTSTATUS wow64_key_asymmetric_verify( void *args )
2585 struct
2587 PTR32 key;
2588 PTR32 padding;
2589 PTR32 hash;
2590 ULONG hash_len;
2591 PTR32 signature;
2592 ULONG signature_len;
2593 ULONG flags;
2594 } const *params32 = args;
2596 NTSTATUS ret;
2597 struct key key;
2598 BCRYPT_PKCS1_PADDING_INFO padding;
2599 struct key32 *key32 = ULongToPtr( params32->key );
2600 struct key_asymmetric_verify_params params =
2602 get_asymmetric_key( key32, &key ),
2603 NULL, /* padding */
2604 ULongToPtr(params32->hash),
2605 params32->hash_len,
2606 ULongToPtr(params32->signature),
2607 params32->signature_len,
2608 params32->flags
2611 if (params32->flags & BCRYPT_PAD_PKCS1)
2613 PTR32 *info = ULongToPtr( params32->padding );
2614 if (!info) return STATUS_INVALID_PARAMETER;
2615 padding.pszAlgId = ULongToPtr( *info );
2616 params.padding = &padding;
2619 ret = key_asymmetric_verify( &params );
2620 put_asymmetric_key32( &key, key32 );
2621 return ret;
2624 static NTSTATUS wow64_key_asymmetric_destroy( void *args )
2626 struct key32 *key32 = args;
2627 struct key key;
2629 return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
2632 static NTSTATUS wow64_key_asymmetric_export( void *args )
2634 struct
2636 PTR32 key;
2637 ULONG flags;
2638 PTR32 buf;
2639 ULONG len;
2640 PTR32 ret_len;
2641 } const *params32 = args;
2643 NTSTATUS ret;
2644 struct key key;
2645 struct key32 *key32 = ULongToPtr( params32->key );
2646 struct key_asymmetric_export_params params =
2648 get_asymmetric_key( key32, &key ),
2649 params32->flags,
2650 ULongToPtr(params32->buf),
2651 params32->len,
2652 ULongToPtr(params32->ret_len),
2655 ret = key_asymmetric_export( &params );
2656 put_asymmetric_key32( &key, key32 );
2657 return ret;
2660 static NTSTATUS wow64_key_asymmetric_import( void *args )
2662 struct
2664 PTR32 key;
2665 ULONG flags;
2666 PTR32 buf;
2667 ULONG len;
2668 } const *params32 = args;
2670 NTSTATUS ret;
2671 struct key key;
2672 struct key32 *key32 = ULongToPtr( params32->key );
2673 struct key_asymmetric_import_params params =
2675 get_asymmetric_key( key32, &key ),
2676 params32->flags,
2677 ULongToPtr(params32->buf),
2678 params32->len
2681 ret = key_asymmetric_import( &params );
2682 put_asymmetric_key32( &key, key32 );
2683 return ret;
2686 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
2688 gnutls_process_attach,
2689 gnutls_process_detach,
2690 wow64_key_symmetric_vector_reset,
2691 wow64_key_symmetric_set_auth_data,
2692 wow64_key_symmetric_encrypt,
2693 wow64_key_symmetric_decrypt,
2694 wow64_key_symmetric_get_tag,
2695 wow64_key_symmetric_destroy,
2696 wow64_key_asymmetric_generate,
2697 wow64_key_asymmetric_decrypt,
2698 wow64_key_asymmetric_encrypt,
2699 wow64_key_asymmetric_duplicate,
2700 wow64_key_asymmetric_sign,
2701 wow64_key_asymmetric_verify,
2702 wow64_key_asymmetric_destroy,
2703 wow64_key_asymmetric_export,
2704 wow64_key_asymmetric_import
2707 #endif /* _WIN64 */
2709 #endif /* HAVE_GNUTLS_CIPHER_INIT */