d3d11: Remove null dxgi object checks.
[wine.git] / dlls / bcrypt / gnutls.c
blobb38bf4ba8ffbbeedfe3a67cd5135addbc407af6a
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 *);
101 /* Not present in gnutls version < 2.11.0 */
102 static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
104 /* Not present in gnutls version < 2.12.0 */
105 static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
106 const gnutls_datum_t *, const gnutls_datum_t *);
107 static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
109 /* Not present in gnutls version < 3.3.0 */
110 static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
111 gnutls_datum_t *);
112 static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
113 static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
114 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
115 static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
116 gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
117 gnutls_datum_t *);
118 static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
119 gnutls_datum_t *, gnutls_datum_t *);
120 static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int);
121 static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
122 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
123 const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
124 static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *, gnutls_datum_t *);
126 /* Not present in gnutls version < 3.6.0 */
127 static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
129 static void *libgnutls_handle;
130 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
131 MAKE_FUNCPTR(gnutls_cipher_decrypt2);
132 MAKE_FUNCPTR(gnutls_cipher_deinit);
133 MAKE_FUNCPTR(gnutls_cipher_encrypt2);
134 MAKE_FUNCPTR(gnutls_cipher_init);
135 MAKE_FUNCPTR(gnutls_global_deinit);
136 MAKE_FUNCPTR(gnutls_global_init);
137 MAKE_FUNCPTR(gnutls_global_set_log_function);
138 MAKE_FUNCPTR(gnutls_global_set_log_level);
139 MAKE_FUNCPTR(gnutls_perror);
140 MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
141 MAKE_FUNCPTR(gnutls_privkey_deinit);
142 MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
143 MAKE_FUNCPTR(gnutls_privkey_init);
144 MAKE_FUNCPTR(gnutls_privkey_sign_hash);
145 MAKE_FUNCPTR(gnutls_pubkey_deinit);
146 MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
147 MAKE_FUNCPTR(gnutls_pubkey_init);
148 #undef MAKE_FUNCPTR
150 static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
152 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
155 static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
157 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
160 static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
161 const gnutls_datum_t *x, const gnutls_datum_t *y)
163 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
166 static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
167 gnutls_datum_t *x, gnutls_datum_t *y)
169 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
172 static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
173 gnutls_datum_t *g, gnutls_datum_t *y)
175 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
178 static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
180 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
183 static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
184 gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
185 gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
187 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
190 static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
191 gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
193 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
196 static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
197 const gnutls_datum_t *x, const gnutls_datum_t *y,
198 const gnutls_datum_t *k)
200 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
203 static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
204 gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
206 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
209 static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
211 return GNUTLS_SIGN_UNKNOWN;
214 static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
215 unsigned int flags, const gnutls_datum_t *hash,
216 const gnutls_datum_t *signature)
218 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
221 static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
223 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
226 static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
227 const gnutls_datum_t *g, const gnutls_datum_t *y)
229 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
232 static int compat_gnutls_privkey_generate(gnutls_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits,
233 unsigned int flags)
235 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
238 static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
240 return GNUTLS_E_INTERNAL_ERROR;
243 static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
244 const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
245 const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
247 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
250 static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
251 gnutls_datum_t *plain_text)
253 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
256 static void gnutls_log( int level, const char *msg )
258 TRACE( "<%d> %s", level, msg );
261 static NTSTATUS gnutls_process_attach( void *args )
263 const char *env_str;
264 int ret;
266 if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
268 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
270 else
272 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
273 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
276 if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
278 ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
279 return STATUS_DLL_NOT_FOUND;
282 #define LOAD_FUNCPTR(f) \
283 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
285 ERR( "failed to load %s\n", #f ); \
286 goto fail; \
289 LOAD_FUNCPTR(gnutls_cipher_decrypt2)
290 LOAD_FUNCPTR(gnutls_cipher_deinit)
291 LOAD_FUNCPTR(gnutls_cipher_encrypt2)
292 LOAD_FUNCPTR(gnutls_cipher_init)
293 LOAD_FUNCPTR(gnutls_global_deinit)
294 LOAD_FUNCPTR(gnutls_global_init)
295 LOAD_FUNCPTR(gnutls_global_set_log_function)
296 LOAD_FUNCPTR(gnutls_global_set_log_level)
297 LOAD_FUNCPTR(gnutls_perror)
298 LOAD_FUNCPTR(gnutls_privkey_deinit);
299 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
300 LOAD_FUNCPTR(gnutls_privkey_init);
301 LOAD_FUNCPTR(gnutls_privkey_sign_hash);
302 LOAD_FUNCPTR(gnutls_pubkey_deinit);
303 LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
304 LOAD_FUNCPTR(gnutls_pubkey_init);
305 #undef LOAD_FUNCPTR
307 #define LOAD_FUNCPTR_OPT(f) \
308 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
310 WARN( "failed to load %s\n", #f ); \
311 p##f = compat_##f; \
314 LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
315 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
316 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
317 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
318 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
319 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
320 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
321 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
322 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
323 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
324 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
325 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
326 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
327 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
328 LOAD_FUNCPTR_OPT(gnutls_privkey_generate)
329 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
330 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
331 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
332 #undef LOAD_FUNCPTR_OPT
334 if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
336 pgnutls_perror( ret );
337 goto fail;
340 if (TRACE_ON( bcrypt ))
342 pgnutls_global_set_log_level( 4 );
343 pgnutls_global_set_log_function( gnutls_log );
346 return STATUS_SUCCESS;
348 fail:
349 dlclose( libgnutls_handle );
350 libgnutls_handle = NULL;
351 return STATUS_DLL_NOT_FOUND;
354 static NTSTATUS gnutls_process_detach( void *args )
356 if (libgnutls_handle)
358 pgnutls_global_deinit();
359 dlclose( libgnutls_handle );
360 libgnutls_handle = NULL;
362 return STATUS_SUCCESS;
365 struct buffer
367 BYTE *buffer;
368 DWORD length;
369 DWORD pos;
370 BOOL error;
373 static void buffer_init( struct buffer *buffer )
375 buffer->buffer = NULL;
376 buffer->length = 0;
377 buffer->pos = 0;
378 buffer->error = FALSE;
381 static void buffer_free( struct buffer *buffer )
383 free( buffer->buffer );
386 static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
388 if (!len) return;
390 if (buffer->pos + len > buffer->length)
392 DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
393 BYTE *new_buffer;
395 if (!(new_buffer = realloc( buffer->buffer, new_length )))
397 ERR( "out of memory\n" );
398 buffer->error = TRUE;
399 return;
402 buffer->buffer = new_buffer;
403 buffer->length = new_length;
406 memcpy( &buffer->buffer[buffer->pos], data, len );
407 buffer->pos += len;
410 static void buffer_append_byte( struct buffer *buffer, BYTE value )
412 buffer_append( buffer, &value, sizeof(value) );
415 static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
417 DWORD num_bytes;
419 if (length < 128)
421 buffer_append_byte( buffer, length );
422 return;
425 if (length <= 0xff) num_bytes = 1;
426 else if (length <= 0xffff) num_bytes = 2;
427 else if (length <= 0xffffff) num_bytes = 3;
428 else num_bytes = 4;
430 buffer_append_byte( buffer, 0x80 | num_bytes );
431 while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
434 static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
436 DWORD leading_zero = (*data & 0x80) != 0;
438 buffer_append_byte( buffer, 0x02 ); /* tag */
439 buffer_append_asn1_length( buffer, len + leading_zero );
440 if (leading_zero) buffer_append_byte( buffer, 0 );
441 buffer_append( buffer, data, len );
444 static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
446 if (content->error)
448 buffer->error = TRUE;
449 return;
452 buffer_append_byte( buffer, 0x30 ); /* tag */
453 buffer_append_asn1_length( buffer, content->pos );
454 buffer_append( buffer, content->buffer, content->pos );
457 static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
459 struct buffer value;
461 buffer_init( &value );
462 buffer_append_asn1_integer( &value, r, r_len );
463 buffer_append_asn1_integer( &value, s, s_len );
464 buffer_append_asn1_sequence( buffer, &value );
465 buffer_free( &value );
468 static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
470 switch (key->alg_id)
472 case ALG_ID_3DES:
473 WARN( "handle block size\n" );
474 switch (key->u.s.mode)
476 case MODE_ID_CBC:
477 return GNUTLS_CIPHER_3DES_CBC;
478 default:
479 break;
481 FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
482 return GNUTLS_CIPHER_UNKNOWN;
484 case ALG_ID_AES:
485 WARN( "handle block size\n" );
486 switch (key->u.s.mode)
488 case MODE_ID_GCM:
489 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
490 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
491 break;
492 case MODE_ID_ECB: /* can be emulated with CBC + empty IV */
493 case MODE_ID_CBC:
494 if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
495 if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
496 if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
497 break;
498 default:
499 break;
501 FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
502 return GNUTLS_CIPHER_UNKNOWN;
504 default:
505 FIXME( "algorithm %u not supported\n", key->alg_id );
506 return GNUTLS_CIPHER_UNKNOWN;
510 static NTSTATUS key_symmetric_vector_reset( void *args )
512 struct key *key = args;
514 if (!key_data(key)->cipher) return STATUS_SUCCESS;
515 TRACE( "invalidating cipher handle\n" );
516 pgnutls_cipher_deinit( key_data(key)->cipher );
517 key_data(key)->cipher = NULL;
518 return STATUS_SUCCESS;
521 static NTSTATUS init_cipher_handle( struct key *key )
523 gnutls_cipher_algorithm_t cipher;
524 gnutls_datum_t secret, vector;
525 int ret;
527 if (key_data(key)->cipher) return STATUS_SUCCESS;
528 if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
530 secret.data = key->u.s.secret;
531 secret.size = key->u.s.secret_len;
533 vector.data = key->u.s.vector;
534 vector.size = key->u.s.vector_len;
536 if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
538 pgnutls_perror( ret );
539 return STATUS_INTERNAL_ERROR;
542 return STATUS_SUCCESS;
545 static NTSTATUS key_symmetric_set_auth_data( void *args )
547 const struct key_symmetric_set_auth_data_params *params = args;
548 NTSTATUS status;
549 int ret;
551 if (!params->auth_data) return STATUS_SUCCESS;
552 if ((status = init_cipher_handle( params->key ))) return status;
554 if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
556 pgnutls_perror( ret );
557 return STATUS_INTERNAL_ERROR;
559 return STATUS_SUCCESS;
562 static NTSTATUS key_symmetric_encrypt( void *args )
564 const struct key_symmetric_encrypt_params *params = args;
565 NTSTATUS status;
566 int ret;
568 if ((status = init_cipher_handle( params->key ))) return status;
570 if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
571 params->output, params->output_len )))
573 pgnutls_perror( ret );
574 return STATUS_INTERNAL_ERROR;
576 return STATUS_SUCCESS;
579 static NTSTATUS key_symmetric_decrypt( void *args )
581 const struct key_symmetric_decrypt_params *params = args;
582 NTSTATUS status;
583 int ret;
585 if ((status = init_cipher_handle( params->key ))) return status;
587 if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
588 params->output, params->output_len )))
590 pgnutls_perror( ret );
591 return STATUS_INTERNAL_ERROR;
593 return STATUS_SUCCESS;
596 static NTSTATUS key_symmetric_get_tag( void *args )
598 const struct key_symmetric_get_tag_params *params = args;
599 NTSTATUS status;
600 int ret;
602 if ((status = init_cipher_handle( params->key ))) return status;
604 if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
606 pgnutls_perror( ret );
607 return STATUS_INTERNAL_ERROR;
609 return STATUS_SUCCESS;
612 static NTSTATUS key_symmetric_destroy( void *args )
614 struct key *key = args;
616 if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
617 return STATUS_SUCCESS;
620 static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
622 ULONG size = d->size;
623 UCHAR *src = d->data;
624 ULONG offset = 0;
626 assert( size <= buflen + 1 );
627 if (size == buflen + 1)
629 assert( !src[0] );
630 src++;
631 size--;
633 if (zero_pad)
635 offset = buflen - size;
636 if (buffer) memset( buffer, 0, offset );
637 size = buflen;
640 if (buffer) memcpy( buffer + offset, src, size );
641 return size;
644 #define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p )
645 static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
647 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
648 gnutls_datum_t m, e;
649 UCHAR *dst;
650 int ret;
652 if (key_data(key)->a.pubkey)
653 ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
654 else if (key_data(key)->a.privkey)
655 ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL );
656 else
657 return STATUS_INVALID_PARAMETER;
659 if (ret)
661 pgnutls_perror( ret );
662 return STATUS_INTERNAL_ERROR;
665 *ret_len = sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1);
666 if (len >= *ret_len && buf)
668 dst = (UCHAR *)(rsa_blob + 1);
669 rsa_blob->cbPublicExp = export_gnutls_datum( dst, key->u.a.bitlen / 8, &e, 0 );
671 dst += rsa_blob->cbPublicExp;
672 rsa_blob->cbModulus = export_gnutls_datum( dst, key->u.a.bitlen / 8, &m, 1 );
674 rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
675 rsa_blob->BitLength = key->u.a.bitlen;
676 rsa_blob->cbPrime1 = 0;
677 rsa_blob->cbPrime2 = 0;
680 free( e.data ); free( m.data );
681 return STATUS_SUCCESS;
684 static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
686 BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
687 gnutls_ecc_curve_t curve;
688 gnutls_datum_t x, y;
689 DWORD magic, size;
690 UCHAR *dst;
691 int ret;
693 switch (key->alg_id)
695 case ALG_ID_ECDH_P256:
696 magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
697 size = 32;
698 break;
699 case ALG_ID_ECDSA_P256:
700 magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
701 size = 32;
702 break;
703 default:
704 FIXME( "algorithm %u not supported\n", key->alg_id );
705 return STATUS_NOT_IMPLEMENTED;
708 if (key_data(key)->a.pubkey)
709 ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
710 else if (key_data(key)->a.privkey)
711 ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, NULL );
712 else
713 return STATUS_INVALID_PARAMETER;
715 if (ret)
717 pgnutls_perror( ret );
718 return STATUS_INTERNAL_ERROR;
721 if (curve != GNUTLS_ECC_CURVE_SECP256R1)
723 FIXME( "curve %u not supported\n", curve );
724 free( x.data ); free( y.data );
725 return STATUS_NOT_IMPLEMENTED;
728 *ret_len = sizeof(*ecc_blob) + size * 2;
729 if (len >= *ret_len && buf)
731 ecc_blob->dwMagic = magic;
732 ecc_blob->cbKey = size;
734 dst = (UCHAR *)(ecc_blob + 1);
735 export_gnutls_datum( dst, size, &x, 1 );
737 dst += size;
738 export_gnutls_datum( dst, size, &y, 1 );
741 free( x.data ); free( y.data );
742 return STATUS_SUCCESS;
745 static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
747 BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
748 gnutls_datum_t p, q, g, y;
749 UCHAR *dst;
750 int ret;
752 if (key_data(key)->a.pubkey)
753 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
754 else if (key_data(key)->a.privkey)
755 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
756 else
757 return STATUS_INVALID_PARAMETER;
759 if (ret)
761 pgnutls_perror( ret );
762 return STATUS_INTERNAL_ERROR;
765 if (key->u.a.bitlen > 1024)
767 FIXME( "bitlen > 1024 not supported\n" );
768 return STATUS_NOT_IMPLEMENTED;
771 *ret_len = sizeof(*dsa_blob) + key->u.a.bitlen / 8 * 3;
772 if (len >= *ret_len && buf)
774 dst = (UCHAR *)(dsa_blob + 1);
775 export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
777 dst += key->u.a.bitlen / 8;
778 export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
780 dst += key->u.a.bitlen / 8;
781 export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
783 dst = dsa_blob->q;
784 export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
786 dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
787 dsa_blob->cbKey = key->u.a.bitlen / 8;
788 memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
789 memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
792 free( p.data ); free( q.data ); free( g.data ); free( y.data );
793 return STATUS_SUCCESS;
796 static void reverse_bytes( UCHAR *buf, ULONG len )
798 unsigned int i;
799 UCHAR tmp;
801 for (i = 0; i < len / 2; ++i)
803 tmp = buf[i];
804 buf[i] = buf[len - i - 1];
805 buf[len - i - 1] = tmp;
809 #define Q_SIZE 20
810 static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
812 BLOBHEADER *hdr = (BLOBHEADER *)buf;
813 DSSPUBKEY *dsskey;
814 gnutls_datum_t p, q, g, y;
815 UCHAR *dst;
816 int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed);
818 if (key->u.a.bitlen > 1024)
820 FIXME( "bitlen > 1024 not supported\n" );
821 return STATUS_NOT_IMPLEMENTED;
824 if (key_data(key)->a.pubkey)
825 ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
826 else if (key_data(key)->a.privkey)
827 ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
828 else
829 return STATUS_INVALID_PARAMETER;
831 if (ret)
833 pgnutls_perror( ret );
834 return STATUS_INTERNAL_ERROR;
837 *ret_len = size + key->u.a.bitlen / 8 * 3 + Q_SIZE;
838 if (len >= *ret_len && buf)
840 hdr->bType = PUBLICKEYBLOB;
841 hdr->bVersion = 2;
842 hdr->reserved = 0;
843 hdr->aiKeyAlg = CALG_DSS_SIGN;
845 dsskey = (DSSPUBKEY *)(hdr + 1);
846 dsskey->magic = MAGIC_DSS1;
847 dsskey->bitlen = key->u.a.bitlen;
849 dst = (UCHAR *)(dsskey + 1);
850 export_gnutls_datum( dst, key->u.a.bitlen / 8, &p, 1 );
851 reverse_bytes( dst, key->u.a.bitlen / 8 );
852 dst += key->u.a.bitlen / 8;
854 export_gnutls_datum( dst, Q_SIZE, &q, 1 );
855 reverse_bytes( dst, Q_SIZE );
856 dst += Q_SIZE;
858 export_gnutls_datum( dst, key->u.a.bitlen / 8, &g, 1 );
859 reverse_bytes( dst, key->u.a.bitlen / 8 );
860 dst += key->u.a.bitlen / 8;
862 export_gnutls_datum( dst, key->u.a.bitlen / 8, &y, 1 );
863 reverse_bytes( dst, key->u.a.bitlen / 8 );
864 dst += key->u.a.bitlen / 8;
866 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
869 free( p.data ); free( q.data ); free( g.data ); free( y.data );
870 return STATUS_SUCCESS;
873 static NTSTATUS key_asymmetric_generate( void *args )
875 struct key *key = args;
876 gnutls_pk_algorithm_t pk_alg;
877 gnutls_privkey_t privkey;
878 gnutls_pubkey_t pubkey;
879 unsigned int bitlen;
880 int ret;
882 if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
883 if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
885 switch (key->alg_id)
887 case ALG_ID_RSA:
888 case ALG_ID_RSA_SIGN:
889 pk_alg = GNUTLS_PK_RSA;
890 bitlen = key->u.a.bitlen;
891 break;
893 case ALG_ID_DSA:
894 pk_alg = GNUTLS_PK_DSA;
895 bitlen = key->u.a.bitlen;
896 break;
898 case ALG_ID_ECDH_P256:
899 case ALG_ID_ECDSA_P256:
900 pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
901 bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
902 break;
904 default:
905 FIXME( "algorithm %u not supported\n", key->alg_id );
906 return STATUS_NOT_SUPPORTED;
909 if ((ret = pgnutls_privkey_init( &privkey )))
911 pgnutls_perror( ret );
912 return STATUS_INTERNAL_ERROR;
914 if ((ret = pgnutls_pubkey_init( &pubkey )))
916 pgnutls_perror( ret );
917 pgnutls_privkey_deinit( privkey );
918 return STATUS_INTERNAL_ERROR;
921 if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
923 pgnutls_perror( ret );
924 pgnutls_privkey_deinit( privkey );
925 pgnutls_pubkey_deinit( pubkey );
926 return STATUS_INTERNAL_ERROR;
928 if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
930 pgnutls_perror( ret );
931 pgnutls_privkey_deinit( privkey );
932 pgnutls_pubkey_deinit( pubkey );
933 return STATUS_INTERNAL_ERROR;
936 key_data(key)->a.privkey = privkey;
937 key_data(key)->a.pubkey = pubkey;
938 return STATUS_SUCCESS;
941 static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
943 BCRYPT_ECCKEY_BLOB *ecc_blob;
944 gnutls_ecc_curve_t curve;
945 gnutls_datum_t x, y, d;
946 DWORD magic, size;
947 UCHAR *dst;
948 int ret;
950 switch (key->alg_id)
952 case ALG_ID_ECDH_P256:
953 magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
954 size = 32;
955 break;
956 case ALG_ID_ECDSA_P256:
957 magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
958 size = 32;
959 break;
961 default:
962 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
963 return STATUS_NOT_IMPLEMENTED;
966 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
968 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
970 pgnutls_perror( ret );
971 return STATUS_INTERNAL_ERROR;
974 if (curve != GNUTLS_ECC_CURVE_SECP256R1)
976 FIXME( "curve %u not supported\n", curve );
977 free( x.data ); free( y.data ); free( d.data );
978 return STATUS_NOT_IMPLEMENTED;
981 *ret_len = sizeof(*ecc_blob) + size * 3;
982 if (len >= *ret_len && buf)
984 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
985 ecc_blob->dwMagic = magic;
986 ecc_blob->cbKey = size;
988 dst = (UCHAR *)(ecc_blob + 1);
989 export_gnutls_datum( dst, size, &x, 1 );
990 dst += size;
992 export_gnutls_datum( dst, size, &y, 1 );
993 dst += size;
995 export_gnutls_datum( dst, size, &d, 1 );
998 free( x.data ); free( y.data ); free( d.data );
999 return STATUS_SUCCESS;
1002 static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1004 BCRYPT_ECCKEY_BLOB *ecc_blob;
1005 gnutls_ecc_curve_t curve;
1006 gnutls_privkey_t handle;
1007 gnutls_datum_t x, y, k;
1008 int ret;
1010 switch (key->alg_id)
1012 case ALG_ID_ECDH_P256:
1013 case ALG_ID_ECDSA_P256:
1014 curve = GNUTLS_ECC_CURVE_SECP256R1;
1015 break;
1017 default:
1018 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1019 return STATUS_NOT_IMPLEMENTED;
1022 if ((ret = pgnutls_privkey_init( &handle )))
1024 pgnutls_perror( ret );
1025 return STATUS_INTERNAL_ERROR;
1028 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1029 x.data = (unsigned char *)(ecc_blob + 1);
1030 x.size = ecc_blob->cbKey;
1031 y.data = x.data + ecc_blob->cbKey;
1032 y.size = ecc_blob->cbKey;
1033 k.data = y.data + ecc_blob->cbKey;
1034 k.size = ecc_blob->cbKey;
1036 if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1038 pgnutls_perror( ret );
1039 pgnutls_privkey_deinit( handle );
1040 return STATUS_INTERNAL_ERROR;
1043 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1044 key_data(key)->a.privkey = handle;
1045 return STATUS_SUCCESS;
1048 static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1050 BCRYPT_RSAKEY_BLOB *rsa_blob;
1051 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1052 ULONG bitlen = key->u.a.bitlen;
1053 BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1054 UCHAR *dst;
1055 int ret;
1057 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1059 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1061 pgnutls_perror( ret );
1062 return STATUS_INTERNAL_ERROR;
1065 *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);
1066 if (full) *ret_len += EXPORT_SIZE(e1,16,1) + EXPORT_SIZE(e2,16,1) + EXPORT_SIZE(u,16,1) + EXPORT_SIZE(d,8,1);
1068 if (len >= *ret_len && buf)
1070 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1071 rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1072 rsa_blob->BitLength = bitlen;
1074 dst = (UCHAR *)(rsa_blob + 1);
1075 rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 );
1077 dst += rsa_blob->cbPublicExp;
1078 rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 );
1080 dst += rsa_blob->cbModulus;
1081 rsa_blob->cbPrime1 = export_gnutls_datum( dst, bitlen / 16, &p, 1 );
1083 dst += rsa_blob->cbPrime1;
1084 rsa_blob->cbPrime2 = export_gnutls_datum( dst, bitlen / 16, &q, 1 );
1086 if (full)
1088 dst += rsa_blob->cbPrime2;
1089 export_gnutls_datum( dst, bitlen / 16, &e1, 1 );
1091 dst += rsa_blob->cbPrime1;
1092 export_gnutls_datum( dst, bitlen / 16, &e2, 1 );
1094 dst += rsa_blob->cbPrime2;
1095 export_gnutls_datum( dst, bitlen / 16, &u, 1 );
1097 dst += rsa_blob->cbPrime1;
1098 export_gnutls_datum( dst, bitlen / 8, &d, 1 );
1102 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1103 free( e1.data ); free( e2.data );
1104 return STATUS_SUCCESS;
1107 static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1109 BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1110 gnutls_datum_t m, e, p, q;
1111 gnutls_privkey_t handle;
1112 int ret;
1114 if ((ret = pgnutls_privkey_init( &handle )))
1116 pgnutls_perror( ret );
1117 return STATUS_INTERNAL_ERROR;
1120 e.data = (unsigned char *)(rsa_blob + 1);
1121 e.size = rsa_blob->cbPublicExp;
1122 m.data = e.data + e.size;
1123 m.size = rsa_blob->cbModulus;
1124 p.data = m.data + m.size;
1125 p.size = rsa_blob->cbPrime1;
1126 q.data = p.data + p.size;
1127 q.size = rsa_blob->cbPrime2;
1129 if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1131 pgnutls_perror( ret );
1132 pgnutls_privkey_deinit( handle );
1133 return STATUS_INTERNAL_ERROR;
1136 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1137 key_data(key)->a.privkey = handle;
1138 return STATUS_SUCCESS;
1141 static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1143 BLOBHEADER *hdr;
1144 DSSPUBKEY *pubkey;
1145 gnutls_datum_t p, q, g, y, x;
1146 UCHAR *dst;
1147 int ret, size;
1149 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1151 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1153 pgnutls_perror( ret );
1154 return STATUS_INTERNAL_ERROR;
1157 if (q.size > 21 || x.size > 21)
1159 ERR( "can't export key in this format\n" );
1160 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1161 return STATUS_NOT_SUPPORTED;
1164 size = key->u.a.bitlen / 8;
1165 *ret_len = sizeof(*hdr) + sizeof(*pubkey) + size * 2 + 40 + sizeof(key->u.a.dss_seed);
1166 if (len >= *ret_len && buf)
1168 hdr = (BLOBHEADER *)buf;
1169 hdr->bType = PRIVATEKEYBLOB;
1170 hdr->bVersion = 2;
1171 hdr->reserved = 0;
1172 hdr->aiKeyAlg = CALG_DSS_SIGN;
1174 pubkey = (DSSPUBKEY *)(hdr + 1);
1175 pubkey->magic = MAGIC_DSS2;
1176 pubkey->bitlen = key->u.a.bitlen;
1178 dst = (UCHAR *)(pubkey + 1);
1179 export_gnutls_datum( dst, size, &p, 1 );
1180 reverse_bytes( dst, size );
1181 dst += size;
1183 export_gnutls_datum( dst, 20, &q, 1 );
1184 reverse_bytes( dst, 20 );
1185 dst += 20;
1187 export_gnutls_datum( dst, size, &g, 1 );
1188 reverse_bytes( dst, size );
1189 dst += size;
1191 export_gnutls_datum( dst, 20, &x, 1 );
1192 reverse_bytes( dst, 20 );
1193 dst += 20;
1195 memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1198 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1199 return STATUS_SUCCESS;
1202 static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1204 BLOBHEADER *hdr = (BLOBHEADER *)buf;
1205 DSSPUBKEY *pubkey;
1206 gnutls_privkey_t handle;
1207 gnutls_datum_t p, q, g, x;
1208 unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1209 int i, ret, size;
1211 if ((ret = pgnutls_privkey_init( &handle )))
1213 pgnutls_perror( ret );
1214 return STATUS_INTERNAL_ERROR;
1217 pubkey = (DSSPUBKEY *)(hdr + 1);
1218 if ((size = pubkey->bitlen / 8) > sizeof(p_data))
1220 FIXME( "size %u not supported\n", size );
1221 pgnutls_privkey_deinit( handle );
1222 return STATUS_NOT_SUPPORTED;
1224 data = (unsigned char *)(pubkey + 1);
1226 p.data = p_data;
1227 p.size = size;
1228 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1229 data += p.size;
1231 q.data = q_data;
1232 q.size = sizeof(q_data);
1233 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1234 data += q.size;
1236 g.data = g_data;
1237 g.size = size;
1238 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1239 data += g.size;
1241 x.data = x_data;
1242 x.size = sizeof(x_data);
1243 for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1244 data += x.size;
1246 if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1248 pgnutls_perror( ret );
1249 pgnutls_privkey_deinit( handle );
1250 return STATUS_INTERNAL_ERROR;
1253 memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1255 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1256 key_data(key)->a.privkey = handle;
1257 return STATUS_SUCCESS;
1260 static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1262 BCRYPT_ECCKEY_BLOB *ecc_blob;
1263 gnutls_ecc_curve_t curve;
1264 gnutls_datum_t x, y;
1265 gnutls_pubkey_t handle;
1266 int ret;
1268 switch (key->alg_id)
1270 case ALG_ID_ECDH_P256:
1271 case ALG_ID_ECDSA_P256: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1272 case ALG_ID_ECDSA_P384: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1274 default:
1275 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1276 return STATUS_NOT_IMPLEMENTED;
1279 if ((ret = pgnutls_pubkey_init( &handle )))
1281 pgnutls_perror( ret );
1282 return STATUS_INTERNAL_ERROR;
1285 ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1286 x.data = buf + sizeof(*ecc_blob);
1287 x.size = ecc_blob->cbKey;
1288 y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1289 y.size = ecc_blob->cbKey;
1291 if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1293 pgnutls_perror( ret );
1294 pgnutls_pubkey_deinit( handle );
1295 return STATUS_INTERNAL_ERROR;
1298 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1299 key_data(key)->a.pubkey = handle;
1300 return STATUS_SUCCESS;
1303 static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1305 BCRYPT_RSAKEY_BLOB *rsa_blob;
1306 gnutls_pubkey_t handle;
1307 gnutls_datum_t m, e;
1308 int ret;
1310 if ((ret = pgnutls_pubkey_init( &handle )))
1312 pgnutls_perror( ret );
1313 return STATUS_INTERNAL_ERROR;
1316 rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1317 e.data = buf + sizeof(*rsa_blob);
1318 e.size = rsa_blob->cbPublicExp;
1319 m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1320 m.size = rsa_blob->cbModulus;
1322 if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1324 pgnutls_perror( ret );
1325 pgnutls_pubkey_deinit( handle );
1326 return STATUS_INTERNAL_ERROR;
1329 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1330 key_data(key)->a.pubkey = handle;
1331 return STATUS_SUCCESS;
1334 static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1336 BCRYPT_DSA_KEY_BLOB *dsa_blob;
1337 gnutls_datum_t p, q, g, y;
1338 gnutls_pubkey_t handle;
1339 int ret;
1341 if ((ret = pgnutls_pubkey_init( &handle )))
1343 pgnutls_perror( ret );
1344 return STATUS_INTERNAL_ERROR;
1347 dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1348 p.data = buf + sizeof(*dsa_blob);
1349 p.size = dsa_blob->cbKey;
1350 q.data = dsa_blob->q;
1351 q.size = sizeof(dsa_blob->q);
1352 g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1353 g.size = dsa_blob->cbKey;
1354 y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1355 y.size = dsa_blob->cbKey;
1357 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1359 pgnutls_perror( ret );
1360 pgnutls_pubkey_deinit( handle );
1361 return STATUS_INTERNAL_ERROR;
1364 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1365 key_data(key)->a.pubkey = handle;
1366 return STATUS_SUCCESS;
1369 static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1371 BLOBHEADER *hdr;
1372 DSSPUBKEY *pubkey;
1373 gnutls_datum_t p, q, g, y;
1374 gnutls_pubkey_t handle;
1375 unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1376 int i, ret, size;
1378 if ((ret = pgnutls_pubkey_init( &handle )))
1380 pgnutls_perror( ret );
1381 return STATUS_INTERNAL_ERROR;
1384 hdr = (BLOBHEADER *)buf;
1385 pubkey = (DSSPUBKEY *)(hdr + 1);
1386 size = pubkey->bitlen / 8;
1387 data = (unsigned char *)(pubkey + 1);
1389 p.data = p_data;
1390 p.size = size;
1391 for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1392 data += p.size;
1394 q.data = q_data;
1395 q.size = sizeof(q_data);
1396 for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1397 data += q.size;
1399 g.data = g_data;
1400 g.size = size;
1401 for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1402 data += g.size;
1404 y.data = y_data;
1405 y.size = sizeof(y_data);
1406 for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1408 if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1410 pgnutls_perror( ret );
1411 pgnutls_pubkey_deinit( handle );
1412 return STATUS_INTERNAL_ERROR;
1415 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1416 key_data(key)->a.pubkey = handle;
1417 return STATUS_SUCCESS;
1420 static NTSTATUS key_asymmetric_export( void *args )
1422 const struct key_asymmetric_export_params *params = args;
1423 struct key *key = params->key;
1424 unsigned flags = params->flags;
1426 switch (key->alg_id)
1428 case ALG_ID_ECDH_P256:
1429 case ALG_ID_ECDSA_P256:
1430 case ALG_ID_ECDSA_P384:
1431 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1432 return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1433 return key_export_ecc( key, params->buf, params->len, params->ret_len );
1435 case ALG_ID_RSA:
1436 case ALG_ID_RSA_SIGN:
1437 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1438 return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1439 return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1441 case ALG_ID_DSA:
1442 if (flags & KEY_EXPORT_FLAG_PUBLIC)
1444 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1445 return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1446 return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1448 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1449 return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1450 return STATUS_NOT_IMPLEMENTED;
1452 default:
1453 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1454 return STATUS_NOT_IMPLEMENTED;
1458 static NTSTATUS key_asymmetric_import( void *args )
1460 const struct key_asymmetric_import_params *params = args;
1461 struct key *key = params->key;
1462 unsigned flags = params->flags;
1464 switch (key->alg_id)
1466 case ALG_ID_ECDH_P256:
1467 case ALG_ID_ECDSA_P256:
1468 case ALG_ID_ECDSA_P384:
1469 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1470 return key_import_ecc_public( key, params->buf, params->len );
1471 return key_import_ecc( key, params->buf, params->len );
1473 case ALG_ID_RSA:
1474 case ALG_ID_RSA_SIGN:
1475 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1476 return key_import_rsa_public( key, params->buf, params->len );
1477 return key_import_rsa( key, params->buf, params->len );
1479 case ALG_ID_DSA:
1480 if (flags & KEY_IMPORT_FLAG_PUBLIC)
1482 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1483 return key_import_dsa_capi_public( key, params->buf, params->len );
1484 return key_import_dsa_public( key, params->buf, params->len );
1486 if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1487 return key_import_dsa_capi( key, params->buf, params->len );
1488 FIXME( "DSA private key not supported\n" );
1489 return STATUS_NOT_IMPLEMENTED;
1491 default:
1492 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1493 return STATUS_NOT_IMPLEMENTED;
1497 static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
1498 gnutls_datum_t *gnutls_signature )
1500 struct buffer buffer;
1501 DWORD r_len = signature_len / 2;
1502 DWORD s_len = r_len;
1503 BYTE *r = signature;
1504 BYTE *s = signature + r_len;
1506 buffer_init( &buffer );
1507 buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
1508 if (buffer.error)
1510 buffer_free( &buffer );
1511 return STATUS_NO_MEMORY;
1514 gnutls_signature->data = buffer.buffer;
1515 gnutls_signature->size = buffer.pos;
1516 return STATUS_SUCCESS;
1519 static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
1520 gnutls_datum_t *gnutls_signature )
1522 gnutls_signature->data = signature;
1523 gnutls_signature->size = signature_len;
1524 return STATUS_SUCCESS;
1527 static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
1528 gnutls_datum_t *gnutls_signature )
1530 switch (key->alg_id)
1532 case ALG_ID_ECDSA_P256:
1533 case ALG_ID_ECDSA_P384:
1534 case ALG_ID_DSA:
1535 return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
1537 case ALG_ID_RSA:
1538 case ALG_ID_RSA_SIGN:
1539 return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
1541 default:
1542 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1543 return STATUS_NOT_IMPLEMENTED;
1547 static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
1549 if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
1550 if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
1551 if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
1552 if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
1553 if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
1554 if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
1555 return GNUTLS_DIG_UNKNOWN;
1558 static NTSTATUS key_asymmetric_verify( void *args )
1560 const struct key_asymmetric_verify_params *params = args;
1561 struct key *key = params->key;
1562 unsigned flags = params->flags;
1563 gnutls_digest_algorithm_t hash_alg;
1564 gnutls_sign_algorithm_t sign_alg;
1565 gnutls_datum_t gnutls_hash, gnutls_signature;
1566 gnutls_pk_algorithm_t pk_alg;
1567 NTSTATUS status;
1568 int ret;
1570 switch (key->alg_id)
1572 case ALG_ID_ECDSA_P256:
1573 case ALG_ID_ECDSA_P384:
1575 if (flags) FIXME( "flags %#x not supported\n", flags );
1577 /* only the hash size must match, not the actual hash function */
1578 switch (params->hash_len)
1580 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1581 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1582 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1584 default:
1585 FIXME( "hash size %u not yet supported\n", params->hash_len );
1586 return STATUS_INVALID_SIGNATURE;
1588 pk_alg = GNUTLS_PK_ECC;
1589 break;
1591 case ALG_ID_RSA:
1592 case ALG_ID_RSA_SIGN:
1594 BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
1596 if (!(flags & BCRYPT_PAD_PKCS1) || !info) return STATUS_INVALID_PARAMETER;
1597 if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
1599 if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
1601 FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
1602 return STATUS_NOT_SUPPORTED;
1604 pk_alg = GNUTLS_PK_RSA;
1605 break;
1607 case ALG_ID_DSA:
1609 if (flags) FIXME( "flags %#x not supported\n", flags );
1610 if (params->hash_len != 20)
1612 FIXME( "hash size %u not supported\n", params->hash_len );
1613 return STATUS_INVALID_PARAMETER;
1615 hash_alg = GNUTLS_DIG_SHA1;
1616 pk_alg = GNUTLS_PK_DSA;
1617 break;
1619 default:
1620 FIXME( "algorithm %u not yet supported\n", key->alg_id );
1621 return STATUS_NOT_IMPLEMENTED;
1624 if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
1626 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
1627 return STATUS_NOT_IMPLEMENTED;
1630 if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
1631 return status;
1633 gnutls_hash.data = params->hash;
1634 gnutls_hash.size = params->hash_len;
1635 ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
1637 if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
1638 return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
1641 static unsigned int get_signature_length( enum alg_id id )
1643 switch (id)
1645 case ALG_ID_ECDSA_P256: return 64;
1646 case ALG_ID_ECDSA_P384: return 96;
1647 case ALG_ID_DSA: return 40;
1648 default:
1649 FIXME( "unhandled algorithm %u\n", id );
1650 return 0;
1654 static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
1655 UCHAR *output, ULONG output_len, ULONG *ret_len )
1657 switch (type)
1659 case ALG_ID_RSA:
1660 case ALG_ID_RSA_SIGN:
1662 *ret_len = signature.size;
1663 if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
1664 if (output) memcpy( output, signature.data, signature.size );
1665 return STATUS_SUCCESS;
1667 case ALG_ID_ECDSA_P256:
1668 case ALG_ID_ECDSA_P384:
1669 case ALG_ID_DSA:
1671 int err;
1672 unsigned int sig_len = get_signature_length( type );
1673 gnutls_datum_t r, s; /* format as r||s */
1675 if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
1677 pgnutls_perror( err );
1678 return STATUS_INTERNAL_ERROR;
1681 *ret_len = sig_len;
1682 if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
1684 if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
1686 ERR( "we didn't get a correct signature\n" );
1687 return STATUS_INTERNAL_ERROR;
1690 if (output)
1692 export_gnutls_datum( output, sig_len / 2, &r, 1 );
1693 export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
1696 free( r.data ); free( s.data );
1697 return STATUS_SUCCESS;
1699 default:
1700 return STATUS_INTERNAL_ERROR;
1704 static NTSTATUS key_asymmetric_sign( void *args )
1706 const struct key_asymmetric_sign_params *params = args;
1707 struct key *key = params->key;
1708 unsigned flags = params->flags;
1709 BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
1710 gnutls_datum_t hash, signature;
1711 gnutls_digest_algorithm_t hash_alg;
1712 NTSTATUS status;
1713 int ret;
1715 if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
1717 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1718 switch (params->input_len)
1720 case 20: hash_alg = GNUTLS_DIG_SHA1; break;
1721 case 32: hash_alg = GNUTLS_DIG_SHA256; break;
1722 case 48: hash_alg = GNUTLS_DIG_SHA384; break;
1723 case 64: hash_alg = GNUTLS_DIG_SHA512; break;
1725 default:
1726 FIXME( "hash size %u not yet supported\n", params->input_len );
1727 return STATUS_INVALID_PARAMETER;
1730 if (flags == BCRYPT_PAD_PKCS1 && pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
1732 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
1733 return STATUS_INVALID_PARAMETER;
1736 else if (key->alg_id == ALG_ID_DSA)
1738 if (flags) FIXME( "flags %#x not supported\n", flags );
1739 if (params->input_len != 20)
1741 FIXME( "hash size %u not supported\n", params->input_len );
1742 return STATUS_INVALID_PARAMETER;
1744 hash_alg = GNUTLS_DIG_SHA1;
1746 else if (flags == BCRYPT_PAD_PKCS1)
1748 if (!pad || !pad->pszAlgId)
1750 WARN( "padding info not found\n" );
1751 return STATUS_INVALID_PARAMETER;
1754 if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
1756 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
1757 return STATUS_NOT_SUPPORTED;
1760 else if (!flags)
1762 WARN( "invalid flags %#x\n", flags );
1763 return STATUS_INVALID_PARAMETER;
1765 else
1767 FIXME( "flags %#x not implemented\n", flags );
1768 return STATUS_NOT_IMPLEMENTED;
1771 if (!params->output)
1773 *params->ret_len = key->u.a.bitlen / 8;
1774 return STATUS_SUCCESS;
1776 if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1778 hash.data = params->input;
1779 hash.size = params->input_len;
1781 signature.data = NULL;
1782 signature.size = 0;
1784 if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, 0, &hash, &signature )))
1786 pgnutls_perror( ret );
1787 return STATUS_INTERNAL_ERROR;
1790 status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
1791 free( signature.data );
1792 return status;
1795 static NTSTATUS key_asymmetric_destroy( void *args )
1797 struct key *key = args;
1799 if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1800 if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1801 return STATUS_SUCCESS;
1804 static NTSTATUS key_asymmetric_duplicate( void *args )
1806 const struct key_asymmetric_duplicate_params *params = args;
1807 struct key *key_orig = params->key_orig;
1808 struct key *key_copy = params->key_copy;
1809 gnutls_privkey_t privkey;
1810 gnutls_pubkey_t pubkey;
1811 int ret;
1813 if (!key_data(key_orig)->a.privkey) return STATUS_SUCCESS;
1815 if ((ret = pgnutls_privkey_init( &privkey )))
1817 pgnutls_perror( ret );
1818 return STATUS_INTERNAL_ERROR;
1821 switch (key_orig->alg_id)
1823 case ALG_ID_RSA:
1824 case ALG_ID_RSA_SIGN:
1826 gnutls_datum_t m, e, d, p, q, u, e1, e2;
1827 if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1829 pgnutls_perror( ret );
1830 return STATUS_INTERNAL_ERROR;
1832 ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
1833 free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1834 free( e1.data ); free( e2.data );
1835 if (ret)
1837 pgnutls_perror( ret );
1838 return STATUS_INTERNAL_ERROR;
1840 break;
1842 case ALG_ID_DSA:
1844 gnutls_datum_t p, q, g, y, x;
1845 if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
1847 pgnutls_perror( ret );
1848 return STATUS_INTERNAL_ERROR;
1850 ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
1851 free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1852 if (ret)
1854 pgnutls_perror( ret );
1855 return STATUS_INTERNAL_ERROR;
1857 key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
1858 break;
1860 case ALG_ID_ECDH_P256:
1861 case ALG_ID_ECDSA_P256:
1862 case ALG_ID_ECDSA_P384:
1864 gnutls_ecc_curve_t curve;
1865 gnutls_datum_t x, y, k;
1866 if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
1868 pgnutls_perror( ret );
1869 return STATUS_INTERNAL_ERROR;
1871 ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
1872 free( x.data ); free( y.data ); free( k.data );
1873 if (ret)
1875 pgnutls_perror( ret );
1876 return STATUS_INTERNAL_ERROR;
1878 break;
1880 default:
1881 ERR( "unhandled algorithm %u\n", key_orig->alg_id );
1882 return STATUS_INTERNAL_ERROR;
1885 if (key_data(key_orig)->a.pubkey)
1887 if ((ret = pgnutls_pubkey_init( &pubkey )))
1889 pgnutls_perror( ret );
1890 pgnutls_privkey_deinit( privkey );
1891 return STATUS_INTERNAL_ERROR;
1893 if ((ret = pgnutls_pubkey_import_privkey( pubkey, key_data(key_orig)->a.privkey, 0, 0 )))
1895 pgnutls_perror( ret );
1896 pgnutls_pubkey_deinit( pubkey );
1897 pgnutls_privkey_deinit( privkey );
1898 return STATUS_INTERNAL_ERROR;
1900 key_data(key_copy)->a.pubkey = pubkey;
1903 key_data(key_copy)->a.privkey = privkey;
1904 return STATUS_SUCCESS;
1907 static NTSTATUS key_asymmetric_decrypt( void *args )
1909 const struct key_asymmetric_decrypt_params *params = args;
1910 gnutls_datum_t e, d = { 0 };
1911 NTSTATUS status = STATUS_SUCCESS;
1912 int ret;
1914 e.data = params->input;
1915 e.size = params->input_len;
1916 if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
1918 pgnutls_perror( ret );
1919 return STATUS_INTERNAL_ERROR;
1922 *params->ret_len = d.size;
1923 if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
1924 else status = STATUS_BUFFER_TOO_SMALL;
1926 free( d.data );
1927 return status;
1930 const unixlib_entry_t __wine_unix_call_funcs[] =
1932 gnutls_process_attach,
1933 gnutls_process_detach,
1934 key_symmetric_vector_reset,
1935 key_symmetric_set_auth_data,
1936 key_symmetric_encrypt,
1937 key_symmetric_decrypt,
1938 key_symmetric_get_tag,
1939 key_symmetric_destroy,
1940 key_asymmetric_generate,
1941 key_asymmetric_decrypt,
1942 key_asymmetric_duplicate,
1943 key_asymmetric_sign,
1944 key_asymmetric_verify,
1945 key_asymmetric_destroy,
1946 key_asymmetric_export,
1947 key_asymmetric_import
1950 #ifdef _WIN64
1952 typedef ULONG PTR32;
1954 struct key_symmetric32
1956 enum mode_id mode;
1957 ULONG block_size;
1958 PTR32 vector;
1959 ULONG vector_len;
1960 PTR32 secret;
1961 ULONG secret_len;
1962 ULONG __cs[6];
1965 struct key_asymmetric32
1967 ULONG bitlen; /* ignored for ECC keys */
1968 ULONG flags;
1969 PTR32 pubkey;
1970 ULONG pubkey_len;
1971 DSSSEED dss_seed;
1974 struct key32
1976 struct object hdr;
1977 enum alg_id alg_id;
1978 UINT64 private[2]; /* private data for backend */
1979 union
1981 struct key_symmetric32 s;
1982 struct key_asymmetric32 a;
1983 } u;
1986 static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
1988 key->hdr = key32->hdr;
1989 key->alg_id = key32->alg_id;
1990 key->private[0] = key32->private[0];
1991 key->private[1] = key32->private[1];
1992 key->u.s.mode = key32->u.s.mode;
1993 key->u.s.block_size = key32->u.s.block_size;
1994 key->u.s.vector = ULongToPtr(key32->u.s.vector);
1995 key->u.s.vector_len = key32->u.s.vector_len;
1996 key->u.s.secret = ULongToPtr(key32->u.s.secret);
1997 key->u.s.secret_len = key32->u.s.secret_len;
1998 return key;
2001 static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
2003 key->hdr = key32->hdr;
2004 key->alg_id = key32->alg_id;
2005 key->private[0] = key32->private[0];
2006 key->private[1] = key32->private[1];
2007 key->u.a.bitlen = key32->u.a.bitlen;
2008 key->u.a.flags = key32->u.a.flags;
2009 key->u.a.dss_seed = key32->u.a.dss_seed;
2010 return key;
2013 static void put_symmetric_key32( struct key *key, struct key32 *key32 )
2015 key32->private[0] = key->private[0];
2016 key32->private[1] = key->private[1];
2019 static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
2021 key32->private[0] = key->private[0];
2022 key32->private[1] = key->private[1];
2023 key32->u.a.flags = key->u.a.flags;
2024 key32->u.a.dss_seed = key->u.a.dss_seed;
2027 static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
2029 NTSTATUS ret;
2030 struct key key;
2031 struct key32 *key32 = args;
2033 ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
2034 put_symmetric_key32( &key, key32 );
2035 return ret;
2038 static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
2040 struct
2042 PTR32 key;
2043 PTR32 auth_data;
2044 ULONG len;
2045 } const *params32 = args;
2047 NTSTATUS ret;
2048 struct key key;
2049 struct key32 *key32 = ULongToPtr( params32->key );
2050 struct key_symmetric_set_auth_data_params params =
2052 get_symmetric_key( key32, &key ),
2053 ULongToPtr(params32->auth_data),
2054 params32->len
2057 ret = key_symmetric_set_auth_data( &params );
2058 put_symmetric_key32( &key, key32 );
2059 return ret;
2062 static NTSTATUS wow64_key_symmetric_encrypt( void *args )
2064 struct
2066 PTR32 key;
2067 PTR32 input;
2068 ULONG input_len;
2069 PTR32 output;
2070 ULONG output_len;
2071 } const *params32 = args;
2073 NTSTATUS ret;
2074 struct key key;
2075 struct key32 *key32 = ULongToPtr( params32->key );
2076 struct key_symmetric_encrypt_params params =
2078 get_symmetric_key( key32, &key ),
2079 ULongToPtr(params32->input),
2080 params32->input_len,
2081 ULongToPtr(params32->output),
2082 params32->output_len
2085 ret = key_symmetric_encrypt( &params );
2086 put_symmetric_key32( &key, key32 );
2087 return ret;
2090 static NTSTATUS wow64_key_symmetric_decrypt( void *args )
2092 struct
2094 PTR32 key;
2095 PTR32 input;
2096 ULONG input_len;
2097 PTR32 output;
2098 ULONG output_len;
2099 } const *params32 = args;
2101 NTSTATUS ret;
2102 struct key key;
2103 struct key32 *key32 = ULongToPtr( params32->key );
2104 struct key_symmetric_decrypt_params params =
2106 get_symmetric_key( key32, &key ),
2107 ULongToPtr(params32->input),
2108 params32->input_len,
2109 ULongToPtr(params32->output),
2110 params32->output_len
2113 ret = key_symmetric_decrypt( &params );
2114 put_symmetric_key32( &key, key32 );
2115 return ret;
2118 static NTSTATUS wow64_key_symmetric_get_tag( void *args )
2120 struct
2122 PTR32 key;
2123 PTR32 tag;
2124 ULONG len;
2125 } const *params32 = args;
2127 NTSTATUS ret;
2128 struct key key;
2129 struct key32 *key32 = ULongToPtr( params32->key );
2130 struct key_symmetric_get_tag_params params =
2132 get_symmetric_key( key32, &key ),
2133 ULongToPtr(params32->tag),
2134 params32->len
2137 ret = key_symmetric_get_tag( &params );
2138 put_symmetric_key32( &key, key32 );
2139 return ret;
2142 static NTSTATUS wow64_key_symmetric_destroy( void *args )
2144 struct key32 *key32 = args;
2145 struct key key;
2147 return key_symmetric_destroy( get_symmetric_key( key32, &key ));
2150 static NTSTATUS wow64_key_asymmetric_generate( void *args )
2152 struct key32 *key32 = args;
2153 struct key key;
2154 NTSTATUS ret;
2156 ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
2157 put_asymmetric_key32( &key, key32 );
2158 return ret;
2161 static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
2163 struct
2165 PTR32 key;
2166 PTR32 input;
2167 ULONG input_len;
2168 PTR32 output;
2169 ULONG output_len;
2170 PTR32 ret_len;
2171 } const *params32 = args;
2173 NTSTATUS ret;
2174 struct key key;
2175 struct key32 *key32 = ULongToPtr( params32->key );
2176 struct key_asymmetric_decrypt_params params =
2178 get_asymmetric_key( key32, &key ),
2179 ULongToPtr(params32->input),
2180 params32->input_len,
2181 ULongToPtr(params32->output),
2182 params32->output_len,
2183 ULongToPtr(params32->ret_len)
2186 ret = key_asymmetric_decrypt( &params );
2187 put_asymmetric_key32( &key, key32 );
2188 return ret;
2191 static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
2193 struct
2195 PTR32 key_orig;
2196 PTR32 key_copy;
2197 } const *params32 = args;
2199 NTSTATUS ret;
2200 struct key key_orig, key_copy;
2201 struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
2202 struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
2203 struct key_asymmetric_duplicate_params params =
2205 get_asymmetric_key( key_orig32, &key_orig ),
2206 get_asymmetric_key( key_copy32, &key_copy )
2209 ret = key_asymmetric_duplicate( &params );
2210 put_asymmetric_key32( &key_copy, key_copy32 );
2211 return ret;
2214 static NTSTATUS wow64_key_asymmetric_sign( void *args )
2216 struct
2218 PTR32 key;
2219 PTR32 padding;
2220 PTR32 input;
2221 ULONG input_len;
2222 PTR32 output;
2223 ULONG output_len;
2224 PTR32 ret_len;
2225 ULONG flags;
2226 } const *params32 = args;
2228 NTSTATUS ret;
2229 struct key key;
2230 BCRYPT_PKCS1_PADDING_INFO padding;
2231 struct key32 *key32 = ULongToPtr( params32->key );
2232 struct key_asymmetric_sign_params params =
2234 get_asymmetric_key( key32, &key ),
2235 NULL, /* padding */
2236 ULongToPtr(params32->input),
2237 params32->input_len,
2238 ULongToPtr(params32->output),
2239 params32->output_len,
2240 ULongToPtr(params32->ret_len),
2241 params32->flags
2244 if (params32->flags & BCRYPT_PAD_PKCS1)
2246 PTR32 *info = ULongToPtr( params32->padding );
2247 if (!info) return STATUS_INVALID_PARAMETER;
2248 padding.pszAlgId = ULongToPtr( *info );
2249 params.padding = &padding;
2252 ret = key_asymmetric_sign( &params );
2253 put_asymmetric_key32( &key, key32 );
2254 return ret;
2257 static NTSTATUS wow64_key_asymmetric_verify( void *args )
2259 struct
2261 PTR32 key;
2262 PTR32 padding;
2263 PTR32 hash;
2264 ULONG hash_len;
2265 PTR32 signature;
2266 ULONG signature_len;
2267 ULONG flags;
2268 } const *params32 = args;
2270 NTSTATUS ret;
2271 struct key key;
2272 BCRYPT_PKCS1_PADDING_INFO padding;
2273 struct key32 *key32 = ULongToPtr( params32->key );
2274 struct key_asymmetric_verify_params params =
2276 get_asymmetric_key( key32, &key ),
2277 NULL, /* padding */
2278 ULongToPtr(params32->hash),
2279 params32->hash_len,
2280 ULongToPtr(params32->signature),
2281 params32->signature_len,
2282 params32->flags
2285 if (params32->flags & BCRYPT_PAD_PKCS1)
2287 PTR32 *info = ULongToPtr( params32->padding );
2288 if (!info) return STATUS_INVALID_PARAMETER;
2289 padding.pszAlgId = ULongToPtr( *info );
2290 params.padding = &padding;
2293 ret = key_asymmetric_verify( &params );
2294 put_asymmetric_key32( &key, key32 );
2295 return ret;
2298 static NTSTATUS wow64_key_asymmetric_destroy( void *args )
2300 struct key32 *key32 = args;
2301 struct key key;
2303 return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
2306 static NTSTATUS wow64_key_asymmetric_export( void *args )
2308 struct
2310 PTR32 key;
2311 ULONG flags;
2312 PTR32 buf;
2313 ULONG len;
2314 PTR32 ret_len;
2315 } const *params32 = args;
2317 NTSTATUS ret;
2318 struct key key;
2319 struct key32 *key32 = ULongToPtr( params32->key );
2320 struct key_asymmetric_export_params params =
2322 get_asymmetric_key( key32, &key ),
2323 params32->flags,
2324 ULongToPtr(params32->buf),
2325 params32->len,
2326 ULongToPtr(params32->ret_len),
2329 ret = key_asymmetric_export( &params );
2330 put_asymmetric_key32( &key, key32 );
2331 return ret;
2334 static NTSTATUS wow64_key_asymmetric_import( void *args )
2336 struct
2338 PTR32 key;
2339 ULONG flags;
2340 PTR32 buf;
2341 ULONG len;
2342 } const *params32 = args;
2344 NTSTATUS ret;
2345 struct key key;
2346 struct key32 *key32 = ULongToPtr( params32->key );
2347 struct key_asymmetric_import_params params =
2349 get_asymmetric_key( key32, &key ),
2350 params32->flags,
2351 ULongToPtr(params32->buf),
2352 params32->len
2355 ret = key_asymmetric_import( &params );
2356 put_asymmetric_key32( &key, key32 );
2357 return ret;
2360 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
2362 gnutls_process_attach,
2363 gnutls_process_detach,
2364 wow64_key_symmetric_vector_reset,
2365 wow64_key_symmetric_set_auth_data,
2366 wow64_key_symmetric_encrypt,
2367 wow64_key_symmetric_decrypt,
2368 wow64_key_symmetric_get_tag,
2369 wow64_key_symmetric_destroy,
2370 wow64_key_asymmetric_generate,
2371 wow64_key_asymmetric_decrypt,
2372 wow64_key_asymmetric_duplicate,
2373 wow64_key_asymmetric_sign,
2374 wow64_key_asymmetric_verify,
2375 wow64_key_asymmetric_destroy,
2376 wow64_key_asymmetric_export,
2377 wow64_key_asymmetric_import
2380 #endif /* _WIN64 */
2382 #endif /* HAVE_GNUTLS_CIPHER_INIT */