winepulse: Remove AudioSessionManager.
[wine.git] / dlls / bcrypt / gnutls.c
blobc54ebc471a98652382b63a4e0a45d93dfc993af8
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 const struct key_asymmetric_verify_params *params = args;
1718 struct key *key = params->key;
1719 unsigned flags = params->flags;
1720 gnutls_digest_algorithm_t hash_alg;
1721 gnutls_sign_algorithm_t sign_alg;
1722 gnutls_datum_t gnutls_hash, gnutls_signature;
1723 gnutls_pk_algorithm_t pk_alg;
1724 NTSTATUS status;
1725 int ret;
1727 switch (key->alg_id)
1729 case ALG_ID_ECDSA_P256:
1730 case ALG_ID_ECDSA_P384:
1732 if (flags) FIXME( "flags %#x not supported\n", flags );
1734 /* only the hash size must match, not the actual hash function */
1735 switch (params->hash_len)
1737 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1738 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1739 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1741 default:
1742 FIXME( "hash size %u not yet supported\n", params->hash_len );
1743 return STATUS_INVALID_SIGNATURE;
1745 pk_alg = GNUTLS_PK_ECC;
1746 break;
1748 case ALG_ID_RSA:
1749 case ALG_ID_RSA_SIGN:
1751 if (flags & BCRYPT_PAD_PKCS1)
1753 BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
1755 if (!info) return STATUS_INVALID_PARAMETER;
1756 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1757 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1759 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1760 return STATUS_NOT_SUPPORTED;
1762 pk_alg = GNUTLS_PK_RSA;
1764 else if (flags & BCRYPT_PAD_PSS)
1766 BCRYPT_PSS_PADDING_INFO *info = params->padding;
1768 if (!info) return STATUS_INVALID_PARAMETER;
1769 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1770 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1772 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1773 return STATUS_NOT_SUPPORTED;
1775 if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
1776 pk_alg = GNUTLS_PK_RSA_PSS;
1778 else return STATUS_INVALID_PARAMETER;
1779 break;
1781 case ALG_ID_DSA:
1783 if (flags) FIXME( "flags %#x not supported\n", flags );
1784 if (params->hash_len != 20)
1786 FIXME( "hash size %u not supported\n", params->hash_len );
1787 return STATUS_INVALID_PARAMETER;
1789 hash_alg = GNUTLS_DIG_SHA1;
1790 pk_alg = GNUTLS_PK_DSA;
1791 break;
1793 default:
1794 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1795 return STATUS_NOT_IMPLEMENTED;
1798 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
1800 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
1801 return STATUS_NOT_IMPLEMENTED;
1804 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
1805 return status;
1807 gnutls_hash.data = params->hash;
1808 gnutls_hash.size = params->hash_len;
1809 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
1811 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
1812 return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
1815 static unsigned int get_signature_length( enum alg_id id )
1817 switch (id)
1819 case ALG_ID_ECDSA_P256: return 64;
1820 case ALG_ID_ECDSA_P384: return 96;
1821 case ALG_ID_DSA: return 40;
1822 default:
1823 FIXME( "unhandled algorithm %u\n", id );
1824 return 0;
1828 static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
1829 UCHAR *output, ULONG output_len, ULONG *ret_len )
1831 switch (type)
1833 case ALG_ID_RSA:
1834 case ALG_ID_RSA_SIGN:
1836 *ret_len = signature.size;
1837 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
1838 if (output) memcpy( output, signature.data, signature.size );
1839 return STATUS_SUCCESS;
1841 case ALG_ID_ECDSA_P256:
1842 case ALG_ID_ECDSA_P384:
1843 case ALG_ID_DSA:
1845 int err;
1846 unsigned int sig_len = get_signature_length( type );
1847 gnutls_datum_t r, s; /* format as r||s */
1849 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
1851 pgnutls_perror( err );
1852 return STATUS_INTERNAL_ERROR;
1855 *ret_len = sig_len;
1856 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
1858 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
1860 ERR( "we didn't get a correct signature\n" );
1861 return STATUS_INTERNAL_ERROR;
1864 if (output)
1866 export_gnutls_datum( output, sig_len / 2, &r, 1 );
1867 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
1870 free( r.data ); free( s.data );
1871 return STATUS_SUCCESS;
1873 default:
1874 return STATUS_INTERNAL_ERROR;
1878 static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
1880 gnutls_x509_spki_t spki;
1881 int ret;
1883 if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
1885 pgnutls_perror( ret );
1886 return STATUS_INTERNAL_ERROR;
1888 pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
1889 ret = pgnutls_privkey_set_spki( key, spki, 0 );
1890 pgnutls_x509_spki_deinit( spki );
1891 if (ret < 0)
1893 pgnutls_perror( ret );
1894 return STATUS_INTERNAL_ERROR;
1896 return STATUS_SUCCESS;
1899 static NTSTATUS key_asymmetric_sign( void *args )
1901 const struct key_asymmetric_sign_params *params = args;
1902 struct key *key = params->key;
1903 unsigned int flags = params->flags, gnutls_flags = 0;
1904 gnutls_datum_t hash, signature;
1905 gnutls_digest_algorithm_t hash_alg;
1906 NTSTATUS status;
1907 int ret;
1909 if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
1911 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1912 switch (params->input_len)
1914 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1915 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1916 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1917 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
1919 default:
1920 FIXME( "hash size %u not yet supported\n", params->input_len );
1921 return STATUS_INVALID_PARAMETER;
1924 if (flags == BCRYPT_PAD_PKCS1)
1926 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1927 if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
1929 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
1930 return STATUS_INVALID_PARAMETER;
1934 else if (key->alg_id == ALG_ID_DSA)
1936 if (flags) FIXME( "flags %#x not supported\n", flags );
1937 if (params->input_len != 20)
1939 FIXME( "hash size %u not supported\n", params->input_len );
1940 return STATUS_INVALID_PARAMETER;
1942 hash_alg = GNUTLS_DIG_SHA1;
1944 else if (flags == BCRYPT_PAD_PKCS1)
1946 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1948 if (!pad || !pad->pszAlgId)
1950 WARN( "padding info not found\n" );
1951 return STATUS_INVALID_PARAMETER;
1953 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1955 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1956 return STATUS_NOT_SUPPORTED;
1959 else if (flags == BCRYPT_PAD_PSS)
1961 BCRYPT_PSS_PADDING_INFO *pad = params->padding;
1963 if (!pad || !pad->pszAlgId)
1965 WARN( "padding info not found\n" );
1966 return STATUS_INVALID_PARAMETER;
1968 if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
1970 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
1971 return STATUS_NOT_SUPPORTED;
1973 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1975 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1976 return STATUS_NOT_SUPPORTED;
1979 if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
1980 gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
1982 else if (!flags)
1984 WARN( "invalid flags %#x\n", flags );
1985 return STATUS_INVALID_PARAMETER;
1987 else
1989 FIXME( "flags %#x not implemented\n", flags );
1990 return STATUS_NOT_IMPLEMENTED;
1993 if (!params->output)
1995 *params->ret_len = key->u.a.bitlen / 8;
1996 return STATUS_SUCCESS;
1998 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2000 hash.data = params->input;
2001 hash.size = params->input_len;
2003 signature.data = NULL;
2004 signature.size = 0;
2006 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2008 pgnutls_perror( ret );
2009 return STATUS_INTERNAL_ERROR;
2012 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2013 free( signature.data );
2014 return status;
2017 static NTSTATUS key_asymmetric_destroy( void *args )
2019 struct key *key = args;
2021 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2022 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2023 return STATUS_SUCCESS;
2026 static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2028 gnutls_privkey_t privkey;
2029 int ret;
2031 if ((ret = pgnutls_privkey_init( &privkey )))
2033 pgnutls_perror( ret );
2034 return STATUS_INTERNAL_ERROR;
2037 switch (key_orig->alg_id)
2039 case ALG_ID_RSA:
2040 case ALG_ID_RSA_SIGN:
2042 gnutls_datum_t m, e, d, p, q, u, e1, e2;
2043 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2045 pgnutls_perror( ret );
2046 return STATUS_INTERNAL_ERROR;
2048 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2049 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2050 free( e1.data ); free( e2.data );
2051 if (ret)
2053 pgnutls_perror( ret );
2054 return STATUS_INTERNAL_ERROR;
2056 break;
2058 case ALG_ID_DSA:
2060 gnutls_datum_t p, q, g, y, x;
2061 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
2063 pgnutls_perror( ret );
2064 return STATUS_INTERNAL_ERROR;
2066 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2067 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2068 if (ret)
2070 pgnutls_perror( ret );
2071 return STATUS_INTERNAL_ERROR;
2073 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2074 break;
2076 case ALG_ID_ECDH_P256:
2077 case ALG_ID_ECDH_P384:
2078 case ALG_ID_ECDSA_P256:
2079 case ALG_ID_ECDSA_P384:
2081 gnutls_ecc_curve_t curve;
2082 gnutls_datum_t x, y, k;
2083 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
2085 pgnutls_perror( ret );
2086 return STATUS_INTERNAL_ERROR;
2088 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2089 free( x.data ); free( y.data ); free( k.data );
2090 if (ret)
2092 pgnutls_perror( ret );
2093 return STATUS_INTERNAL_ERROR;
2095 break;
2097 default:
2098 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2099 return STATUS_INTERNAL_ERROR;
2102 key_data(key_copy)->a.privkey = privkey;
2103 return STATUS_SUCCESS;
2106 static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2108 gnutls_pubkey_t pubkey;
2109 int ret;
2111 if ((ret = pgnutls_pubkey_init( &pubkey )))
2113 pgnutls_perror( ret );
2114 return STATUS_INTERNAL_ERROR;
2117 switch (key_orig->alg_id)
2119 case ALG_ID_RSA:
2120 case ALG_ID_RSA_SIGN:
2122 gnutls_datum_t m, e;
2123 if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e )))
2125 pgnutls_perror( ret );
2126 return STATUS_INTERNAL_ERROR;
2128 ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2129 free( m.data ); free( e.data );
2130 if (ret)
2132 pgnutls_perror( ret );
2133 return STATUS_INTERNAL_ERROR;
2135 break;
2137 case ALG_ID_DSA:
2139 gnutls_datum_t p, q, g, y;
2140 if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y )))
2142 pgnutls_perror( ret );
2143 return STATUS_INTERNAL_ERROR;
2145 ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2146 free( p.data ); free( q.data ); free( g.data ); free( y.data );
2147 if (ret)
2149 pgnutls_perror( ret );
2150 return STATUS_INTERNAL_ERROR;
2152 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2153 break;
2155 case ALG_ID_ECDH_P256:
2156 case ALG_ID_ECDH_P384:
2157 case ALG_ID_ECDSA_P256:
2158 case ALG_ID_ECDSA_P384:
2160 gnutls_ecc_curve_t curve;
2161 gnutls_datum_t x, y;
2162 if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y )))
2164 pgnutls_perror( ret );
2165 return STATUS_INTERNAL_ERROR;
2167 ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2168 free( x.data ); free( y.data );
2169 if (ret)
2171 pgnutls_perror( ret );
2172 return STATUS_INTERNAL_ERROR;
2174 break;
2176 default:
2177 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2178 return STATUS_INTERNAL_ERROR;
2181 key_data(key_copy)->a.pubkey = pubkey;
2182 return STATUS_SUCCESS;
2185 static NTSTATUS key_asymmetric_duplicate( void *args )
2187 const struct key_asymmetric_duplicate_params *params = args;
2188 NTSTATUS status;
2190 if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2191 return status;
2193 if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2194 return status;
2196 return STATUS_SUCCESS;
2199 static NTSTATUS key_asymmetric_decrypt( void *args )
2201 const struct key_asymmetric_decrypt_params *params = args;
2202 gnutls_datum_t e, d = { 0 };
2203 NTSTATUS status = STATUS_SUCCESS;
2204 int ret;
2206 e.data = params->input;
2207 e.size = params->input_len;
2208 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2210 pgnutls_perror( ret );
2211 return STATUS_INTERNAL_ERROR;
2214 *params->ret_len = d.size;
2215 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2216 else status = STATUS_BUFFER_TOO_SMALL;
2218 free( d.data );
2219 return status;
2222 static NTSTATUS key_asymmetric_encrypt( void *args )
2224 const struct key_asymmetric_encrypt_params *params = args;
2225 gnutls_datum_t d, e = { 0 };
2226 NTSTATUS status = STATUS_SUCCESS;
2227 int ret;
2229 if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2231 d.data = params->input;
2232 d.size = params->input_len;
2233 if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2235 pgnutls_perror( ret );
2236 return STATUS_INTERNAL_ERROR;
2239 *params->ret_len = e.size;
2240 if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2241 else if (params->output_len == 0) status = STATUS_SUCCESS;
2242 else status = STATUS_BUFFER_TOO_SMALL;
2244 free( e.data );
2245 return status;
2248 const unixlib_entry_t __wine_unix_call_funcs[] =
2250 gnutls_process_attach,
2251 gnutls_process_detach,
2252 key_symmetric_vector_reset,
2253 key_symmetric_set_auth_data,
2254 key_symmetric_encrypt,
2255 key_symmetric_decrypt,
2256 key_symmetric_get_tag,
2257 key_symmetric_destroy,
2258 key_asymmetric_generate,
2259 key_asymmetric_decrypt,
2260 key_asymmetric_encrypt,
2261 key_asymmetric_duplicate,
2262 key_asymmetric_sign,
2263 key_asymmetric_verify,
2264 key_asymmetric_destroy,
2265 key_asymmetric_export,
2266 key_asymmetric_import
2269 #ifdef _WIN64
2271 typedef ULONG PTR32;
2273 struct key_symmetric32
2275 enum chain_mode mode;
2276 ULONG block_size;
2277 PTR32 vector;
2278 ULONG vector_len;
2279 PTR32 secret;
2280 ULONG secret_len;
2281 ULONG __cs[6];
2284 struct key_asymmetric32
2286 ULONG bitlen; /* ignored for ECC keys */
2287 ULONG flags;
2288 DSSSEED dss_seed;
2291 struct key32
2293 struct object hdr;
2294 enum alg_id alg_id;
2295 UINT64 private[2]; /* private data for backend */
2296 union
2298 struct key_symmetric32 s;
2299 struct key_asymmetric32 a;
2300 } u;
2303 union padding
2305 BCRYPT_PKCS1_PADDING_INFO pkcs1;
2306 BCRYPT_PSS_PADDING_INFO pss;
2309 union padding32
2311 struct
2313 PTR32 pszAlgId;
2314 } pkcs1;
2315 struct
2317 PTR32 pszAlgId;
2318 ULONG cbSalt;
2319 } pss;
2322 static union padding *get_padding( union padding32 *padding32, union padding *padding, ULONG flags)
2324 if (!padding32) return NULL;
2326 switch (flags)
2328 case BCRYPT_PAD_PKCS1:
2329 padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
2330 return padding;
2331 case BCRYPT_PAD_PSS:
2332 padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
2333 padding->pss.cbSalt = padding32->pss.cbSalt;
2334 return padding;
2335 default:
2336 break;
2338 return NULL;
2341 static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
2343 key->hdr = key32->hdr;
2344 key->alg_id = key32->alg_id;
2345 key->private[0] = key32->private[0];
2346 key->private[1] = key32->private[1];
2347 key->u.s.mode = key32->u.s.mode;
2348 key->u.s.block_size = key32->u.s.block_size;
2349 key->u.s.vector = ULongToPtr(key32->u.s.vector);
2350 key->u.s.vector_len = key32->u.s.vector_len;
2351 key->u.s.secret = ULongToPtr(key32->u.s.secret);
2352 key->u.s.secret_len = key32->u.s.secret_len;
2353 return key;
2356 static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2358 key->hdr = key32->hdr;
2359 key->alg_id = key32->alg_id;
2360 key->private[0] = key32->private[0];
2361 key->private[1] = key32->private[1];
2362 key->u.a.bitlen = key32->u.a.bitlen;
2363 key->u.a.flags = key32->u.a.flags;
2364 key->u.a.dss_seed = key32->u.a.dss_seed;
2365 return key;
2368 static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2370 key32->private[0] = key->private[0];
2371 key32->private[1] = key->private[1];
2374 static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2376 key32->private[0] = key->private[0];
2377 key32->private[1] = key->private[1];
2378 key32->u.a.flags = key->u.a.flags;
2379 key32->u.a.dss_seed = key->u.a.dss_seed;
2382 static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
2384 NTSTATUS ret;
2385 struct key key;
2386 struct key32 *key32 = args;
2388 ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
2389 put_symmetric_key32( &key, key32 );
2390 return ret;
2393 static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
2395 struct
2397 PTR32 key;
2398 PTR32 auth_data;
2399 ULONG len;
2400 } const *params32 = args;
2402 NTSTATUS ret;
2403 struct key key;
2404 struct key32 *key32 = ULongToPtr( params32->key );
2405 struct key_symmetric_set_auth_data_params params =
2407 get_symmetric_key( key32, &key ),
2408 ULongToPtr(params32->auth_data),
2409 params32->len
2412 ret = key_symmetric_set_auth_data( &params );
2413 put_symmetric_key32( &key, key32 );
2414 return ret;
2417 static NTSTATUS wow64_key_symmetric_encrypt( void *args )
2419 struct
2421 PTR32 key;
2422 PTR32 input;
2423 ULONG input_len;
2424 PTR32 output;
2425 ULONG output_len;
2426 } const *params32 = args;
2428 NTSTATUS ret;
2429 struct key key;
2430 struct key32 *key32 = ULongToPtr( params32->key );
2431 struct key_symmetric_encrypt_params params =
2433 get_symmetric_key( key32, &key ),
2434 ULongToPtr(params32->input),
2435 params32->input_len,
2436 ULongToPtr(params32->output),
2437 params32->output_len
2440 ret = key_symmetric_encrypt( &params );
2441 put_symmetric_key32( &key, key32 );
2442 return ret;
2445 static NTSTATUS wow64_key_symmetric_decrypt( void *args )
2447 struct
2449 PTR32 key;
2450 PTR32 input;
2451 ULONG input_len;
2452 PTR32 output;
2453 ULONG output_len;
2454 } const *params32 = args;
2456 NTSTATUS ret;
2457 struct key key;
2458 struct key32 *key32 = ULongToPtr( params32->key );
2459 struct key_symmetric_decrypt_params params =
2461 get_symmetric_key( key32, &key ),
2462 ULongToPtr(params32->input),
2463 params32->input_len,
2464 ULongToPtr(params32->output),
2465 params32->output_len
2468 ret = key_symmetric_decrypt( &params );
2469 put_symmetric_key32( &key, key32 );
2470 return ret;
2473 static NTSTATUS wow64_key_symmetric_get_tag( void *args )
2475 struct
2477 PTR32 key;
2478 PTR32 tag;
2479 ULONG len;
2480 } const *params32 = args;
2482 NTSTATUS ret;
2483 struct key key;
2484 struct key32 *key32 = ULongToPtr( params32->key );
2485 struct key_symmetric_get_tag_params params =
2487 get_symmetric_key( key32, &key ),
2488 ULongToPtr(params32->tag),
2489 params32->len
2492 ret = key_symmetric_get_tag( &params );
2493 put_symmetric_key32( &key, key32 );
2494 return ret;
2497 static NTSTATUS wow64_key_symmetric_destroy( void *args )
2499 struct key32 *key32 = args;
2500 struct key key;
2502 return key_symmetric_destroy( get_symmetric_key( key32, &key ));
2505 static NTSTATUS wow64_key_asymmetric_generate( void *args )
2507 struct key32 *key32 = args;
2508 struct key key;
2509 NTSTATUS ret;
2511 ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
2512 put_asymmetric_key32( &key, key32 );
2513 return ret;
2516 static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
2518 struct
2520 PTR32 key;
2521 PTR32 input;
2522 ULONG input_len;
2523 PTR32 output;
2524 ULONG output_len;
2525 PTR32 ret_len;
2526 } const *params32 = args;
2528 NTSTATUS ret;
2529 struct key key;
2530 struct key32 *key32 = ULongToPtr( params32->key );
2531 struct key_asymmetric_decrypt_params params =
2533 get_asymmetric_key( key32, &key ),
2534 ULongToPtr(params32->input),
2535 params32->input_len,
2536 ULongToPtr(params32->output),
2537 params32->output_len,
2538 ULongToPtr(params32->ret_len)
2541 ret = key_asymmetric_decrypt( &params );
2542 put_asymmetric_key32( &key, key32 );
2543 return ret;
2546 static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
2548 struct
2550 PTR32 key;
2551 PTR32 input;
2552 ULONG input_len;
2553 PTR32 output;
2554 ULONG output_len;
2555 PTR32 ret_len;
2556 } const *params32 = args;
2558 NTSTATUS ret;
2559 struct key key;
2560 struct key32 *key32 = ULongToPtr( params32->key );
2561 struct key_asymmetric_encrypt_params params =
2563 get_asymmetric_key( key32, &key ),
2564 ULongToPtr(params32->input),
2565 params32->input_len,
2566 ULongToPtr(params32->output),
2567 params32->output_len,
2568 ULongToPtr(params32->ret_len)
2571 ret = key_asymmetric_encrypt( &params );
2572 put_asymmetric_key32( &key, key32 );
2573 return ret;
2576 static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
2578 struct
2580 PTR32 key_orig;
2581 PTR32 key_copy;
2582 } const *params32 = args;
2584 NTSTATUS ret;
2585 struct key key_orig, key_copy;
2586 struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
2587 struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
2588 struct key_asymmetric_duplicate_params params =
2590 get_asymmetric_key( key_orig32, &key_orig ),
2591 get_asymmetric_key( key_copy32, &key_copy )
2594 ret = key_asymmetric_duplicate( &params );
2595 put_asymmetric_key32( &key_copy, key_copy32 );
2596 return ret;
2599 static NTSTATUS wow64_key_asymmetric_sign( void *args )
2601 struct
2603 PTR32 key;
2604 PTR32 padding;
2605 PTR32 input;
2606 ULONG input_len;
2607 PTR32 output;
2608 ULONG output_len;
2609 PTR32 ret_len;
2610 ULONG flags;
2611 } const *params32 = args;
2613 NTSTATUS ret;
2614 struct key key;
2615 union padding padding;
2616 struct key32 *key32 = ULongToPtr( params32->key );
2617 struct key_asymmetric_sign_params params =
2619 get_asymmetric_key( key32, &key ),
2620 get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
2621 ULongToPtr(params32->input),
2622 params32->input_len,
2623 ULongToPtr(params32->output),
2624 params32->output_len,
2625 ULongToPtr(params32->ret_len),
2626 params32->flags
2629 ret = key_asymmetric_sign( &params );
2630 put_asymmetric_key32( &key, key32 );
2631 return ret;
2634 static NTSTATUS wow64_key_asymmetric_verify( void *args )
2636 struct
2638 PTR32 key;
2639 PTR32 padding;
2640 PTR32 hash;
2641 ULONG hash_len;
2642 PTR32 signature;
2643 ULONG signature_len;
2644 ULONG flags;
2645 } const *params32 = args;
2647 NTSTATUS ret;
2648 struct key key;
2649 union padding padding;
2650 struct key32 *key32 = ULongToPtr( params32->key );
2651 struct key_asymmetric_verify_params params =
2653 get_asymmetric_key( key32, &key ),
2654 get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
2655 ULongToPtr(params32->hash),
2656 params32->hash_len,
2657 ULongToPtr(params32->signature),
2658 params32->signature_len,
2659 params32->flags
2662 ret = key_asymmetric_verify( &params );
2663 put_asymmetric_key32( &key, key32 );
2664 return ret;
2667 static NTSTATUS wow64_key_asymmetric_destroy( void *args )
2669 struct key32 *key32 = args;
2670 struct key key;
2672 return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
2675 static NTSTATUS wow64_key_asymmetric_export( void *args )
2677 struct
2679 PTR32 key;
2680 ULONG flags;
2681 PTR32 buf;
2682 ULONG len;
2683 PTR32 ret_len;
2684 } const *params32 = args;
2686 NTSTATUS ret;
2687 struct key key;
2688 struct key32 *key32 = ULongToPtr( params32->key );
2689 struct key_asymmetric_export_params params =
2691 get_asymmetric_key( key32, &key ),
2692 params32->flags,
2693 ULongToPtr(params32->buf),
2694 params32->len,
2695 ULongToPtr(params32->ret_len),
2698 ret = key_asymmetric_export( &params );
2699 put_asymmetric_key32( &key, key32 );
2700 return ret;
2703 static NTSTATUS wow64_key_asymmetric_import( void *args )
2705 struct
2707 PTR32 key;
2708 ULONG flags;
2709 PTR32 buf;
2710 ULONG len;
2711 } const *params32 = args;
2713 NTSTATUS ret;
2714 struct key key;
2715 struct key32 *key32 = ULongToPtr( params32->key );
2716 struct key_asymmetric_import_params params =
2718 get_asymmetric_key( key32, &key ),
2719 params32->flags,
2720 ULongToPtr(params32->buf),
2721 params32->len
2724 ret = key_asymmetric_import( &params );
2725 put_asymmetric_key32( &key, key32 );
2726 return ret;
2729 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
2731 gnutls_process_attach,
2732 gnutls_process_detach,
2733 wow64_key_symmetric_vector_reset,
2734 wow64_key_symmetric_set_auth_data,
2735 wow64_key_symmetric_encrypt,
2736 wow64_key_symmetric_decrypt,
2737 wow64_key_symmetric_get_tag,
2738 wow64_key_symmetric_destroy,
2739 wow64_key_asymmetric_generate,
2740 wow64_key_asymmetric_decrypt,
2741 wow64_key_asymmetric_encrypt,
2742 wow64_key_asymmetric_duplicate,
2743 wow64_key_asymmetric_sign,
2744 wow64_key_asymmetric_verify,
2745 wow64_key_asymmetric_destroy,
2746 wow64_key_asymmetric_export,
2747 wow64_key_asymmetric_import
2750 #endif /* _WIN64 */
2752 #endif /* HAVE_GNUTLS_CIPHER_INIT */