win32u: Avoid invalid access when registered device alloc failed. (Coverity).
[wine.git] / dlls / bcrypt / gnutls.c
blob9d52b7360cecaeb7841d2eb6195b3faf28921e4c
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 union key_data
74 gnutls_cipher_hd_t cipher;
75 struct
77 gnutls_privkey_t privkey;
78 gnutls_pubkey_t pubkey;
79 } a;
81 C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
83 static union key_data *key_data( struct key *key )
85 return (union key_data *)key->private;
88 /* Not present in gnutls version < 3.0 */
89 static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
90 static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
91 static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign)(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
92 static int (*pgnutls_pubkey_import_ecc_raw)(gnutls_pubkey_t, gnutls_ecc_curve_t,
93 const gnutls_datum_t *, const gnutls_datum_t *);
94 static int (*pgnutls_pubkey_export_ecc_raw)(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
95 gnutls_datum_t *x, gnutls_datum_t *y);
96 static int (*pgnutls_privkey_import_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t, const gnutls_datum_t *,
97 const gnutls_datum_t *, const gnutls_datum_t *);
98 static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t, gnutls_sign_algorithm_t, unsigned int,
99 const gnutls_datum_t *, const gnutls_datum_t *);
100 static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t, unsigned int flags, const gnutls_datum_t *,
101 gnutls_datum_t *);
103 /* Not present in gnutls version < 2.11.0 */
104 static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
106 /* Not present in gnutls version < 2.12.0 */
107 static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
108 const gnutls_datum_t *, const gnutls_datum_t *);
109 static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
110 static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *,
111 gnutls_datum_t *);
113 /* Not present in gnutls version < 3.3.0 */
114 static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
115 gnutls_datum_t *);
116 static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
117 static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
118 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
119 static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
120 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
121 gnutls_datum_t *);
122 static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
123 gnutls_datum_t *, gnutls_datum_t *);
124 static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int);
125 static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
126 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
127 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
129 /* Not present in gnutls version < 3.6.0 */
130 static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
132 static void *libgnutls_handle;
133 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
134 MAKE_FUNCPTR(gnutls_cipher_decrypt2);
135 MAKE_FUNCPTR(gnutls_cipher_deinit);
136 MAKE_FUNCPTR(gnutls_cipher_encrypt2);
137 MAKE_FUNCPTR(gnutls_cipher_init);
138 MAKE_FUNCPTR(gnutls_global_deinit);
139 MAKE_FUNCPTR(gnutls_global_init);
140 MAKE_FUNCPTR(gnutls_global_set_log_function);
141 MAKE_FUNCPTR(gnutls_global_set_log_level);
142 MAKE_FUNCPTR(gnutls_perror);
143 MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
144 MAKE_FUNCPTR(gnutls_privkey_deinit);
145 MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
146 MAKE_FUNCPTR(gnutls_privkey_init);
147 MAKE_FUNCPTR(gnutls_privkey_sign_hash);
148 MAKE_FUNCPTR(gnutls_pubkey_deinit);
149 MAKE_FUNCPTR(gnutls_pubkey_encrypt_data);
150 MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
151 MAKE_FUNCPTR(gnutls_pubkey_init);
152 #undef MAKE_FUNCPTR
154 static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
156 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
159 static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
161 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
164 static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
165 const gnutls_datum_t *x, const gnutls_datum_t *y)
167 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
170 static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
171 gnutls_datum_t *x, gnutls_datum_t *y)
173 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
176 static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
177 gnutls_datum_t *g, gnutls_datum_t *y)
179 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
182 static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
184 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
187 static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
188 gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
189 gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
191 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
194 static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
195 gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
197 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
200 static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
201 const gnutls_datum_t *x, const gnutls_datum_t *y,
202 const gnutls_datum_t *k)
204 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
207 static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
208 gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
210 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
213 static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
215 return GNUTLS_SIGN_UNKNOWN;
218 static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
219 unsigned int flags, const gnutls_datum_t *hash,
220 const gnutls_datum_t *signature)
222 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
225 static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
227 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
230 static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
231 const gnutls_datum_t *g, const gnutls_datum_t *y)
233 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
236 static int compat_gnutls_privkey_generate(gnutls_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits,
237 unsigned int flags)
239 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
242 static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
244 return GNUTLS_E_INTERNAL_ERROR;
247 static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
248 const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
249 const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
251 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
254 static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
255 gnutls_datum_t *plain_text)
257 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
260 static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
261 gnutls_datum_t *plain_text)
263 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
266 static void gnutls_log( int level, const char *msg )
268 TRACE( "<%d> %s", level, msg );
271 static NTSTATUS gnutls_process_attach( void *args )
273 const char *env_str;
274 int ret;
276 if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
278 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
280 else
282 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
283 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
286 if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
288 ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
289 return STATUS_DLL_NOT_FOUND;
292 #define LOAD_FUNCPTR(f) \
293 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
295 ERR( "failed to load %s\n", #f ); \
296 goto fail; \
299 LOAD_FUNCPTR(gnutls_cipher_decrypt2)
300 LOAD_FUNCPTR(gnutls_cipher_deinit)
301 LOAD_FUNCPTR(gnutls_cipher_encrypt2)
302 LOAD_FUNCPTR(gnutls_cipher_init)
303 LOAD_FUNCPTR(gnutls_global_deinit)
304 LOAD_FUNCPTR(gnutls_global_init)
305 LOAD_FUNCPTR(gnutls_global_set_log_function)
306 LOAD_FUNCPTR(gnutls_global_set_log_level)
307 LOAD_FUNCPTR(gnutls_perror)
308 LOAD_FUNCPTR(gnutls_privkey_deinit);
309 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
310 LOAD_FUNCPTR(gnutls_privkey_init);
311 LOAD_FUNCPTR(gnutls_privkey_sign_hash);
312 LOAD_FUNCPTR(gnutls_pubkey_deinit);
313 LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
314 LOAD_FUNCPTR(gnutls_pubkey_init);
315 #undef LOAD_FUNCPTR
317 #define LOAD_FUNCPTR_OPT(f) \
318 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
320 WARN( "failed to load %s\n", #f ); \
321 p##f = compat_##f; \
324 LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
325 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
326 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
327 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
328 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
329 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
330 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
331 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
332 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
333 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
334 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
335 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
336 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
337 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
338 LOAD_FUNCPTR_OPT(gnutls_privkey_generate)
339 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
340 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
341 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
342 LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data)
343 #undef LOAD_FUNCPTR_OPT
345 if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
347 pgnutls_perror( ret );
348 goto fail;
351 if (TRACE_ON( bcrypt ))
353 pgnutls_global_set_log_level( 4 );
354 pgnutls_global_set_log_function( gnutls_log );
357 return STATUS_SUCCESS;
359 fail:
360 dlclose( libgnutls_handle );
361 libgnutls_handle = NULL;
362 return STATUS_DLL_NOT_FOUND;
365 static NTSTATUS gnutls_process_detach( void *args )
367 if (libgnutls_handle)
369 pgnutls_global_deinit();
370 dlclose( libgnutls_handle );
371 libgnutls_handle = NULL;
373 return STATUS_SUCCESS;
376 struct buffer
378 BYTE *buffer;
379 DWORD length;
380 DWORD pos;
381 BOOL error;
384 static void buffer_init( struct buffer *buffer )
386 buffer->buffer = NULL;
387 buffer->length = 0;
388 buffer->pos = 0;
389 buffer->error = FALSE;
392 static void buffer_free( struct buffer *buffer )
394 free( buffer->buffer );
397 static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
399 if (!len) return;
401 if (buffer->pos + len > buffer->length)
403 DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
404 BYTE *new_buffer;
406 if (!(new_buffer = realloc( buffer->buffer, new_length )))
408 ERR( "out of memory\n" );
409 buffer->error = TRUE;
410 return;
413 buffer->buffer = new_buffer;
414 buffer->length = new_length;
417 memcpy( &buffer->buffer[buffer->pos], data, len );
418 buffer->pos += len;
421 static void buffer_append_byte( struct buffer *buffer, BYTE value )
423 buffer_append( buffer, &value, sizeof(value) );
426 static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
428 DWORD num_bytes;
430 if (length < 128)
432 buffer_append_byte( buffer, length );
433 return;
436 if (length <= 0xff) num_bytes = 1;
437 else if (length <= 0xffff) num_bytes = 2;
438 else if (length <= 0xffffff) num_bytes = 3;
439 else num_bytes = 4;
441 buffer_append_byte( buffer, 0x80 | num_bytes );
442 while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
445 static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
447 DWORD leading_zero = (*data & 0x80) != 0;
449 buffer_append_byte( buffer, 0x02 ); /* tag */
450 buffer_append_asn1_length( buffer, len + leading_zero );
451 if (leading_zero) buffer_append_byte( buffer, 0 );
452 buffer_append( buffer, data, len );
455 static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
457 if (content->error)
459 buffer->error = TRUE;
460 return;
463 buffer_append_byte( buffer, 0x30 ); /* tag */
464 buffer_append_asn1_length( buffer, content->pos );
465 buffer_append( buffer, content->buffer, content->pos );
468 static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
470 struct buffer value;
472 buffer_init( &value );
473 buffer_append_asn1_integer( &value, r, r_len );
474 buffer_append_asn1_integer( &value, s, s_len );
475 buffer_append_asn1_sequence( buffer, &value );
476 buffer_free( &value );
479 static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
481 switch (key->alg_id)
483 case ALG_ID_3DES:
484 WARN( "handle block size\n" );
485 switch (key->u.s.mode)
487 case MODE_ID_CBC:
488 return GNUTLS_CIPHER_3DES_CBC;
489 default:
490 break;
492 FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
493 return GNUTLS_CIPHER_UNKNOWN;
495 case ALG_ID_AES:
496 WARN( "handle block size\n" );
497 switch (key->u.s.mode)
499 case MODE_ID_GCM:
500 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
501 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
502 break;
503 case MODE_ID_ECB: /* can be emulated with CBC + empty IV */
504 case MODE_ID_CBC:
505 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
506 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
507 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
508 break;
509 case MODE_ID_CFB:
510 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
511 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
512 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
513 break;
514 default:
515 break;
517 FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
518 return GNUTLS_CIPHER_UNKNOWN;
520 default:
521 FIXME( "algorithm %u not supported\n", key->alg_id );
522 return GNUTLS_CIPHER_UNKNOWN;
526 static NTSTATUS key_symmetric_vector_reset( void *args )
528 struct key *key = args;
530 if (!key_data(key)->cipher) return STATUS_SUCCESS;
531 TRACE( "invalidating cipher handle\n" );
532 pgnutls_cipher_deinit( key_data(key)->cipher );
533 key_data(key)->cipher = NULL;
534 return STATUS_SUCCESS;
537 static NTSTATUS init_cipher_handle( struct key *key )
539 gnutls_cipher_algorithm_t cipher;
540 gnutls_datum_t secret, vector;
541 int ret;
543 if (key_data(key)->cipher) return STATUS_SUCCESS;
544 if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
546 secret.data = key->u.s.secret;
547 secret.size = key->u.s.secret_len;
549 vector.data = key->u.s.vector;
550 vector.size = key->u.s.vector_len;
552 if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
554 pgnutls_perror( ret );
555 return STATUS_INTERNAL_ERROR;
558 return STATUS_SUCCESS;
561 static NTSTATUS key_symmetric_set_auth_data( void *args )
563 const struct key_symmetric_set_auth_data_params *params = args;
564 NTSTATUS status;
565 int ret;
567 if (!params->auth_data) return STATUS_SUCCESS;
568 if ((status = init_cipher_handle( params->key ))) return status;
570 if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
572 pgnutls_perror( ret );
573 return STATUS_INTERNAL_ERROR;
575 return STATUS_SUCCESS;
578 static NTSTATUS key_symmetric_encrypt( void *args )
580 const struct key_symmetric_encrypt_params *params = args;
581 NTSTATUS status;
582 int ret;
584 if ((status = init_cipher_handle( params->key ))) return status;
586 if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
587 params->output, params->output_len )))
589 pgnutls_perror( ret );
590 return STATUS_INTERNAL_ERROR;
592 return STATUS_SUCCESS;
595 static NTSTATUS key_symmetric_decrypt( void *args )
597 const struct key_symmetric_decrypt_params *params = args;
598 NTSTATUS status;
599 int ret;
601 if ((status = init_cipher_handle( params->key ))) return status;
603 if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
604 params->output, params->output_len )))
606 pgnutls_perror( ret );
607 return STATUS_INTERNAL_ERROR;
609 return STATUS_SUCCESS;
612 static NTSTATUS key_symmetric_get_tag( void *args )
614 const struct key_symmetric_get_tag_params *params = args;
615 NTSTATUS status;
616 int ret;
618 if ((status = init_cipher_handle( params->key ))) return status;
620 if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
622 pgnutls_perror( ret );
623 return STATUS_INTERNAL_ERROR;
625 return STATUS_SUCCESS;
628 static NTSTATUS key_symmetric_destroy( void *args )
630 struct key *key = args;
632 if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
633 return STATUS_SUCCESS;
636 static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
638 ULONG size = d->size;
639 UCHAR *src = d->data;
640 ULONG offset = 0;
642 assert( size <= buflen + 1 );
643 if (size == buflen + 1)
645 assert( !src[0] );
646 src++;
647 size--;
649 if (zero_pad)
651 offset = buflen - size;
652 if (buffer) memset( buffer, 0, offset );
653 size = buflen;
656 if (buffer) memcpy( buffer + offset, src, size );
657 return size;
660 #define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p )
661 static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
663 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
664 gnutls_datum_t m, e;
665 UCHAR *dst;
666 int ret;
668 if (key_data(key)->a.pubkey)
669 ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
670 else if (key_data(key)->a.privkey)
671 ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL );
672 else
673 return STATUS_INVALID_PARAMETER;
675 if (ret)
677 pgnutls_perror( ret );
678 return STATUS_INTERNAL_ERROR;
681 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1);
682 if (len >= *ret_len && buf)
684 dst = (UCHAR *)(rsa_blob + 1);
685 rsa_blob->cbPublicExp = export_gnutls_datum( dst, key->u.a.bitlen / 8, &e, 0 );
687 dst += rsa_blob->cbPublicExp;
688 rsa_blob->cbModulus = export_gnutls_datum( dst, key->u.a.bitlen / 8, &m, 1 );
690 rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
691 rsa_blob->BitLength = key->u.a.bitlen;
692 rsa_blob->cbPrime1 = 0;
693 rsa_blob->cbPrime2 = 0;
696 free( e.data ); free( m.data );
697 return STATUS_SUCCESS;
700 static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
702 BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
703 gnutls_ecc_curve_t curve;
704 gnutls_datum_t x, y;
705 DWORD magic, size;
706 UCHAR *dst;
707 int ret;
709 switch (key->alg_id)
711 case ALG_ID_ECDH_P256:
712 magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
713 size = 32;
714 break;
715 case ALG_ID_ECDSA_P256:
716 magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
717 size = 32;
718 break;
719 default:
720 FIXME( "algorithm %u not supported\n", key->alg_id );
721 return STATUS_NOT_IMPLEMENTED;
724 if (key_data(key)->a.pubkey)
725 ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
726 else if (key_data(key)->a.privkey)
727 ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, NULL );
728 else
729 return STATUS_INVALID_PARAMETER;
731 if (ret)
733 pgnutls_perror( ret );
734 return STATUS_INTERNAL_ERROR;
737 if (curve != GNUTLS_ECC_CURVE_SECP256R1)
739 FIXME( "curve %u not supported\n", curve );
740 free( x.data ); free( y.data );
741 return STATUS_NOT_IMPLEMENTED;
744 *ret_len = sizeof(*ecc_blob) + size * 2;
745 if (len >= *ret_len && buf)
747 ecc_blob->dwMagic = magic;
748 ecc_blob->cbKey = size;
750 dst = (UCHAR *)(ecc_blob + 1);
751 export_gnutls_datum( dst, size, &x, 1 );
753 dst += size;
754 export_gnutls_datum( dst, size, &y, 1 );
757 free( x.data ); free( y.data );
758 return STATUS_SUCCESS;
761 static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
763 BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
764 gnutls_datum_t p, q, g, y;
765 UCHAR *dst;
766 int ret;
768 if (key_data(key)->a.pubkey)
769 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
770 else if (key_data(key)->a.privkey)
771 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
772 else
773 return STATUS_INVALID_PARAMETER;
775 if (ret)
777 pgnutls_perror( ret );
778 return STATUS_INTERNAL_ERROR;
781 if (key->u.a.bitlen > 1024)
783 FIXME( "bitlen > 1024 not supported\n" );
784 return STATUS_NOT_IMPLEMENTED;
787 *ret_len = sizeof(*dsa_blob) + key->u.a.bitlen / 8 * 3;
788 if (len >= *ret_len && buf)
790 dst = (UCHAR *)(dsa_blob + 1);
791 export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
793 dst += key->u.a.bitlen / 8;
794 export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
796 dst += key->u.a.bitlen / 8;
797 export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
799 dst = dsa_blob->q;
800 export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
802 dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
803 dsa_blob->cbKey = key->u.a.bitlen / 8;
804 memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
805 memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
808 free( p.data ); free( q.data ); free( g.data ); free( y.data );
809 return STATUS_SUCCESS;
812 static void reverse_bytes( UCHAR *buf, ULONG len )
814 unsigned int i;
815 UCHAR tmp;
817 for (i = 0; i < len / 2; ++i)
819 tmp = buf[i];
820 buf[i] = buf[len - i - 1];
821 buf[len - i - 1] = tmp;
825 #define Q_SIZE 20
826 static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
828 BLOBHEADER *hdr = (BLOBHEADER *)buf;
829 DSSPUBKEY *dsskey;
830 gnutls_datum_t p, q, g, y;
831 UCHAR *dst;
832 int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed);
834 if (key->u.a.bitlen > 1024)
836 FIXME( "bitlen > 1024 not supported\n" );
837 return STATUS_NOT_IMPLEMENTED;
840 if (key_data(key)->a.pubkey)
841 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
842 else if (key_data(key)->a.privkey)
843 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
844 else
845 return STATUS_INVALID_PARAMETER;
847 if (ret)
849 pgnutls_perror( ret );
850 return STATUS_INTERNAL_ERROR;
853 *ret_len = size + key->u.a.bitlen / 8 * 3 + Q_SIZE;
854 if (len >= *ret_len && buf)
856 hdr->bType = PUBLICKEYBLOB;
857 hdr->bVersion = 2;
858 hdr->reserved = 0;
859 hdr->aiKeyAlg = CALG_DSS_SIGN;
861 dsskey = (DSSPUBKEY *)(hdr + 1);
862 dsskey->magic = MAGIC_DSS1;
863 dsskey->bitlen = key->u.a.bitlen;
865 dst = (UCHAR *)(dsskey + 1);
866 export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
867 reverse_bytes( dst, key->u.a.bitlen / 8 );
868 dst += key->u.a.bitlen / 8;
870 export_gnutls_datum( dst, Q_SIZE, &q, 1 );
871 reverse_bytes( dst, Q_SIZE );
872 dst += Q_SIZE;
874 export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
875 reverse_bytes( dst, key->u.a.bitlen / 8 );
876 dst += key->u.a.bitlen / 8;
878 export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
879 reverse_bytes( dst, key->u.a.bitlen / 8 );
880 dst += key->u.a.bitlen / 8;
882 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
885 free( p.data ); free( q.data ); free( g.data ); free( y.data );
886 return STATUS_SUCCESS;
889 static NTSTATUS key_asymmetric_generate( void *args )
891 struct key *key = args;
892 gnutls_pk_algorithm_t pk_alg;
893 gnutls_privkey_t privkey;
894 gnutls_pubkey_t pubkey;
895 unsigned int bitlen;
896 int ret;
898 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
899 if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
901 switch (key->alg_id)
903 case ALG_ID_RSA:
904 case ALG_ID_RSA_SIGN:
905 pk_alg = GNUTLS_PK_RSA;
906 bitlen = key->u.a.bitlen;
907 break;
909 case ALG_ID_DSA:
910 pk_alg = GNUTLS_PK_DSA;
911 bitlen = key->u.a.bitlen;
912 break;
914 case ALG_ID_ECDH_P256:
915 case ALG_ID_ECDSA_P256:
916 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
917 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
918 break;
920 default:
921 FIXME( "algorithm %u not supported\n", key->alg_id );
922 return STATUS_NOT_SUPPORTED;
925 if ((ret = pgnutls_privkey_init( &privkey )))
927 pgnutls_perror( ret );
928 return STATUS_INTERNAL_ERROR;
930 if ((ret = pgnutls_pubkey_init( &pubkey )))
932 pgnutls_perror( ret );
933 pgnutls_privkey_deinit( privkey );
934 return STATUS_INTERNAL_ERROR;
937 if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
939 pgnutls_perror( ret );
940 pgnutls_privkey_deinit( privkey );
941 pgnutls_pubkey_deinit( pubkey );
942 return STATUS_INTERNAL_ERROR;
944 if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
946 pgnutls_perror( ret );
947 pgnutls_privkey_deinit( privkey );
948 pgnutls_pubkey_deinit( pubkey );
949 return STATUS_INTERNAL_ERROR;
952 key_data(key)->a.privkey = privkey;
953 key_data(key)->a.pubkey = pubkey;
954 return STATUS_SUCCESS;
957 static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
959 BCRYPT_ECCKEY_BLOB *ecc_blob;
960 gnutls_ecc_curve_t curve;
961 gnutls_datum_t x, y, d;
962 DWORD magic, size;
963 UCHAR *dst;
964 int ret;
966 switch (key->alg_id)
968 case ALG_ID_ECDH_P256:
969 magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
970 size = 32;
971 break;
972 case ALG_ID_ECDSA_P256:
973 magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
974 size = 32;
975 break;
977 default:
978 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
979 return STATUS_NOT_IMPLEMENTED;
982 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
984 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
986 pgnutls_perror( ret );
987 return STATUS_INTERNAL_ERROR;
990 if (curve != GNUTLS_ECC_CURVE_SECP256R1)
992 FIXME( "curve %u not supported\n", curve );
993 free( x.data ); free( y.data ); free( d.data );
994 return STATUS_NOT_IMPLEMENTED;
997 *ret_len = sizeof(*ecc_blob) + size * 3;
998 if (len >= *ret_len && buf)
1000 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1001 ecc_blob->dwMagic = magic;
1002 ecc_blob->cbKey = size;
1004 dst = (UCHAR *)(ecc_blob + 1);
1005 export_gnutls_datum( dst, size, &x, 1 );
1006 dst += size;
1008 export_gnutls_datum( dst, size, &y, 1 );
1009 dst += size;
1011 export_gnutls_datum( dst, size, &d, 1 );
1014 free( x.data ); free( y.data ); free( d.data );
1015 return STATUS_SUCCESS;
1018 static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1020 BCRYPT_ECCKEY_BLOB *ecc_blob;
1021 gnutls_ecc_curve_t curve;
1022 gnutls_privkey_t handle;
1023 gnutls_datum_t x, y, k;
1024 int ret;
1026 switch (key->alg_id)
1028 case ALG_ID_ECDH_P256:
1029 case ALG_ID_ECDSA_P256:
1030 curve = GNUTLS_ECC_CURVE_SECP256R1;
1031 break;
1033 default:
1034 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1035 return STATUS_NOT_IMPLEMENTED;
1038 if ((ret = pgnutls_privkey_init( &handle )))
1040 pgnutls_perror( ret );
1041 return STATUS_INTERNAL_ERROR;
1044 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1045 x.data = (unsigned char *)(ecc_blob + 1);
1046 x.size = ecc_blob->cbKey;
1047 y.data = x.data + ecc_blob->cbKey;
1048 y.size = ecc_blob->cbKey;
1049 k.data = y.data + ecc_blob->cbKey;
1050 k.size = ecc_blob->cbKey;
1052 if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1054 pgnutls_perror( ret );
1055 pgnutls_privkey_deinit( handle );
1056 return STATUS_INTERNAL_ERROR;
1059 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1060 key_data(key)->a.privkey = handle;
1061 return STATUS_SUCCESS;
1064 static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1066 BCRYPT_RSAKEY_BLOB *rsa_blob;
1067 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1068 ULONG bitlen = key->u.a.bitlen;
1069 BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1070 UCHAR *dst;
1071 int ret;
1073 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1075 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1077 pgnutls_perror( ret );
1078 return STATUS_INTERNAL_ERROR;
1081 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1) + EXPORT_SIZE(p,16,1) + EXPORT_SIZE(q,16,1);
1082 if (full) *ret_len += EXPORT_SIZE(e1,16,1) + EXPORT_SIZE(e2,16,1) + EXPORT_SIZE(u,16,1) + EXPORT_SIZE(d,8,1);
1084 if (len >= *ret_len && buf)
1086 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1087 rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1088 rsa_blob->BitLength = bitlen;
1090 dst = (UCHAR *)(rsa_blob + 1);
1091 rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 );
1093 dst += rsa_blob->cbPublicExp;
1094 rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 );
1096 dst += rsa_blob->cbModulus;
1097 rsa_blob->cbPrime1 = export_gnutls_datum( dst, bitlen / 16, &p, 1 );
1099 dst += rsa_blob->cbPrime1;
1100 rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 );
1102 if (full)
1104 dst += rsa_blob->cbPrime2;
1105 export_gnutls_datum( dst, bitlen / 16, &e1, 1 );
1107 dst += rsa_blob->cbPrime1;
1108 export_gnutls_datum( dst, bitlen / 16, &e2, 1 );
1110 dst += rsa_blob->cbPrime2;
1111 export_gnutls_datum( dst, bitlen / 16, &u, 1 );
1113 dst += rsa_blob->cbPrime1;
1114 export_gnutls_datum( dst, bitlen / 8, &d, 1 );
1118 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1119 free( e1.data ); free( e2.data );
1120 return STATUS_SUCCESS;
1123 static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1125 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1126 gnutls_datum_t m, e, p, q;
1127 gnutls_privkey_t handle;
1128 int ret;
1130 if ((ret = pgnutls_privkey_init( &handle )))
1132 pgnutls_perror( ret );
1133 return STATUS_INTERNAL_ERROR;
1136 e.data = (unsigned char *)(rsa_blob + 1);
1137 e.size = rsa_blob->cbPublicExp;
1138 m.data = e.data + e.size;
1139 m.size = rsa_blob->cbModulus;
1140 p.data = m.data + m.size;
1141 p.size = rsa_blob->cbPrime1;
1142 q.data = p.data + p.size;
1143 q.size = rsa_blob->cbPrime2;
1145 if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1147 pgnutls_perror( ret );
1148 pgnutls_privkey_deinit( handle );
1149 return STATUS_INTERNAL_ERROR;
1152 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1153 key_data(key)->a.privkey = handle;
1154 return STATUS_SUCCESS;
1157 static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1159 BLOBHEADER *hdr;
1160 DSSPUBKEY *pubkey;
1161 gnutls_datum_t p, q, g, y, x;
1162 UCHAR *dst;
1163 int ret, size;
1165 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1167 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1169 pgnutls_perror( ret );
1170 return STATUS_INTERNAL_ERROR;
1173 if (q.size > 21 || x.size > 21)
1175 ERR( "can't export key in this format\n" );
1176 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1177 return STATUS_NOT_SUPPORTED;
1180 size = key->u.a.bitlen / 8;
1181 *ret_len = sizeof(*hdr) + sizeof(*pubkey) + size * 2 + 40 + sizeof(key->u.a.dss_seed);
1182 if (len >= *ret_len && buf)
1184 hdr = (BLOBHEADER *)buf;
1185 hdr->bType = PRIVATEKEYBLOB;
1186 hdr->bVersion = 2;
1187 hdr->reserved = 0;
1188 hdr->aiKeyAlg = CALG_DSS_SIGN;
1190 pubkey = (DSSPUBKEY *)(hdr + 1);
1191 pubkey->magic = MAGIC_DSS2;
1192 pubkey->bitlen = key->u.a.bitlen;
1194 dst = (UCHAR *)(pubkey + 1);
1195 export_gnutls_datum( dst, size, &p, 1 );
1196 reverse_bytes( dst, size );
1197 dst += size;
1199 export_gnutls_datum( dst, 20, &q, 1 );
1200 reverse_bytes( dst, 20 );
1201 dst += 20;
1203 export_gnutls_datum( dst, size, &g, 1 );
1204 reverse_bytes( dst, size );
1205 dst += size;
1207 export_gnutls_datum( dst, 20, &x, 1 );
1208 reverse_bytes( dst, 20 );
1209 dst += 20;
1211 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1214 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1215 return STATUS_SUCCESS;
1218 static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1220 BLOBHEADER *hdr = (BLOBHEADER *)buf;
1221 DSSPUBKEY *pubkey;
1222 gnutls_privkey_t handle;
1223 gnutls_datum_t p, q, g, x;
1224 unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1225 int i, ret, size;
1227 if ((ret = pgnutls_privkey_init( &handle )))
1229 pgnutls_perror( ret );
1230 return STATUS_INTERNAL_ERROR;
1233 pubkey = (DSSPUBKEY *)(hdr + 1);
1234 if ((size = pubkey->bitlen / 8) > sizeof(p_data))
1236 FIXME( "size %u not supported\n", size );
1237 pgnutls_privkey_deinit( handle );
1238 return STATUS_NOT_SUPPORTED;
1240 data = (unsigned char *)(pubkey + 1);
1242 p.data = p_data;
1243 p.size = size;
1244 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1245 data += p.size;
1247 q.data = q_data;
1248 q.size = sizeof(q_data);
1249 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1250 data += q.size;
1252 g.data = g_data;
1253 g.size = size;
1254 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1255 data += g.size;
1257 x.data = x_data;
1258 x.size = sizeof(x_data);
1259 for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1260 data += x.size;
1262 if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1264 pgnutls_perror( ret );
1265 pgnutls_privkey_deinit( handle );
1266 return STATUS_INTERNAL_ERROR;
1269 memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1271 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1272 key_data(key)->a.privkey = handle;
1273 return STATUS_SUCCESS;
1276 static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1278 BCRYPT_ECCKEY_BLOB *ecc_blob;
1279 gnutls_ecc_curve_t curve;
1280 gnutls_datum_t x, y;
1281 gnutls_pubkey_t handle;
1282 int ret;
1284 switch (key->alg_id)
1286 case ALG_ID_ECDH_P256:
1287 case ALG_ID_ECDSA_P256: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1288 case ALG_ID_ECDSA_P384: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1290 default:
1291 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1292 return STATUS_NOT_IMPLEMENTED;
1295 if ((ret = pgnutls_pubkey_init( &handle )))
1297 pgnutls_perror( ret );
1298 return STATUS_INTERNAL_ERROR;
1301 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1302 x.data = buf + sizeof(*ecc_blob);
1303 x.size = ecc_blob->cbKey;
1304 y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1305 y.size = ecc_blob->cbKey;
1307 if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1309 pgnutls_perror( ret );
1310 pgnutls_pubkey_deinit( handle );
1311 return STATUS_INTERNAL_ERROR;
1314 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1315 key_data(key)->a.pubkey = handle;
1316 return STATUS_SUCCESS;
1319 static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1321 BCRYPT_RSAKEY_BLOB *rsa_blob;
1322 gnutls_pubkey_t handle;
1323 gnutls_datum_t m, e;
1324 int ret;
1326 if ((ret = pgnutls_pubkey_init( &handle )))
1328 pgnutls_perror( ret );
1329 return STATUS_INTERNAL_ERROR;
1332 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1333 e.data = buf + sizeof(*rsa_blob);
1334 e.size = rsa_blob->cbPublicExp;
1335 m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1336 m.size = rsa_blob->cbModulus;
1338 if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1340 pgnutls_perror( ret );
1341 pgnutls_pubkey_deinit( handle );
1342 return STATUS_INTERNAL_ERROR;
1345 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1346 key_data(key)->a.pubkey = handle;
1347 return STATUS_SUCCESS;
1350 static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1352 BCRYPT_DSA_KEY_BLOB *dsa_blob;
1353 gnutls_datum_t p, q, g, y;
1354 gnutls_pubkey_t handle;
1355 int ret;
1357 if ((ret = pgnutls_pubkey_init( &handle )))
1359 pgnutls_perror( ret );
1360 return STATUS_INTERNAL_ERROR;
1363 dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1364 p.data = buf + sizeof(*dsa_blob);
1365 p.size = dsa_blob->cbKey;
1366 q.data = dsa_blob->q;
1367 q.size = sizeof(dsa_blob->q);
1368 g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1369 g.size = dsa_blob->cbKey;
1370 y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1371 y.size = dsa_blob->cbKey;
1373 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1375 pgnutls_perror( ret );
1376 pgnutls_pubkey_deinit( handle );
1377 return STATUS_INTERNAL_ERROR;
1380 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1381 key_data(key)->a.pubkey = handle;
1382 return STATUS_SUCCESS;
1385 static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1387 BLOBHEADER *hdr;
1388 DSSPUBKEY *pubkey;
1389 gnutls_datum_t p, q, g, y;
1390 gnutls_pubkey_t handle;
1391 unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1392 int i, ret, size;
1394 if ((ret = pgnutls_pubkey_init( &handle )))
1396 pgnutls_perror( ret );
1397 return STATUS_INTERNAL_ERROR;
1400 hdr = (BLOBHEADER *)buf;
1401 pubkey = (DSSPUBKEY *)(hdr + 1);
1402 size = pubkey->bitlen / 8;
1403 data = (unsigned char *)(pubkey + 1);
1405 p.data = p_data;
1406 p.size = size;
1407 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1408 data += p.size;
1410 q.data = q_data;
1411 q.size = sizeof(q_data);
1412 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1413 data += q.size;
1415 g.data = g_data;
1416 g.size = size;
1417 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1418 data += g.size;
1420 y.data = y_data;
1421 y.size = sizeof(y_data);
1422 for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1424 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1426 pgnutls_perror( ret );
1427 pgnutls_pubkey_deinit( handle );
1428 return STATUS_INTERNAL_ERROR;
1431 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1432 key_data(key)->a.pubkey = handle;
1433 return STATUS_SUCCESS;
1436 static NTSTATUS key_asymmetric_export( void *args )
1438 const struct key_asymmetric_export_params *params = args;
1439 struct key *key = params->key;
1440 unsigned flags = params->flags;
1442 switch (key->alg_id)
1444 case ALG_ID_ECDH_P256:
1445 case ALG_ID_ECDSA_P256:
1446 case ALG_ID_ECDSA_P384:
1447 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1448 return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1449 return key_export_ecc( key, params->buf, params->len, params->ret_len );
1451 case ALG_ID_RSA:
1452 case ALG_ID_RSA_SIGN:
1453 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1454 return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1455 return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1457 case ALG_ID_DSA:
1458 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1460 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1461 return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1462 return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1464 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1465 return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1466 return STATUS_NOT_IMPLEMENTED;
1468 default:
1469 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1470 return STATUS_NOT_IMPLEMENTED;
1474 static NTSTATUS key_asymmetric_import( void *args )
1476 const struct key_asymmetric_import_params *params = args;
1477 struct key *key = params->key;
1478 unsigned flags = params->flags;
1480 switch (key->alg_id)
1482 case ALG_ID_ECDH_P256:
1483 case ALG_ID_ECDSA_P256:
1484 case ALG_ID_ECDSA_P384:
1485 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1486 return key_import_ecc_public( key, params->buf, params->len );
1487 return key_import_ecc( key, params->buf, params->len );
1489 case ALG_ID_RSA:
1490 case ALG_ID_RSA_SIGN:
1491 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1492 return key_import_rsa_public( key, params->buf, params->len );
1493 return key_import_rsa( key, params->buf, params->len );
1495 case ALG_ID_DSA:
1496 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1498 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1499 return key_import_dsa_capi_public( key, params->buf, params->len );
1500 return key_import_dsa_public( key, params->buf, params->len );
1502 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1503 return key_import_dsa_capi( key, params->buf, params->len );
1504 FIXME( "DSA private key not supported\n" );
1505 return STATUS_NOT_IMPLEMENTED;
1507 default:
1508 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1509 return STATUS_NOT_IMPLEMENTED;
1513 static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
1514 gnutls_datum_t *gnutls_signature )
1516 struct buffer buffer;
1517 DWORD r_len = signature_len / 2;
1518 DWORD s_len = r_len;
1519 BYTE *r = signature;
1520 BYTE *s = signature + r_len;
1522 buffer_init( &buffer );
1523 buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
1524 if (buffer.error)
1526 buffer_free( &buffer );
1527 return STATUS_NO_MEMORY;
1530 gnutls_signature->data = buffer.buffer;
1531 gnutls_signature->size = buffer.pos;
1532 return STATUS_SUCCESS;
1535 static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
1536 gnutls_datum_t *gnutls_signature )
1538 gnutls_signature->data = signature;
1539 gnutls_signature->size = signature_len;
1540 return STATUS_SUCCESS;
1543 static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
1544 gnutls_datum_t *gnutls_signature )
1546 switch (key->alg_id)
1548 case ALG_ID_ECDSA_P256:
1549 case ALG_ID_ECDSA_P384:
1550 case ALG_ID_DSA:
1551 return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
1553 case ALG_ID_RSA:
1554 case ALG_ID_RSA_SIGN:
1555 return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
1557 default:
1558 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1559 return STATUS_NOT_IMPLEMENTED;
1563 static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
1565 if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
1566 if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
1567 if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
1568 if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
1569 if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
1570 if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
1571 return GNUTLS_DIG_UNKNOWN;
1574 static NTSTATUS key_asymmetric_verify( void *args )
1576 const struct key_asymmetric_verify_params *params = args;
1577 struct key *key = params->key;
1578 unsigned flags = params->flags;
1579 gnutls_digest_algorithm_t hash_alg;
1580 gnutls_sign_algorithm_t sign_alg;
1581 gnutls_datum_t gnutls_hash, gnutls_signature;
1582 gnutls_pk_algorithm_t pk_alg;
1583 NTSTATUS status;
1584 int ret;
1586 switch (key->alg_id)
1588 case ALG_ID_ECDSA_P256:
1589 case ALG_ID_ECDSA_P384:
1591 if (flags) FIXME( "flags %#x not supported\n", flags );
1593 /* only the hash size must match, not the actual hash function */
1594 switch (params->hash_len)
1596 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1597 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1598 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1600 default:
1601 FIXME( "hash size %u not yet supported\n", params->hash_len );
1602 return STATUS_INVALID_SIGNATURE;
1604 pk_alg = GNUTLS_PK_ECC;
1605 break;
1607 case ALG_ID_RSA:
1608 case ALG_ID_RSA_SIGN:
1610 BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
1612 if (!(flags & BCRYPT_PAD_PKCS1) || !info) return STATUS_INVALID_PARAMETER;
1613 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1615 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1617 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1618 return STATUS_NOT_SUPPORTED;
1620 pk_alg = GNUTLS_PK_RSA;
1621 break;
1623 case ALG_ID_DSA:
1625 if (flags) FIXME( "flags %#x not supported\n", flags );
1626 if (params->hash_len != 20)
1628 FIXME( "hash size %u not supported\n", params->hash_len );
1629 return STATUS_INVALID_PARAMETER;
1631 hash_alg = GNUTLS_DIG_SHA1;
1632 pk_alg = GNUTLS_PK_DSA;
1633 break;
1635 default:
1636 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1637 return STATUS_NOT_IMPLEMENTED;
1640 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
1642 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
1643 return STATUS_NOT_IMPLEMENTED;
1646 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
1647 return status;
1649 gnutls_hash.data = params->hash;
1650 gnutls_hash.size = params->hash_len;
1651 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
1653 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
1654 return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
1657 static unsigned int get_signature_length( enum alg_id id )
1659 switch (id)
1661 case ALG_ID_ECDSA_P256: return 64;
1662 case ALG_ID_ECDSA_P384: return 96;
1663 case ALG_ID_DSA: return 40;
1664 default:
1665 FIXME( "unhandled algorithm %u\n", id );
1666 return 0;
1670 static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
1671 UCHAR *output, ULONG output_len, ULONG *ret_len )
1673 switch (type)
1675 case ALG_ID_RSA:
1676 case ALG_ID_RSA_SIGN:
1678 *ret_len = signature.size;
1679 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
1680 if (output) memcpy( output, signature.data, signature.size );
1681 return STATUS_SUCCESS;
1683 case ALG_ID_ECDSA_P256:
1684 case ALG_ID_ECDSA_P384:
1685 case ALG_ID_DSA:
1687 int err;
1688 unsigned int sig_len = get_signature_length( type );
1689 gnutls_datum_t r, s; /* format as r||s */
1691 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
1693 pgnutls_perror( err );
1694 return STATUS_INTERNAL_ERROR;
1697 *ret_len = sig_len;
1698 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
1700 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
1702 ERR( "we didn't get a correct signature\n" );
1703 return STATUS_INTERNAL_ERROR;
1706 if (output)
1708 export_gnutls_datum( output, sig_len / 2, &r, 1 );
1709 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
1712 free( r.data ); free( s.data );
1713 return STATUS_SUCCESS;
1715 default:
1716 return STATUS_INTERNAL_ERROR;
1720 static NTSTATUS key_asymmetric_sign( void *args )
1722 const struct key_asymmetric_sign_params *params = args;
1723 struct key *key = params->key;
1724 unsigned flags = params->flags;
1725 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1726 gnutls_datum_t hash, signature;
1727 gnutls_digest_algorithm_t hash_alg;
1728 NTSTATUS status;
1729 int ret;
1731 if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
1733 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1734 switch (params->input_len)
1736 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1737 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1738 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1739 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
1741 default:
1742 FIXME( "hash size %u not yet supported\n", params->input_len );
1743 return STATUS_INVALID_PARAMETER;
1746 if (flags == BCRYPT_PAD_PKCS1 && pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
1748 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
1749 return STATUS_INVALID_PARAMETER;
1752 else if (key->alg_id == ALG_ID_DSA)
1754 if (flags) FIXME( "flags %#x not supported\n", flags );
1755 if (params->input_len != 20)
1757 FIXME( "hash size %u not supported\n", params->input_len );
1758 return STATUS_INVALID_PARAMETER;
1760 hash_alg = GNUTLS_DIG_SHA1;
1762 else if (flags == BCRYPT_PAD_PKCS1)
1764 if (!pad || !pad->pszAlgId)
1766 WARN( "padding info not found\n" );
1767 return STATUS_INVALID_PARAMETER;
1770 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1772 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1773 return STATUS_NOT_SUPPORTED;
1776 else if (!flags)
1778 WARN( "invalid flags %#x\n", flags );
1779 return STATUS_INVALID_PARAMETER;
1781 else
1783 FIXME( "flags %#x not implemented\n", flags );
1784 return STATUS_NOT_IMPLEMENTED;
1787 if (!params->output)
1789 *params->ret_len = key->u.a.bitlen / 8;
1790 return STATUS_SUCCESS;
1792 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1794 hash.data = params->input;
1795 hash.size = params->input_len;
1797 signature.data = NULL;
1798 signature.size = 0;
1800 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, 0, &hash, &signature )))
1802 pgnutls_perror( ret );
1803 return STATUS_INTERNAL_ERROR;
1806 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
1807 free( signature.data );
1808 return status;
1811 static NTSTATUS key_asymmetric_destroy( void *args )
1813 struct key *key = args;
1815 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1816 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1817 return STATUS_SUCCESS;
1820 static NTSTATUS key_asymmetric_duplicate( void *args )
1822 const struct key_asymmetric_duplicate_params *params = args;
1823 struct key *key_orig = params->key_orig;
1824 struct key *key_copy = params->key_copy;
1825 gnutls_privkey_t privkey;
1826 gnutls_pubkey_t pubkey;
1827 int ret;
1829 if (!key_data(key_orig)->a.privkey) return STATUS_SUCCESS;
1831 if ((ret = pgnutls_privkey_init( &privkey )))
1833 pgnutls_perror( ret );
1834 return STATUS_INTERNAL_ERROR;
1837 switch (key_orig->alg_id)
1839 case ALG_ID_RSA:
1840 case ALG_ID_RSA_SIGN:
1842 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1843 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1845 pgnutls_perror( ret );
1846 return STATUS_INTERNAL_ERROR;
1848 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
1849 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1850 free( e1.data ); free( e2.data );
1851 if (ret)
1853 pgnutls_perror( ret );
1854 return STATUS_INTERNAL_ERROR;
1856 break;
1858 case ALG_ID_DSA:
1860 gnutls_datum_t p, q, g, y, x;
1861 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
1863 pgnutls_perror( ret );
1864 return STATUS_INTERNAL_ERROR;
1866 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
1867 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1868 if (ret)
1870 pgnutls_perror( ret );
1871 return STATUS_INTERNAL_ERROR;
1873 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
1874 break;
1876 case ALG_ID_ECDH_P256:
1877 case ALG_ID_ECDSA_P256:
1878 case ALG_ID_ECDSA_P384:
1880 gnutls_ecc_curve_t curve;
1881 gnutls_datum_t x, y, k;
1882 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
1884 pgnutls_perror( ret );
1885 return STATUS_INTERNAL_ERROR;
1887 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
1888 free( x.data ); free( y.data ); free( k.data );
1889 if (ret)
1891 pgnutls_perror( ret );
1892 return STATUS_INTERNAL_ERROR;
1894 break;
1896 default:
1897 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
1898 return STATUS_INTERNAL_ERROR;
1901 if (key_data(key_orig)->a.pubkey)
1903 if ((ret = pgnutls_pubkey_init( &pubkey )))
1905 pgnutls_perror( ret );
1906 pgnutls_privkey_deinit( privkey );
1907 return STATUS_INTERNAL_ERROR;
1909 if ((ret = pgnutls_pubkey_import_privkey( pubkey, key_data(key_orig)->a.privkey, 0, 0 )))
1911 pgnutls_perror( ret );
1912 pgnutls_pubkey_deinit( pubkey );
1913 pgnutls_privkey_deinit( privkey );
1914 return STATUS_INTERNAL_ERROR;
1916 key_data(key_copy)->a.pubkey = pubkey;
1919 key_data(key_copy)->a.privkey = privkey;
1920 return STATUS_SUCCESS;
1923 static NTSTATUS key_asymmetric_decrypt( void *args )
1925 const struct key_asymmetric_decrypt_params *params = args;
1926 gnutls_datum_t e, d = { 0 };
1927 NTSTATUS status = STATUS_SUCCESS;
1928 int ret;
1930 e.data = params->input;
1931 e.size = params->input_len;
1932 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
1934 pgnutls_perror( ret );
1935 return STATUS_INTERNAL_ERROR;
1938 *params->ret_len = d.size;
1939 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
1940 else status = STATUS_BUFFER_TOO_SMALL;
1942 free( d.data );
1943 return status;
1946 static NTSTATUS key_asymmetric_encrypt( void *args )
1948 const struct key_asymmetric_encrypt_params *params = args;
1949 gnutls_datum_t d, e = { 0 };
1950 NTSTATUS status = STATUS_SUCCESS;
1951 int ret;
1953 d.data = params->input;
1954 d.size = params->input_len;
1955 if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
1957 pgnutls_perror( ret );
1958 return STATUS_INTERNAL_ERROR;
1961 *params->ret_len = e.size;
1962 if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
1963 else if (params->output_len == 0) status = STATUS_SUCCESS;
1964 else status = STATUS_BUFFER_TOO_SMALL;
1966 free( e.data );
1967 return status;
1970 const unixlib_entry_t __wine_unix_call_funcs[] =
1972 gnutls_process_attach,
1973 gnutls_process_detach,
1974 key_symmetric_vector_reset,
1975 key_symmetric_set_auth_data,
1976 key_symmetric_encrypt,
1977 key_symmetric_decrypt,
1978 key_symmetric_get_tag,
1979 key_symmetric_destroy,
1980 key_asymmetric_generate,
1981 key_asymmetric_decrypt,
1982 key_asymmetric_encrypt,
1983 key_asymmetric_duplicate,
1984 key_asymmetric_sign,
1985 key_asymmetric_verify,
1986 key_asymmetric_destroy,
1987 key_asymmetric_export,
1988 key_asymmetric_import
1991 #ifdef _WIN64
1993 typedef ULONG PTR32;
1995 struct key_symmetric32
1997 enum mode_id mode;
1998 ULONG block_size;
1999 PTR32 vector;
2000 ULONG vector_len;
2001 PTR32 secret;
2002 ULONG secret_len;
2003 ULONG __cs[6];
2006 struct key_asymmetric32
2008 ULONG bitlen; /* ignored for ECC keys */
2009 ULONG flags;
2010 PTR32 pubkey;
2011 ULONG pubkey_len;
2012 DSSSEED dss_seed;
2015 struct key32
2017 struct object hdr;
2018 enum alg_id alg_id;
2019 UINT64 private[2]; /* private data for backend */
2020 union
2022 struct key_symmetric32 s;
2023 struct key_asymmetric32 a;
2024 } u;
2027 static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
2029 key->hdr = key32->hdr;
2030 key->alg_id = key32->alg_id;
2031 key->private[0] = key32->private[0];
2032 key->private[1] = key32->private[1];
2033 key->u.s.mode = key32->u.s.mode;
2034 key->u.s.block_size = key32->u.s.block_size;
2035 key->u.s.vector = ULongToPtr(key32->u.s.vector);
2036 key->u.s.vector_len = key32->u.s.vector_len;
2037 key->u.s.secret = ULongToPtr(key32->u.s.secret);
2038 key->u.s.secret_len = key32->u.s.secret_len;
2039 return key;
2042 static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2044 key->hdr = key32->hdr;
2045 key->alg_id = key32->alg_id;
2046 key->private[0] = key32->private[0];
2047 key->private[1] = key32->private[1];
2048 key->u.a.bitlen = key32->u.a.bitlen;
2049 key->u.a.flags = key32->u.a.flags;
2050 key->u.a.dss_seed = key32->u.a.dss_seed;
2051 return key;
2054 static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2056 key32->private[0] = key->private[0];
2057 key32->private[1] = key->private[1];
2060 static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2062 key32->private[0] = key->private[0];
2063 key32->private[1] = key->private[1];
2064 key32->u.a.flags = key->u.a.flags;
2065 key32->u.a.dss_seed = key->u.a.dss_seed;
2068 static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
2070 NTSTATUS ret;
2071 struct key key;
2072 struct key32 *key32 = args;
2074 ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
2075 put_symmetric_key32( &key, key32 );
2076 return ret;
2079 static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
2081 struct
2083 PTR32 key;
2084 PTR32 auth_data;
2085 ULONG len;
2086 } const *params32 = args;
2088 NTSTATUS ret;
2089 struct key key;
2090 struct key32 *key32 = ULongToPtr( params32->key );
2091 struct key_symmetric_set_auth_data_params params =
2093 get_symmetric_key( key32, &key ),
2094 ULongToPtr(params32->auth_data),
2095 params32->len
2098 ret = key_symmetric_set_auth_data( &params );
2099 put_symmetric_key32( &key, key32 );
2100 return ret;
2103 static NTSTATUS wow64_key_symmetric_encrypt( void *args )
2105 struct
2107 PTR32 key;
2108 PTR32 input;
2109 ULONG input_len;
2110 PTR32 output;
2111 ULONG output_len;
2112 } const *params32 = args;
2114 NTSTATUS ret;
2115 struct key key;
2116 struct key32 *key32 = ULongToPtr( params32->key );
2117 struct key_symmetric_encrypt_params params =
2119 get_symmetric_key( key32, &key ),
2120 ULongToPtr(params32->input),
2121 params32->input_len,
2122 ULongToPtr(params32->output),
2123 params32->output_len
2126 ret = key_symmetric_encrypt( &params );
2127 put_symmetric_key32( &key, key32 );
2128 return ret;
2131 static NTSTATUS wow64_key_symmetric_decrypt( void *args )
2133 struct
2135 PTR32 key;
2136 PTR32 input;
2137 ULONG input_len;
2138 PTR32 output;
2139 ULONG output_len;
2140 } const *params32 = args;
2142 NTSTATUS ret;
2143 struct key key;
2144 struct key32 *key32 = ULongToPtr( params32->key );
2145 struct key_symmetric_decrypt_params params =
2147 get_symmetric_key( key32, &key ),
2148 ULongToPtr(params32->input),
2149 params32->input_len,
2150 ULongToPtr(params32->output),
2151 params32->output_len
2154 ret = key_symmetric_decrypt( &params );
2155 put_symmetric_key32( &key, key32 );
2156 return ret;
2159 static NTSTATUS wow64_key_symmetric_get_tag( void *args )
2161 struct
2163 PTR32 key;
2164 PTR32 tag;
2165 ULONG len;
2166 } const *params32 = args;
2168 NTSTATUS ret;
2169 struct key key;
2170 struct key32 *key32 = ULongToPtr( params32->key );
2171 struct key_symmetric_get_tag_params params =
2173 get_symmetric_key( key32, &key ),
2174 ULongToPtr(params32->tag),
2175 params32->len
2178 ret = key_symmetric_get_tag( &params );
2179 put_symmetric_key32( &key, key32 );
2180 return ret;
2183 static NTSTATUS wow64_key_symmetric_destroy( void *args )
2185 struct key32 *key32 = args;
2186 struct key key;
2188 return key_symmetric_destroy( get_symmetric_key( key32, &key ));
2191 static NTSTATUS wow64_key_asymmetric_generate( void *args )
2193 struct key32 *key32 = args;
2194 struct key key;
2195 NTSTATUS ret;
2197 ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
2198 put_asymmetric_key32( &key, key32 );
2199 return ret;
2202 static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
2204 struct
2206 PTR32 key;
2207 PTR32 input;
2208 ULONG input_len;
2209 PTR32 output;
2210 ULONG output_len;
2211 PTR32 ret_len;
2212 } const *params32 = args;
2214 NTSTATUS ret;
2215 struct key key;
2216 struct key32 *key32 = ULongToPtr( params32->key );
2217 struct key_asymmetric_decrypt_params params =
2219 get_asymmetric_key( key32, &key ),
2220 ULongToPtr(params32->input),
2221 params32->input_len,
2222 ULongToPtr(params32->output),
2223 params32->output_len,
2224 ULongToPtr(params32->ret_len)
2227 ret = key_asymmetric_decrypt( &params );
2228 put_asymmetric_key32( &key, key32 );
2229 return ret;
2232 static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
2234 struct
2236 PTR32 key;
2237 PTR32 input;
2238 ULONG input_len;
2239 PTR32 output;
2240 ULONG output_len;
2241 PTR32 ret_len;
2242 } const *params32 = args;
2244 NTSTATUS ret;
2245 struct key key;
2246 struct key32 *key32 = ULongToPtr( params32->key );
2247 struct key_asymmetric_encrypt_params params =
2249 get_asymmetric_key( key32, &key ),
2250 ULongToPtr(params32->input),
2251 params32->input_len,
2252 ULongToPtr(params32->output),
2253 params32->output_len,
2254 ULongToPtr(params32->ret_len)
2257 ret = key_asymmetric_encrypt( &params );
2258 put_asymmetric_key32( &key, key32 );
2259 return ret;
2262 static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
2264 struct
2266 PTR32 key_orig;
2267 PTR32 key_copy;
2268 } const *params32 = args;
2270 NTSTATUS ret;
2271 struct key key_orig, key_copy;
2272 struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
2273 struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
2274 struct key_asymmetric_duplicate_params params =
2276 get_asymmetric_key( key_orig32, &key_orig ),
2277 get_asymmetric_key( key_copy32, &key_copy )
2280 ret = key_asymmetric_duplicate( &params );
2281 put_asymmetric_key32( &key_copy, key_copy32 );
2282 return ret;
2285 static NTSTATUS wow64_key_asymmetric_sign( void *args )
2287 struct
2289 PTR32 key;
2290 PTR32 padding;
2291 PTR32 input;
2292 ULONG input_len;
2293 PTR32 output;
2294 ULONG output_len;
2295 PTR32 ret_len;
2296 ULONG flags;
2297 } const *params32 = args;
2299 NTSTATUS ret;
2300 struct key key;
2301 BCRYPT_PKCS1_PADDING_INFO padding;
2302 struct key32 *key32 = ULongToPtr( params32->key );
2303 struct key_asymmetric_sign_params params =
2305 get_asymmetric_key( key32, &key ),
2306 NULL, /* padding */
2307 ULongToPtr(params32->input),
2308 params32->input_len,
2309 ULongToPtr(params32->output),
2310 params32->output_len,
2311 ULongToPtr(params32->ret_len),
2312 params32->flags
2315 if (params32->flags & BCRYPT_PAD_PKCS1)
2317 PTR32 *info = ULongToPtr( params32->padding );
2318 if (!info) return STATUS_INVALID_PARAMETER;
2319 padding.pszAlgId = ULongToPtr( *info );
2320 params.padding = &padding;
2323 ret = key_asymmetric_sign( &params );
2324 put_asymmetric_key32( &key, key32 );
2325 return ret;
2328 static NTSTATUS wow64_key_asymmetric_verify( void *args )
2330 struct
2332 PTR32 key;
2333 PTR32 padding;
2334 PTR32 hash;
2335 ULONG hash_len;
2336 PTR32 signature;
2337 ULONG signature_len;
2338 ULONG flags;
2339 } const *params32 = args;
2341 NTSTATUS ret;
2342 struct key key;
2343 BCRYPT_PKCS1_PADDING_INFO padding;
2344 struct key32 *key32 = ULongToPtr( params32->key );
2345 struct key_asymmetric_verify_params params =
2347 get_asymmetric_key( key32, &key ),
2348 NULL, /* padding */
2349 ULongToPtr(params32->hash),
2350 params32->hash_len,
2351 ULongToPtr(params32->signature),
2352 params32->signature_len,
2353 params32->flags
2356 if (params32->flags & BCRYPT_PAD_PKCS1)
2358 PTR32 *info = ULongToPtr( params32->padding );
2359 if (!info) return STATUS_INVALID_PARAMETER;
2360 padding.pszAlgId = ULongToPtr( *info );
2361 params.padding = &padding;
2364 ret = key_asymmetric_verify( &params );
2365 put_asymmetric_key32( &key, key32 );
2366 return ret;
2369 static NTSTATUS wow64_key_asymmetric_destroy( void *args )
2371 struct key32 *key32 = args;
2372 struct key key;
2374 return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
2377 static NTSTATUS wow64_key_asymmetric_export( void *args )
2379 struct
2381 PTR32 key;
2382 ULONG flags;
2383 PTR32 buf;
2384 ULONG len;
2385 PTR32 ret_len;
2386 } const *params32 = args;
2388 NTSTATUS ret;
2389 struct key key;
2390 struct key32 *key32 = ULongToPtr( params32->key );
2391 struct key_asymmetric_export_params params =
2393 get_asymmetric_key( key32, &key ),
2394 params32->flags,
2395 ULongToPtr(params32->buf),
2396 params32->len,
2397 ULongToPtr(params32->ret_len),
2400 ret = key_asymmetric_export( &params );
2401 put_asymmetric_key32( &key, key32 );
2402 return ret;
2405 static NTSTATUS wow64_key_asymmetric_import( void *args )
2407 struct
2409 PTR32 key;
2410 ULONG flags;
2411 PTR32 buf;
2412 ULONG len;
2413 } const *params32 = args;
2415 NTSTATUS ret;
2416 struct key key;
2417 struct key32 *key32 = ULongToPtr( params32->key );
2418 struct key_asymmetric_import_params params =
2420 get_asymmetric_key( key32, &key ),
2421 params32->flags,
2422 ULongToPtr(params32->buf),
2423 params32->len
2426 ret = key_asymmetric_import( &params );
2427 put_asymmetric_key32( &key, key32 );
2428 return ret;
2431 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
2433 gnutls_process_attach,
2434 gnutls_process_detach,
2435 wow64_key_symmetric_vector_reset,
2436 wow64_key_symmetric_set_auth_data,
2437 wow64_key_symmetric_encrypt,
2438 wow64_key_symmetric_decrypt,
2439 wow64_key_symmetric_get_tag,
2440 wow64_key_symmetric_destroy,
2441 wow64_key_asymmetric_generate,
2442 wow64_key_asymmetric_decrypt,
2443 wow64_key_asymmetric_encrypt,
2444 wow64_key_asymmetric_duplicate,
2445 wow64_key_asymmetric_sign,
2446 wow64_key_asymmetric_verify,
2447 wow64_key_asymmetric_destroy,
2448 wow64_key_asymmetric_export,
2449 wow64_key_asymmetric_import
2452 #endif /* _WIN64 */
2454 #endif /* HAVE_GNUTLS_CIPHER_INIT */