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
27 #ifdef HAVE_GNUTLS_CIPHER_INIT
32 #include <sys/types.h>
34 #include <gnutls/gnutls.h>
35 #include <gnutls/crypto.h>
36 #include <gnutls/abstract.h>
39 #define WIN32_NO_STATUS
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)))
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
,
74 gnutls_cipher_hd_t cipher
;
75 gnutls_privkey_t privkey
;
77 C_ASSERT( sizeof(union key_data
) <= sizeof(((struct key
*)0)->private) );
79 static union key_data
*key_data( struct key
*key
)
81 return (union key_data
*)key
->private;
84 /* Not present in gnutls version < 3.0 */
85 static int (*pgnutls_cipher_tag
)(gnutls_cipher_hd_t
, void *, size_t);
86 static int (*pgnutls_cipher_add_auth
)(gnutls_cipher_hd_t
, const void *, size_t);
87 static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign
)(gnutls_pk_algorithm_t
, gnutls_digest_algorithm_t
);
88 static int (*pgnutls_pubkey_import_ecc_raw
)(gnutls_pubkey_t
, gnutls_ecc_curve_t
,
89 const gnutls_datum_t
*, const gnutls_datum_t
*);
90 static int (*pgnutls_privkey_import_ecc_raw
)(gnutls_privkey_t
, gnutls_ecc_curve_t
, const gnutls_datum_t
*,
91 const gnutls_datum_t
*, const gnutls_datum_t
*);
92 static int (*pgnutls_pubkey_verify_hash2
)(gnutls_pubkey_t
, gnutls_sign_algorithm_t
, unsigned int,
93 const gnutls_datum_t
*, const gnutls_datum_t
*);
95 /* Not present in gnutls version < 2.11.0 */
96 static int (*pgnutls_pubkey_import_rsa_raw
)(gnutls_pubkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*);
98 /* Not present in gnutls version < 2.12.0 */
99 static int (*pgnutls_pubkey_import_dsa_raw
)(gnutls_pubkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*,
100 const gnutls_datum_t
*, const gnutls_datum_t
*);
102 /* Not present in gnutls version < 3.3.0 */
103 static int (*pgnutls_privkey_export_ecc_raw
)(gnutls_privkey_t
, gnutls_ecc_curve_t
*,
104 gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*);
105 static int (*pgnutls_privkey_export_rsa_raw
)(gnutls_privkey_t
, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
106 gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
108 static int (*pgnutls_privkey_export_dsa_raw
)(gnutls_privkey_t
, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
109 gnutls_datum_t
*, gnutls_datum_t
*);
110 static int (*pgnutls_privkey_generate
)(gnutls_privkey_t
, gnutls_pk_algorithm_t
, unsigned int, unsigned int);
111 static int (*pgnutls_privkey_import_rsa_raw
)(gnutls_privkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*,
112 const gnutls_datum_t
*, const gnutls_datum_t
*, const gnutls_datum_t
*,
113 const gnutls_datum_t
*, const gnutls_datum_t
*, const gnutls_datum_t
*);
114 static int (*pgnutls_privkey_decrypt_data
)(gnutls_privkey_t
, unsigned int flags
, const gnutls_datum_t
*, gnutls_datum_t
*);
116 /* Not present in gnutls version < 3.6.0 */
117 static int (*pgnutls_decode_rs_value
)(const gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*);
119 static void *libgnutls_handle
;
120 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
121 MAKE_FUNCPTR(gnutls_cipher_decrypt2
);
122 MAKE_FUNCPTR(gnutls_cipher_deinit
);
123 MAKE_FUNCPTR(gnutls_cipher_encrypt2
);
124 MAKE_FUNCPTR(gnutls_cipher_init
);
125 MAKE_FUNCPTR(gnutls_global_deinit
);
126 MAKE_FUNCPTR(gnutls_global_init
);
127 MAKE_FUNCPTR(gnutls_global_set_log_function
);
128 MAKE_FUNCPTR(gnutls_global_set_log_level
);
129 MAKE_FUNCPTR(gnutls_perror
);
130 MAKE_FUNCPTR(gnutls_privkey_decrypt_data
);
131 MAKE_FUNCPTR(gnutls_privkey_deinit
);
132 MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw
);
133 MAKE_FUNCPTR(gnutls_privkey_init
);
134 MAKE_FUNCPTR(gnutls_privkey_sign_hash
);
135 MAKE_FUNCPTR(gnutls_pubkey_deinit
);
136 MAKE_FUNCPTR(gnutls_pubkey_init
);
139 static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle
, void *tag
, size_t tag_size
)
141 return GNUTLS_E_UNKNOWN_CIPHER_TYPE
;
144 static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle
, const void *ptext
, size_t ptext_size
)
146 return GNUTLS_E_UNKNOWN_CIPHER_TYPE
;
149 static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key
, gnutls_ecc_curve_t curve
,
150 const gnutls_datum_t
*x
, const gnutls_datum_t
*y
)
152 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
155 static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key
, gnutls_datum_t
*m
, gnutls_datum_t
*e
,
156 gnutls_datum_t
*d
, gnutls_datum_t
*p
, gnutls_datum_t
*q
,
157 gnutls_datum_t
*u
, gnutls_datum_t
*e1
, gnutls_datum_t
*e2
)
159 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
162 static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key
, gnutls_ecc_curve_t
*curve
,
163 gnutls_datum_t
*x
, gnutls_datum_t
*y
, gnutls_datum_t
*k
)
165 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
168 static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key
, gnutls_ecc_curve_t curve
,
169 const gnutls_datum_t
*x
, const gnutls_datum_t
*y
,
170 const gnutls_datum_t
*k
)
172 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
175 static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key
, gnutls_datum_t
*p
, gnutls_datum_t
*q
,
176 gnutls_datum_t
*g
, gnutls_datum_t
*y
, gnutls_datum_t
*x
)
178 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
181 static gnutls_sign_algorithm_t
compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk
, gnutls_digest_algorithm_t hash
)
183 return GNUTLS_SIGN_UNKNOWN
;
186 static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key
, gnutls_sign_algorithm_t algo
,
187 unsigned int flags
, const gnutls_datum_t
*hash
,
188 const gnutls_datum_t
*signature
)
190 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
193 static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key
, const gnutls_datum_t
*m
, const gnutls_datum_t
*e
)
195 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
198 static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key
, const gnutls_datum_t
*p
, const gnutls_datum_t
*q
,
199 const gnutls_datum_t
*g
, const gnutls_datum_t
*y
)
201 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
204 static int compat_gnutls_privkey_generate(gnutls_privkey_t key
, gnutls_pk_algorithm_t algo
, unsigned int bits
,
207 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
210 static int compat_gnutls_decode_rs_value(const gnutls_datum_t
* sig_value
, gnutls_datum_t
* r
, gnutls_datum_t
* s
)
212 return GNUTLS_E_INTERNAL_ERROR
;
215 static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key
, const gnutls_datum_t
*m
, const gnutls_datum_t
*e
,
216 const gnutls_datum_t
*d
, const gnutls_datum_t
*p
, const gnutls_datum_t
*q
,
217 const gnutls_datum_t
*u
, const gnutls_datum_t
*e1
, const gnutls_datum_t
*e2
)
219 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
222 static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key
, unsigned int flags
, const gnutls_datum_t
*cipher_text
,
223 gnutls_datum_t
*plain_text
)
225 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
228 static void gnutls_log( int level
, const char *msg
)
230 TRACE( "<%d> %s", level
, msg
);
233 static NTSTATUS
gnutls_process_attach( void *args
)
238 if ((env_str
= getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
240 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str
));
244 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
245 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
248 if (!(libgnutls_handle
= dlopen( SONAME_LIBGNUTLS
, RTLD_NOW
)))
250 ERR_(winediag
)( "failed to load libgnutls, no support for encryption\n" );
251 return STATUS_DLL_NOT_FOUND
;
254 #define LOAD_FUNCPTR(f) \
255 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
257 ERR( "failed to load %s\n", #f ); \
261 LOAD_FUNCPTR(gnutls_cipher_decrypt2
)
262 LOAD_FUNCPTR(gnutls_cipher_deinit
)
263 LOAD_FUNCPTR(gnutls_cipher_encrypt2
)
264 LOAD_FUNCPTR(gnutls_cipher_init
)
265 LOAD_FUNCPTR(gnutls_global_deinit
)
266 LOAD_FUNCPTR(gnutls_global_init
)
267 LOAD_FUNCPTR(gnutls_global_set_log_function
)
268 LOAD_FUNCPTR(gnutls_global_set_log_level
)
269 LOAD_FUNCPTR(gnutls_perror
)
270 LOAD_FUNCPTR(gnutls_privkey_deinit
);
271 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw
);
272 LOAD_FUNCPTR(gnutls_privkey_init
);
273 LOAD_FUNCPTR(gnutls_privkey_sign_hash
);
274 LOAD_FUNCPTR(gnutls_pubkey_deinit
);
275 LOAD_FUNCPTR(gnutls_pubkey_init
);
278 #define LOAD_FUNCPTR_OPT(f) \
279 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
281 WARN( "failed to load %s\n", #f ); \
285 LOAD_FUNCPTR_OPT(gnutls_cipher_tag
)
286 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth
)
287 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw
)
288 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw
)
289 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw
)
290 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw
)
291 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw
)
292 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign
)
293 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2
)
294 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw
)
295 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw
)
296 LOAD_FUNCPTR_OPT(gnutls_privkey_generate
)
297 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value
)
298 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw
)
299 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data
)
300 #undef LOAD_FUNCPTR_OPT
302 if ((ret
= pgnutls_global_init()) != GNUTLS_E_SUCCESS
)
304 pgnutls_perror( ret
);
308 if (TRACE_ON( bcrypt
))
310 pgnutls_global_set_log_level( 4 );
311 pgnutls_global_set_log_function( gnutls_log
);
314 return STATUS_SUCCESS
;
317 dlclose( libgnutls_handle
);
318 libgnutls_handle
= NULL
;
319 return STATUS_DLL_NOT_FOUND
;
322 static NTSTATUS
gnutls_process_detach( void *args
)
324 if (libgnutls_handle
)
326 pgnutls_global_deinit();
327 dlclose( libgnutls_handle
);
328 libgnutls_handle
= NULL
;
330 return STATUS_SUCCESS
;
341 static void buffer_init( struct buffer
*buffer
)
343 buffer
->buffer
= NULL
;
346 buffer
->error
= FALSE
;
349 static void buffer_free( struct buffer
*buffer
)
351 free( buffer
->buffer
);
354 static void buffer_append( struct buffer
*buffer
, BYTE
*data
, DWORD len
)
358 if (buffer
->pos
+ len
> buffer
->length
)
360 DWORD new_length
= max( max( buffer
->pos
+ len
, buffer
->length
* 2 ), 64 );
363 if (!(new_buffer
= realloc( buffer
->buffer
, new_length
)))
365 ERR( "out of memory\n" );
366 buffer
->error
= TRUE
;
370 buffer
->buffer
= new_buffer
;
371 buffer
->length
= new_length
;
374 memcpy( &buffer
->buffer
[buffer
->pos
], data
, len
);
378 static void buffer_append_byte( struct buffer
*buffer
, BYTE value
)
380 buffer_append( buffer
, &value
, sizeof(value
) );
383 static void buffer_append_asn1_length( struct buffer
*buffer
, DWORD length
)
389 buffer_append_byte( buffer
, length
);
393 if (length
<= 0xff) num_bytes
= 1;
394 else if (length
<= 0xffff) num_bytes
= 2;
395 else if (length
<= 0xffffff) num_bytes
= 3;
398 buffer_append_byte( buffer
, 0x80 | num_bytes
);
399 while (num_bytes
--) buffer_append_byte( buffer
, length
>> (num_bytes
* 8) );
402 static void buffer_append_asn1_integer( struct buffer
*buffer
, BYTE
*data
, DWORD len
)
404 DWORD leading_zero
= (*data
& 0x80) != 0;
406 buffer_append_byte( buffer
, 0x02 ); /* tag */
407 buffer_append_asn1_length( buffer
, len
+ leading_zero
);
408 if (leading_zero
) buffer_append_byte( buffer
, 0 );
409 buffer_append( buffer
, data
, len
);
412 static void buffer_append_asn1_sequence( struct buffer
*buffer
, struct buffer
*content
)
416 buffer
->error
= TRUE
;
420 buffer_append_byte( buffer
, 0x30 ); /* tag */
421 buffer_append_asn1_length( buffer
, content
->pos
);
422 buffer_append( buffer
, content
->buffer
, content
->pos
);
425 static void buffer_append_asn1_r_s( struct buffer
*buffer
, BYTE
*r
, DWORD r_len
, BYTE
*s
, DWORD s_len
)
429 buffer_init( &value
);
430 buffer_append_asn1_integer( &value
, r
, r_len
);
431 buffer_append_asn1_integer( &value
, s
, s_len
);
432 buffer_append_asn1_sequence( buffer
, &value
);
433 buffer_free( &value
);
436 static gnutls_cipher_algorithm_t
get_gnutls_cipher( const struct key
*key
)
441 WARN( "handle block size\n" );
442 switch (key
->u
.s
.mode
)
445 return GNUTLS_CIPHER_3DES_CBC
;
449 FIXME( "3DES mode %u with key length %u not supported\n", key
->u
.s
.mode
, key
->u
.s
.secret_len
);
450 return GNUTLS_CIPHER_UNKNOWN
;
453 WARN( "handle block size\n" );
454 switch (key
->u
.s
.mode
)
457 if (key
->u
.s
.secret_len
== 16) return GNUTLS_CIPHER_AES_128_GCM
;
458 if (key
->u
.s
.secret_len
== 32) return GNUTLS_CIPHER_AES_256_GCM
;
460 case MODE_ID_ECB
: /* can be emulated with CBC + empty IV */
462 if (key
->u
.s
.secret_len
== 16) return GNUTLS_CIPHER_AES_128_CBC
;
463 if (key
->u
.s
.secret_len
== 24) return GNUTLS_CIPHER_AES_192_CBC
;
464 if (key
->u
.s
.secret_len
== 32) return GNUTLS_CIPHER_AES_256_CBC
;
469 FIXME( "AES mode %u with key length %u not supported\n", key
->u
.s
.mode
, key
->u
.s
.secret_len
);
470 return GNUTLS_CIPHER_UNKNOWN
;
473 FIXME( "algorithm %u not supported\n", key
->alg_id
);
474 return GNUTLS_CIPHER_UNKNOWN
;
478 static NTSTATUS
key_symmetric_vector_reset( void *args
)
480 struct key
*key
= args
;
482 if (!key_data(key
)->cipher
) return STATUS_SUCCESS
;
483 TRACE( "invalidating cipher handle\n" );
484 pgnutls_cipher_deinit( key_data(key
)->cipher
);
485 key_data(key
)->cipher
= NULL
;
486 return STATUS_SUCCESS
;
489 static NTSTATUS
init_cipher_handle( struct key
*key
)
491 gnutls_cipher_algorithm_t cipher
;
492 gnutls_datum_t secret
, vector
;
495 if (key_data(key
)->cipher
) return STATUS_SUCCESS
;
496 if ((cipher
= get_gnutls_cipher( key
)) == GNUTLS_CIPHER_UNKNOWN
) return STATUS_NOT_SUPPORTED
;
498 secret
.data
= key
->u
.s
.secret
;
499 secret
.size
= key
->u
.s
.secret_len
;
501 vector
.data
= key
->u
.s
.vector
;
502 vector
.size
= key
->u
.s
.vector_len
;
504 if ((ret
= pgnutls_cipher_init( &key_data(key
)->cipher
, cipher
, &secret
, key
->u
.s
.vector
? &vector
: NULL
)))
506 pgnutls_perror( ret
);
507 return STATUS_INTERNAL_ERROR
;
510 return STATUS_SUCCESS
;
513 static NTSTATUS
key_symmetric_set_auth_data( void *args
)
515 const struct key_symmetric_set_auth_data_params
*params
= args
;
519 if (!params
->auth_data
) return STATUS_SUCCESS
;
520 if ((status
= init_cipher_handle( params
->key
))) return status
;
522 if ((ret
= pgnutls_cipher_add_auth( key_data(params
->key
)->cipher
, params
->auth_data
, params
->len
)))
524 pgnutls_perror( ret
);
525 return STATUS_INTERNAL_ERROR
;
527 return STATUS_SUCCESS
;
530 static NTSTATUS
key_symmetric_encrypt( void *args
)
532 const struct key_symmetric_encrypt_params
*params
= args
;
536 if ((status
= init_cipher_handle( params
->key
))) return status
;
538 if ((ret
= pgnutls_cipher_encrypt2( key_data(params
->key
)->cipher
, params
->input
, params
->input_len
,
539 params
->output
, params
->output_len
)))
541 pgnutls_perror( ret
);
542 return STATUS_INTERNAL_ERROR
;
544 return STATUS_SUCCESS
;
547 static NTSTATUS
key_symmetric_decrypt( void *args
)
549 const struct key_symmetric_decrypt_params
*params
= args
;
553 if ((status
= init_cipher_handle( params
->key
))) return status
;
555 if ((ret
= pgnutls_cipher_decrypt2( key_data(params
->key
)->cipher
, params
->input
, params
->input_len
,
556 params
->output
, params
->output_len
)))
558 pgnutls_perror( ret
);
559 return STATUS_INTERNAL_ERROR
;
561 return STATUS_SUCCESS
;
564 static NTSTATUS
key_symmetric_get_tag( void *args
)
566 const struct key_symmetric_get_tag_params
*params
= args
;
570 if ((status
= init_cipher_handle( params
->key
))) return status
;
572 if ((ret
= pgnutls_cipher_tag( key_data(params
->key
)->cipher
, params
->tag
, params
->len
)))
574 pgnutls_perror( ret
);
575 return STATUS_INTERNAL_ERROR
;
577 return STATUS_SUCCESS
;
580 static NTSTATUS
key_symmetric_destroy( void *args
)
582 struct key
*key
= args
;
584 if (key_data(key
)->cipher
) pgnutls_cipher_deinit( key_data(key
)->cipher
);
585 return STATUS_SUCCESS
;
588 static ULONG
export_gnutls_datum( UCHAR
*buffer
, ULONG buflen
, gnutls_datum_t
*d
, BOOL zero_pad
)
590 ULONG size
= d
->size
;
591 UCHAR
*src
= d
->data
;
594 assert( size
<= buflen
+ 1 );
595 if (size
== buflen
+ 1)
603 offset
= buflen
- size
;
604 if (buffer
) memset( buffer
, 0, offset
);
608 if (buffer
) memcpy( buffer
+ offset
, src
, size
);
612 #define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, bitlen / f, &d, p )
613 static NTSTATUS
export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key
, ULONG bitlen
, void *pubkey
, ULONG
*pubkey_len
)
615 BCRYPT_RSAKEY_BLOB
*rsa_blob
= pubkey
;
620 if ((ret
= pgnutls_privkey_export_rsa_raw( gnutls_key
, &m
, &e
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
)))
622 pgnutls_perror( ret
);
623 return STATUS_INTERNAL_ERROR
;
626 if (*pubkey_len
< sizeof(*rsa_blob
) + EXPORT_SIZE(e
,8,0) + EXPORT_SIZE(m
,8,1))
628 FIXME( "wrong pubkey len %u\n", *pubkey_len
);
629 pgnutls_perror( ret
);
630 free( e
.data
); free( m
.data
);
631 return STATUS_BUFFER_TOO_SMALL
;
634 dst
= (UCHAR
*)(rsa_blob
+ 1);
635 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, bitlen
/ 8, &e
, 0 );
637 dst
+= rsa_blob
->cbPublicExp
;
638 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, bitlen
/ 8, &m
, 1 );
640 rsa_blob
->Magic
= BCRYPT_RSAPUBLIC_MAGIC
;
641 rsa_blob
->BitLength
= bitlen
;
642 rsa_blob
->cbPrime1
= 0;
643 rsa_blob
->cbPrime2
= 0;
645 *pubkey_len
= sizeof(*rsa_blob
) + rsa_blob
->cbPublicExp
+ rsa_blob
->cbModulus
;
647 free( e
.data
); free( m
.data
);
648 return STATUS_SUCCESS
;
651 static NTSTATUS
export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key
, enum alg_id alg_id
, void *pubkey
,
654 BCRYPT_ECCKEY_BLOB
*ecc_blob
= pubkey
;
655 gnutls_ecc_curve_t curve
;
663 case ALG_ID_ECDH_P256
:
664 magic
= BCRYPT_ECDH_PUBLIC_P256_MAGIC
;
667 case ALG_ID_ECDSA_P256
:
668 magic
= BCRYPT_ECDSA_PUBLIC_P256_MAGIC
;
672 FIXME( "algorithm %u not supported\n", alg_id
);
673 return STATUS_NOT_IMPLEMENTED
;
676 if ((ret
= pgnutls_privkey_export_ecc_raw( gnutls_key
, &curve
, &x
, &y
, NULL
)))
678 pgnutls_perror( ret
);
679 return STATUS_INTERNAL_ERROR
;
682 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
)
684 FIXME( "curve %u not supported\n", curve
);
685 free( x
.data
); free( y
.data
);
686 return STATUS_NOT_IMPLEMENTED
;
689 if (*pubkey_len
< sizeof(*ecc_blob
) + size
* 2)
691 FIXME( "wrong pubkey len %u / %u\n", *pubkey_len
, (ULONG
)sizeof(*ecc_blob
) + size
* 2 );
692 pgnutls_perror( ret
);
693 free( x
.data
); free( y
.data
);
694 return STATUS_BUFFER_TOO_SMALL
;
697 ecc_blob
->dwMagic
= magic
;
698 ecc_blob
->cbKey
= size
;
700 dst
= (UCHAR
*)(ecc_blob
+ 1);
701 export_gnutls_datum( dst
, size
, &x
, 1 );
704 export_gnutls_datum( dst
, size
, &y
, 1 );
706 *pubkey_len
= sizeof(*ecc_blob
) + ecc_blob
->cbKey
* 2;
708 free( x
.data
); free( y
.data
);
709 return STATUS_SUCCESS
;
712 static NTSTATUS
export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key
, ULONG bitlen
, void *pubkey
, ULONG
*pubkey_len
)
714 BCRYPT_DSA_KEY_BLOB
*dsa_blob
= pubkey
;
715 gnutls_datum_t p
, q
, g
, y
;
719 if ((ret
= pgnutls_privkey_export_dsa_raw( gnutls_key
, &p
, &q
, &g
, &y
, NULL
)))
721 pgnutls_perror( ret
);
722 return STATUS_INTERNAL_ERROR
;
727 FIXME( "bitlen > 1024 not supported\n" );
728 return STATUS_NOT_IMPLEMENTED
;
731 if (*pubkey_len
< sizeof(*dsa_blob
) + bitlen
/ 8 * 3)
733 FIXME( "wrong pubkey len %u / %u\n", *pubkey_len
, (ULONG
)sizeof(*dsa_blob
) + bitlen
/ 8 * 3 );
734 pgnutls_perror( ret
);
735 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
736 return STATUS_NO_MEMORY
;
739 dst
= (UCHAR
*)(dsa_blob
+ 1);
740 export_gnutls_datum( dst
, bitlen
/ 8, &p
, 1 );
743 export_gnutls_datum( dst
, bitlen
/ 8, &g
, 1 );
746 export_gnutls_datum( dst
, bitlen
/ 8, &y
, 1 );
749 export_gnutls_datum( dst
, sizeof(dsa_blob
->q
), &q
, 1 );
751 dsa_blob
->dwMagic
= BCRYPT_DSA_PUBLIC_MAGIC
;
752 dsa_blob
->cbKey
= bitlen
/ 8;
753 memset( dsa_blob
->Count
, 0, sizeof(dsa_blob
->Count
) ); /* FIXME */
754 memset( dsa_blob
->Seed
, 0, sizeof(dsa_blob
->Seed
) ); /* FIXME */
756 *pubkey_len
= sizeof(*dsa_blob
) + dsa_blob
->cbKey
* 3;
758 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
759 return STATUS_SUCCESS
;
762 static void reverse_bytes( UCHAR
*buf
, ULONG len
)
767 for (i
= 0; i
< len
/ 2; ++i
)
770 buf
[i
] = buf
[len
- i
- 1];
771 buf
[len
- i
- 1] = tmp
;
776 static NTSTATUS
export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key
, const DSSSEED
*seed
, ULONG bitlen
,
777 void *pubkey
, ULONG
*pubkey_len
)
779 BLOBHEADER
*hdr
= pubkey
;
781 gnutls_datum_t p
, q
, g
, y
;
783 int ret
, size
= sizeof(*hdr
) + sizeof(*dsskey
) + sizeof(*seed
);
787 FIXME( "bitlen > 1024 not supported\n" );
788 return STATUS_NOT_IMPLEMENTED
;
791 if ((ret
= pgnutls_privkey_export_dsa_raw( gnutls_key
, &p
, &q
, &g
, &y
, NULL
)))
793 pgnutls_perror( ret
);
794 return STATUS_INTERNAL_ERROR
;
797 if (*pubkey_len
< size
+ bitlen
/ 8 * 3 + Q_SIZE
)
799 FIXME( "wrong pubkey len %u / %u\n", *pubkey_len
, size
+ bitlen
/ 8 * 3 + Q_SIZE
);
800 pgnutls_perror( ret
);
801 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
802 return STATUS_NO_MEMORY
;
805 hdr
->bType
= PUBLICKEYBLOB
;
808 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
810 dsskey
= (DSSPUBKEY
*)(hdr
+ 1);
811 dsskey
->magic
= MAGIC_DSS1
;
812 dsskey
->bitlen
= bitlen
;
814 dst
= (UCHAR
*)(dsskey
+ 1);
815 export_gnutls_datum( dst
, bitlen
/ 8, &p
, 1 );
816 reverse_bytes( dst
, bitlen
/ 8 );
819 export_gnutls_datum( dst
, Q_SIZE
, &q
, 1 );
820 reverse_bytes( dst
, Q_SIZE
);
823 export_gnutls_datum( dst
, bitlen
/ 8, &g
, 1 );
824 reverse_bytes( dst
, bitlen
/ 8 );
827 export_gnutls_datum( dst
, bitlen
/ 8, &y
, 1 );
828 reverse_bytes( dst
, bitlen
/ 8 );
831 memcpy( dst
, seed
, sizeof(*seed
) );
833 *pubkey_len
= size
+ bitlen
/ 8 * 3 + Q_SIZE
;
835 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
836 return STATUS_SUCCESS
;
839 static NTSTATUS
key_asymmetric_generate( void *args
)
841 struct key
*key
= args
;
842 gnutls_pk_algorithm_t pk_alg
;
843 gnutls_privkey_t handle
;
848 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
853 case ALG_ID_RSA_SIGN
:
854 pk_alg
= GNUTLS_PK_RSA
;
855 bitlen
= key
->u
.a
.bitlen
;
859 pk_alg
= GNUTLS_PK_DSA
;
860 bitlen
= key
->u
.a
.bitlen
;
863 case ALG_ID_ECDH_P256
:
864 case ALG_ID_ECDSA_P256
:
865 pk_alg
= GNUTLS_PK_ECC
; /* compatible with ECDSA and ECDH */
866 bitlen
= GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1
);
870 FIXME( "algorithm %u not supported\n", key
->alg_id
);
871 return STATUS_NOT_SUPPORTED
;
874 if ((ret
= pgnutls_privkey_init( &handle
)))
876 pgnutls_perror( ret
);
877 return STATUS_INTERNAL_ERROR
;
880 if ((ret
= pgnutls_privkey_generate( handle
, pk_alg
, bitlen
, 0 )))
882 pgnutls_perror( ret
);
883 pgnutls_privkey_deinit( handle
);
884 return STATUS_INTERNAL_ERROR
;
890 status
= export_gnutls_pubkey_rsa( handle
, key
->u
.a
.bitlen
, key
->u
.a
.pubkey
, &key
->u
.a
.pubkey_len
);
894 status
= export_gnutls_pubkey_ecc( handle
, key
->alg_id
, key
->u
.a
.pubkey
, &key
->u
.a
.pubkey_len
);
898 status
= export_gnutls_pubkey_dsa( handle
, key
->u
.a
.bitlen
, key
->u
.a
.pubkey
, &key
->u
.a
.pubkey_len
);
902 ERR( "unhandled algorithm %u\n", pk_alg
);
903 return STATUS_INTERNAL_ERROR
;
908 pgnutls_privkey_deinit( handle
);
912 key_data(key
)->privkey
= handle
;
913 return STATUS_SUCCESS
;
916 static NTSTATUS
key_export_ecc( void *args
)
918 const struct key_export_params
*params
= args
;
919 struct key
*key
= params
->key
;
920 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
921 gnutls_ecc_curve_t curve
;
922 gnutls_datum_t x
, y
, d
;
929 case ALG_ID_ECDH_P256
:
930 magic
= BCRYPT_ECDH_PRIVATE_P256_MAGIC
;
933 case ALG_ID_ECDSA_P256
:
934 magic
= BCRYPT_ECDSA_PRIVATE_P256_MAGIC
;
939 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key
->alg_id
);
940 return STATUS_NOT_IMPLEMENTED
;
943 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key
)->privkey
, &curve
, &x
, &y
, &d
)))
945 pgnutls_perror( ret
);
946 return STATUS_INTERNAL_ERROR
;
949 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
)
951 FIXME( "curve %u not supported\n", curve
);
952 free( x
.data
); free( y
.data
); free( d
.data
);
953 return STATUS_NOT_IMPLEMENTED
;
956 *params
->ret_len
= sizeof(*ecc_blob
) + size
* 3;
957 if (params
->len
>= *params
->ret_len
&& params
->buf
)
959 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)params
->buf
;
960 ecc_blob
->dwMagic
= magic
;
961 ecc_blob
->cbKey
= size
;
963 dst
= (UCHAR
*)(ecc_blob
+ 1);
964 export_gnutls_datum( dst
, size
, &x
, 1 );
967 export_gnutls_datum( dst
, size
, &y
, 1 );
970 export_gnutls_datum( dst
, size
, &d
, 1 );
973 free( x
.data
); free( y
.data
); free( d
.data
);
974 return STATUS_SUCCESS
;
977 static NTSTATUS
key_import_ecc( void *args
)
979 const struct key_import_params
*params
= args
;
980 struct key
*key
= params
->key
;
981 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
982 gnutls_ecc_curve_t curve
;
983 gnutls_privkey_t handle
;
984 gnutls_datum_t x
, y
, k
;
990 case ALG_ID_ECDH_P256
:
991 case ALG_ID_ECDSA_P256
:
992 curve
= GNUTLS_ECC_CURVE_SECP256R1
;
996 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
997 return STATUS_NOT_IMPLEMENTED
;
1000 if ((ret
= pgnutls_privkey_init( &handle
)))
1002 pgnutls_perror( ret
);
1003 return STATUS_INTERNAL_ERROR
;
1006 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)params
->buf
;
1007 x
.data
= (unsigned char *)(ecc_blob
+ 1);
1008 x
.size
= ecc_blob
->cbKey
;
1009 y
.data
= x
.data
+ ecc_blob
->cbKey
;
1010 y
.size
= ecc_blob
->cbKey
;
1011 k
.data
= y
.data
+ ecc_blob
->cbKey
;
1012 k
.size
= ecc_blob
->cbKey
;
1014 if ((ret
= pgnutls_privkey_import_ecc_raw( handle
, curve
, &x
, &y
, &k
)))
1016 pgnutls_perror( ret
);
1017 pgnutls_privkey_deinit( handle
);
1018 return STATUS_INTERNAL_ERROR
;
1021 if ((status
= export_gnutls_pubkey_ecc( handle
, key
->alg_id
, key
->u
.a
.pubkey
, &key
->u
.a
.pubkey_len
)))
1023 pgnutls_privkey_deinit( handle
);
1027 key_data(key
)->privkey
= handle
;
1028 return STATUS_SUCCESS
;
1031 static NTSTATUS
key_export_rsa( void *args
)
1033 const struct key_export_params
*params
= args
;
1034 struct key
*key
= params
->key
;
1035 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1036 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
1037 ULONG bitlen
= key
->u
.a
.bitlen
;
1041 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key
)->privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
1043 pgnutls_perror( ret
);
1044 return STATUS_INTERNAL_ERROR
;
1047 *params
->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);
1048 if (params
->full
) *params
->ret_len
+= EXPORT_SIZE(e1
,16,1) + EXPORT_SIZE(e2
,16,1) + EXPORT_SIZE(u
,16,1) + EXPORT_SIZE(d
,8,1);
1050 if (params
->len
>= *params
->ret_len
&& params
->buf
)
1052 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)params
->buf
;
1053 rsa_blob
->Magic
= params
->full
? BCRYPT_RSAFULLPRIVATE_MAGIC
: BCRYPT_RSAPRIVATE_MAGIC
;
1054 rsa_blob
->BitLength
= bitlen
;
1056 dst
= (UCHAR
*)(rsa_blob
+ 1);
1057 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, bitlen
/ 8, &e
, 0 );
1059 dst
+= rsa_blob
->cbPublicExp
;
1060 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, bitlen
/ 8, &m
, 1 );
1062 dst
+= rsa_blob
->cbModulus
;
1063 rsa_blob
->cbPrime1
= export_gnutls_datum( dst
, bitlen
/ 16, &p
, 1 );
1065 dst
+= rsa_blob
->cbPrime1
;
1066 rsa_blob
->cbPrime2
= export_gnutls_datum( dst
, bitlen
/ 16, &q
, 1 );
1070 dst
+= rsa_blob
->cbPrime2
;
1071 export_gnutls_datum( dst
, bitlen
/ 16, &e1
, 1 );
1073 dst
+= rsa_blob
->cbPrime1
;
1074 export_gnutls_datum( dst
, bitlen
/ 16, &e2
, 1 );
1076 dst
+= rsa_blob
->cbPrime2
;
1077 export_gnutls_datum( dst
, bitlen
/ 16, &u
, 1 );
1079 dst
+= rsa_blob
->cbPrime1
;
1080 export_gnutls_datum( dst
, bitlen
/ 8, &d
, 1 );
1084 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
1085 free( e1
.data
); free( e2
.data
);
1086 return STATUS_SUCCESS
;
1089 static NTSTATUS
key_import_rsa( void *args
)
1091 const struct key_import_params
*params
= args
;
1092 BCRYPT_RSAKEY_BLOB
*rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)params
->buf
;
1093 gnutls_datum_t m
, e
, p
, q
;
1094 gnutls_privkey_t handle
;
1097 if ((ret
= pgnutls_privkey_init( &handle
)))
1099 pgnutls_perror( ret
);
1100 return STATUS_INTERNAL_ERROR
;
1103 e
.data
= (unsigned char *)(rsa_blob
+ 1);
1104 e
.size
= rsa_blob
->cbPublicExp
;
1105 m
.data
= e
.data
+ e
.size
;
1106 m
.size
= rsa_blob
->cbModulus
;
1107 p
.data
= m
.data
+ m
.size
;
1108 p
.size
= rsa_blob
->cbPrime1
;
1109 q
.data
= p
.data
+ p
.size
;
1110 q
.size
= rsa_blob
->cbPrime2
;
1112 if ((ret
= pgnutls_privkey_import_rsa_raw( handle
, &m
, &e
, NULL
, &p
, &q
, NULL
, NULL
, NULL
)))
1114 pgnutls_perror( ret
);
1115 pgnutls_privkey_deinit( handle
);
1116 return STATUS_INTERNAL_ERROR
;
1119 key_data(params
->key
)->privkey
= handle
;
1120 return STATUS_SUCCESS
;
1123 static NTSTATUS
key_export_dsa_capi( void *args
)
1125 const struct key_export_params
*params
= args
;
1126 struct key
*key
= params
->key
;
1129 gnutls_datum_t p
, q
, g
, y
, x
;
1133 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->privkey
, &p
, &q
, &g
, &y
, &x
)))
1135 pgnutls_perror( ret
);
1136 return STATUS_INTERNAL_ERROR
;
1139 if (q
.size
> 21 || x
.size
> 21)
1141 ERR( "can't export key in this format\n" );
1142 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1143 return STATUS_NOT_SUPPORTED
;
1146 size
= key
->u
.a
.bitlen
/ 8;
1147 *params
->ret_len
= sizeof(*hdr
) + sizeof(*pubkey
) + size
* 2 + 40 + sizeof(key
->u
.a
.dss_seed
);
1148 if (params
->len
>= *params
->ret_len
&& params
->buf
)
1150 hdr
= (BLOBHEADER
*)params
->buf
;
1151 hdr
->bType
= PRIVATEKEYBLOB
;
1154 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
1156 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1157 pubkey
->magic
= MAGIC_DSS2
;
1158 pubkey
->bitlen
= key
->u
.a
.bitlen
;
1160 dst
= (UCHAR
*)(pubkey
+ 1);
1161 export_gnutls_datum( dst
, size
, &p
, 1 );
1162 reverse_bytes( dst
, size
);
1165 export_gnutls_datum( dst
, 20, &q
, 1 );
1166 reverse_bytes( dst
, 20 );
1169 export_gnutls_datum( dst
, size
, &g
, 1 );
1170 reverse_bytes( dst
, size
);
1173 export_gnutls_datum( dst
, 20, &x
, 1 );
1174 reverse_bytes( dst
, 20 );
1177 memcpy( dst
, &key
->u
.a
.dss_seed
, sizeof(key
->u
.a
.dss_seed
) );
1180 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1181 return STATUS_SUCCESS
;
1184 static NTSTATUS
key_import_dsa_capi( void *args
)
1186 const struct key_import_params
*params
= args
;
1187 struct key
*key
= params
->key
;
1188 BLOBHEADER
*hdr
= (BLOBHEADER
*)params
->buf
;
1190 gnutls_privkey_t handle
;
1191 gnutls_datum_t p
, q
, g
, y
, x
;
1192 unsigned char dummy
[128];
1193 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], x_data
[20];
1197 if ((ret
= pgnutls_privkey_init( &handle
)))
1199 pgnutls_perror( ret
);
1200 return STATUS_INTERNAL_ERROR
;
1203 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1204 if ((size
= pubkey
->bitlen
/ 8) > sizeof(p_data
))
1206 FIXME( "size %u not supported\n", size
);
1207 pgnutls_privkey_deinit( handle
);
1208 return STATUS_NOT_SUPPORTED
;
1210 data
= (unsigned char *)(pubkey
+ 1);
1214 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1218 q
.size
= sizeof(q_data
);
1219 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1224 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1228 x
.size
= sizeof(x_data
);
1229 for (i
= 0; i
< x
.size
; i
++) x
.data
[i
] = data
[x
.size
- i
- 1];
1232 WARN( "using dummy public key\n" );
1233 memset( dummy
, 1, sizeof(dummy
) );
1235 y
.size
= min( p
.size
, sizeof(dummy
) );
1237 if ((ret
= pgnutls_privkey_import_dsa_raw( handle
, &p
, &q
, &g
, &y
, &x
)))
1239 pgnutls_perror( ret
);
1240 pgnutls_privkey_deinit( handle
);
1241 return STATUS_INTERNAL_ERROR
;
1244 if ((status
= export_gnutls_pubkey_dsa_capi( handle
, &key
->u
.a
.dss_seed
, key
->u
.a
.bitlen
,
1245 key
->u
.a
.pubkey
, &key
->u
.a
.pubkey_len
)))
1247 pgnutls_privkey_deinit( handle
);
1251 memcpy( &key
->u
.a
.dss_seed
, data
, sizeof(key
->u
.a
.dss_seed
) );
1253 key
->u
.a
.flags
|= KEY_FLAG_LEGACY_DSA_V2
;
1254 key_data(key
)->privkey
= handle
;
1256 return STATUS_SUCCESS
;
1259 static NTSTATUS
import_gnutls_pubkey_ecc( struct key
*key
, gnutls_pubkey_t
*gnutls_key
)
1261 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1262 gnutls_ecc_curve_t curve
;
1263 gnutls_datum_t x
, y
;
1266 switch (key
->alg_id
)
1268 case ALG_ID_ECDSA_P256
: curve
= GNUTLS_ECC_CURVE_SECP256R1
; break;
1269 case ALG_ID_ECDSA_P384
: curve
= GNUTLS_ECC_CURVE_SECP384R1
; break;
1272 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1273 return STATUS_NOT_IMPLEMENTED
;
1276 if ((ret
= pgnutls_pubkey_init( gnutls_key
)))
1278 pgnutls_perror( ret
);
1279 return STATUS_INTERNAL_ERROR
;
1282 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)key
->u
.a
.pubkey
;
1283 x
.data
= key
->u
.a
.pubkey
+ sizeof(*ecc_blob
);
1284 x
.size
= ecc_blob
->cbKey
;
1285 y
.data
= key
->u
.a
.pubkey
+ sizeof(*ecc_blob
) + ecc_blob
->cbKey
;
1286 y
.size
= ecc_blob
->cbKey
;
1288 if ((ret
= pgnutls_pubkey_import_ecc_raw( *gnutls_key
, curve
, &x
, &y
)))
1290 pgnutls_perror( ret
);
1291 pgnutls_pubkey_deinit( *gnutls_key
);
1292 return STATUS_INTERNAL_ERROR
;
1295 return STATUS_SUCCESS
;
1298 static NTSTATUS
import_gnutls_pubkey_rsa( struct key
*key
, gnutls_pubkey_t
*gnutls_key
)
1300 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1301 gnutls_datum_t m
, e
;
1304 if ((ret
= pgnutls_pubkey_init( gnutls_key
)))
1306 pgnutls_perror( ret
);
1307 return STATUS_INTERNAL_ERROR
;
1310 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)key
->u
.a
.pubkey
;
1311 e
.data
= key
->u
.a
.pubkey
+ sizeof(*rsa_blob
);
1312 e
.size
= rsa_blob
->cbPublicExp
;
1313 m
.data
= key
->u
.a
.pubkey
+ sizeof(*rsa_blob
) + rsa_blob
->cbPublicExp
;
1314 m
.size
= rsa_blob
->cbModulus
;
1316 if ((ret
= pgnutls_pubkey_import_rsa_raw( *gnutls_key
, &m
, &e
)))
1318 pgnutls_perror( ret
);
1319 pgnutls_pubkey_deinit( *gnutls_key
);
1320 return STATUS_INTERNAL_ERROR
;
1323 return STATUS_SUCCESS
;
1326 static NTSTATUS
import_gnutls_pubkey_dsa( struct key
*key
, gnutls_pubkey_t
*gnutls_key
)
1328 BCRYPT_DSA_KEY_BLOB
*dsa_blob
;
1329 gnutls_datum_t p
, q
, g
, y
;
1332 if ((ret
= pgnutls_pubkey_init( gnutls_key
)))
1334 pgnutls_perror( ret
);
1335 return STATUS_INTERNAL_ERROR
;
1338 dsa_blob
= (BCRYPT_DSA_KEY_BLOB
*)key
->u
.a
.pubkey
;
1339 p
.data
= key
->u
.a
.pubkey
+ sizeof(*dsa_blob
);
1340 p
.size
= dsa_blob
->cbKey
;
1341 q
.data
= dsa_blob
->q
;
1342 q
.size
= sizeof(dsa_blob
->q
);
1343 g
.data
= key
->u
.a
.pubkey
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
;
1344 g
.size
= dsa_blob
->cbKey
;
1345 y
.data
= key
->u
.a
.pubkey
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
* 2;
1346 y
.size
= dsa_blob
->cbKey
;
1348 if ((ret
= pgnutls_pubkey_import_dsa_raw( *gnutls_key
, &p
, &q
, &g
, &y
)))
1350 pgnutls_perror( ret
);
1351 pgnutls_pubkey_deinit( *gnutls_key
);
1352 return STATUS_INTERNAL_ERROR
;
1355 return STATUS_SUCCESS
;
1358 static NTSTATUS
import_gnutls_pubkey_dsa_capi( struct key
*key
, gnutls_pubkey_t
*gnutls_key
)
1362 gnutls_datum_t p
, q
, g
, y
;
1363 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], y_data
[128];
1366 if ((ret
= pgnutls_pubkey_init( gnutls_key
)))
1368 pgnutls_perror( ret
);
1369 return STATUS_INTERNAL_ERROR
;
1372 hdr
= (BLOBHEADER
*)key
->u
.a
.pubkey
;
1373 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1374 size
= pubkey
->bitlen
/ 8;
1375 data
= (unsigned char *)(pubkey
+ 1);
1379 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1383 q
.size
= sizeof(q_data
);
1384 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1389 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1393 y
.size
= sizeof(y_data
);
1394 for (i
= 0; i
< y
.size
; i
++) y
.data
[i
] = data
[y
.size
- i
- 1];
1396 if ((ret
= pgnutls_pubkey_import_dsa_raw( *gnutls_key
, &p
, &q
, &g
, &y
)))
1398 pgnutls_perror( ret
);
1399 pgnutls_pubkey_deinit( *gnutls_key
);
1400 return STATUS_INTERNAL_ERROR
;
1403 return STATUS_SUCCESS
;
1406 static NTSTATUS
import_gnutls_pubkey( struct key
*key
, gnutls_pubkey_t
*gnutls_key
)
1408 switch (key
->alg_id
)
1410 case ALG_ID_ECDSA_P256
:
1411 case ALG_ID_ECDSA_P384
:
1412 return import_gnutls_pubkey_ecc( key
, gnutls_key
);
1415 case ALG_ID_RSA_SIGN
:
1416 return import_gnutls_pubkey_rsa( key
, gnutls_key
);
1419 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1420 return import_gnutls_pubkey_dsa_capi( key
, gnutls_key
);
1422 return import_gnutls_pubkey_dsa( key
, gnutls_key
);
1425 FIXME("algorithm %u not yet supported\n", key
->alg_id
);
1426 return STATUS_NOT_IMPLEMENTED
;
1430 static NTSTATUS
prepare_gnutls_signature_dsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1431 gnutls_datum_t
*gnutls_signature
)
1433 struct buffer buffer
;
1434 DWORD r_len
= signature_len
/ 2;
1435 DWORD s_len
= r_len
;
1436 BYTE
*r
= signature
;
1437 BYTE
*s
= signature
+ r_len
;
1439 buffer_init( &buffer
);
1440 buffer_append_asn1_r_s( &buffer
, r
, r_len
, s
, s_len
);
1443 buffer_free( &buffer
);
1444 return STATUS_NO_MEMORY
;
1447 gnutls_signature
->data
= buffer
.buffer
;
1448 gnutls_signature
->size
= buffer
.pos
;
1449 return STATUS_SUCCESS
;
1452 static NTSTATUS
prepare_gnutls_signature_rsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1453 gnutls_datum_t
*gnutls_signature
)
1455 gnutls_signature
->data
= signature
;
1456 gnutls_signature
->size
= signature_len
;
1457 return STATUS_SUCCESS
;
1460 static NTSTATUS
prepare_gnutls_signature( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1461 gnutls_datum_t
*gnutls_signature
)
1463 switch (key
->alg_id
)
1465 case ALG_ID_ECDSA_P256
:
1466 case ALG_ID_ECDSA_P384
:
1468 return prepare_gnutls_signature_dsa( key
, signature
, signature_len
, gnutls_signature
);
1471 case ALG_ID_RSA_SIGN
:
1472 return prepare_gnutls_signature_rsa( key
, signature
, signature_len
, gnutls_signature
);
1475 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1476 return STATUS_NOT_IMPLEMENTED
;
1480 static gnutls_digest_algorithm_t
get_digest_from_id( const WCHAR
*alg_id
)
1482 if (!wcscmp( alg_id
, BCRYPT_SHA1_ALGORITHM
)) return GNUTLS_DIG_SHA1
;
1483 if (!wcscmp( alg_id
, BCRYPT_SHA256_ALGORITHM
)) return GNUTLS_DIG_SHA256
;
1484 if (!wcscmp( alg_id
, BCRYPT_SHA384_ALGORITHM
)) return GNUTLS_DIG_SHA384
;
1485 if (!wcscmp( alg_id
, BCRYPT_SHA512_ALGORITHM
)) return GNUTLS_DIG_SHA512
;
1486 if (!wcscmp( alg_id
, BCRYPT_MD2_ALGORITHM
)) return GNUTLS_DIG_MD2
;
1487 if (!wcscmp( alg_id
, BCRYPT_MD5_ALGORITHM
)) return GNUTLS_DIG_MD5
;
1491 static NTSTATUS
key_asymmetric_verify( void *args
)
1493 const struct key_asymmetric_verify_params
*params
= args
;
1494 struct key
*key
= params
->key
;
1495 ULONG flags
= params
->flags
;
1496 gnutls_digest_algorithm_t hash_alg
;
1497 gnutls_sign_algorithm_t sign_alg
;
1498 gnutls_datum_t gnutls_hash
, gnutls_signature
;
1499 gnutls_pk_algorithm_t pk_alg
;
1500 gnutls_pubkey_t gnutls_key
;
1504 switch (key
->alg_id
)
1506 case ALG_ID_ECDSA_P256
:
1507 case ALG_ID_ECDSA_P384
:
1509 if (flags
) FIXME( "flags %08x not supported\n", flags
);
1511 /* only the hash size must match, not the actual hash function */
1512 switch (params
->hash_len
)
1514 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1515 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1516 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1519 FIXME( "hash size %u not yet supported\n", params
->hash_len
);
1520 return STATUS_INVALID_SIGNATURE
;
1522 pk_alg
= GNUTLS_PK_ECC
;
1526 case ALG_ID_RSA_SIGN
:
1528 BCRYPT_PKCS1_PADDING_INFO
*info
= params
->padding
;
1530 if (!(flags
& BCRYPT_PAD_PKCS1
) || !info
) return STATUS_INVALID_PARAMETER
;
1531 if (!info
->pszAlgId
) return STATUS_INVALID_SIGNATURE
;
1533 if ((hash_alg
= get_digest_from_id(info
->pszAlgId
)) == -1)
1535 FIXME( "hash algorithm %s not supported\n", debugstr_w(info
->pszAlgId
) );
1536 return STATUS_NOT_SUPPORTED
;
1538 pk_alg
= GNUTLS_PK_RSA
;
1543 if (flags
) FIXME( "flags %08x not supported\n", flags
);
1544 if (params
->hash_len
!= 20)
1546 FIXME( "hash size %u not supported\n", params
->hash_len
);
1547 return STATUS_INVALID_PARAMETER
;
1549 hash_alg
= GNUTLS_DIG_SHA1
;
1550 pk_alg
= GNUTLS_PK_DSA
;
1554 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1555 return STATUS_NOT_IMPLEMENTED
;
1558 if ((sign_alg
= pgnutls_pk_to_sign( pk_alg
, hash_alg
)) == GNUTLS_SIGN_UNKNOWN
)
1560 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key
->alg_id
, params
->hash_len
);
1561 return STATUS_NOT_IMPLEMENTED
;
1564 if ((status
= import_gnutls_pubkey( key
, &gnutls_key
))) return status
;
1565 if ((status
= prepare_gnutls_signature( key
, params
->signature
, params
->signature_len
, &gnutls_signature
)))
1567 pgnutls_pubkey_deinit( gnutls_key
);
1571 gnutls_hash
.data
= params
->hash
;
1572 gnutls_hash
.size
= params
->hash_len
;
1573 ret
= pgnutls_pubkey_verify_hash2( gnutls_key
, sign_alg
, 0, &gnutls_hash
, &gnutls_signature
);
1575 if (gnutls_signature
.data
!= params
->signature
) free( gnutls_signature
.data
);
1576 pgnutls_pubkey_deinit( gnutls_key
);
1577 return (ret
< 0) ? STATUS_INVALID_SIGNATURE
: STATUS_SUCCESS
;
1580 static unsigned int get_signature_length( enum alg_id id
)
1584 case ALG_ID_ECDSA_P256
: return 64;
1585 case ALG_ID_ECDSA_P384
: return 96;
1586 case ALG_ID_DSA
: return 40;
1588 FIXME( "unhandled algorithm %u\n", id
);
1593 static NTSTATUS
format_gnutls_signature( enum alg_id type
, gnutls_datum_t signature
,
1594 UCHAR
*output
, ULONG output_len
, ULONG
*ret_len
)
1599 case ALG_ID_RSA_SIGN
:
1601 *ret_len
= signature
.size
;
1602 if (output_len
< signature
.size
) return STATUS_BUFFER_TOO_SMALL
;
1603 if (output
) memcpy( output
, signature
.data
, signature
.size
);
1604 return STATUS_SUCCESS
;
1606 case ALG_ID_ECDSA_P256
:
1607 case ALG_ID_ECDSA_P384
:
1611 unsigned int sig_len
= get_signature_length( type
);
1612 gnutls_datum_t r
, s
; /* format as r||s */
1614 if ((err
= pgnutls_decode_rs_value( &signature
, &r
, &s
)))
1616 pgnutls_perror( err
);
1617 return STATUS_INTERNAL_ERROR
;
1621 if (output_len
< sig_len
) return STATUS_BUFFER_TOO_SMALL
;
1623 if (r
.size
> sig_len
/ 2 + 1 || s
.size
> sig_len
/ 2 + 1)
1625 ERR( "we didn't get a correct signature\n" );
1626 return STATUS_INTERNAL_ERROR
;
1631 export_gnutls_datum( output
, sig_len
/ 2, &r
, 1 );
1632 export_gnutls_datum( output
+ sig_len
/ 2, sig_len
/ 2, &s
, 1 );
1635 free( r
.data
); free( s
.data
);
1636 return STATUS_SUCCESS
;
1639 return STATUS_INTERNAL_ERROR
;
1643 static NTSTATUS
key_asymmetric_sign( void *args
)
1645 const struct key_asymmetric_sign_params
*params
= args
;
1646 struct key
*key
= params
->key
;
1647 ULONG flags
= params
->flags
;
1648 BCRYPT_PKCS1_PADDING_INFO
*pad
= params
->padding
;
1649 gnutls_datum_t hash
, signature
;
1650 gnutls_digest_algorithm_t hash_alg
;
1654 if (key
->alg_id
== ALG_ID_ECDSA_P256
|| key
->alg_id
== ALG_ID_ECDSA_P384
)
1656 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1657 switch (params
->input_len
)
1659 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1660 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1661 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1662 case 64: hash_alg
= GNUTLS_DIG_SHA512
; break;
1665 FIXME( "hash size %u not yet supported\n", params
->input_len
);
1666 return STATUS_INVALID_PARAMETER
;
1669 if (flags
== BCRYPT_PAD_PKCS1
&& pad
&& pad
->pszAlgId
&& get_digest_from_id( pad
->pszAlgId
) != hash_alg
)
1671 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad
->pszAlgId
), hash_alg
);
1672 return STATUS_INVALID_PARAMETER
;
1675 else if (key
->alg_id
== ALG_ID_DSA
)
1677 if (flags
) FIXME( "flags %08x not supported\n", flags
);
1678 if (params
->input_len
!= 20)
1680 FIXME( "hash size %u not supported\n", params
->input_len
);
1681 return STATUS_INVALID_PARAMETER
;
1683 hash_alg
= GNUTLS_DIG_SHA1
;
1685 else if (flags
== BCRYPT_PAD_PKCS1
)
1687 if (!pad
|| !pad
->pszAlgId
)
1689 WARN( "padding info not found\n" );
1690 return STATUS_INVALID_PARAMETER
;
1693 if ((hash_alg
= get_digest_from_id( pad
->pszAlgId
)) == -1)
1695 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad
->pszAlgId
) );
1696 return STATUS_NOT_SUPPORTED
;
1701 WARN( "invalid flags %08x\n", flags
);
1702 return STATUS_INVALID_PARAMETER
;
1706 FIXME( "flags %08x not implemented\n", flags
);
1707 return STATUS_NOT_IMPLEMENTED
;
1712 *params
->ret_len
= key
->u
.a
.bitlen
/ 8;
1713 return STATUS_SUCCESS
;
1715 if (!key_data(key
)->privkey
) return STATUS_INVALID_PARAMETER
;
1717 hash
.data
= params
->input
;
1718 hash
.size
= params
->input_len
;
1720 signature
.data
= NULL
;
1723 if ((ret
= pgnutls_privkey_sign_hash( key_data(key
)->privkey
, hash_alg
, 0, &hash
, &signature
)))
1725 pgnutls_perror( ret
);
1726 return STATUS_INTERNAL_ERROR
;
1729 status
= format_gnutls_signature( key
->alg_id
, signature
, params
->output
,
1730 params
->output_len
, params
->ret_len
);
1732 free( signature
.data
);
1736 static NTSTATUS
key_asymmetric_destroy( void *args
)
1738 struct key
*key
= args
;
1740 if (key_data(key
)->privkey
) pgnutls_privkey_deinit( key_data(key
)->privkey
);
1741 return STATUS_SUCCESS
;
1744 static NTSTATUS
key_asymmetric_duplicate( void *args
)
1746 const struct key_asymmetric_duplicate_params
*params
= args
;
1747 struct key
*key_orig
= params
->key_orig
;
1748 struct key
*key_copy
= params
->key_copy
;
1751 if (!key_data(key_orig
)->privkey
) return STATUS_SUCCESS
;
1753 if ((ret
= pgnutls_privkey_init( &key_data(key_copy
)->privkey
)))
1755 pgnutls_perror( ret
);
1756 return STATUS_INTERNAL_ERROR
;
1759 switch (key_orig
->alg_id
)
1762 case ALG_ID_RSA_SIGN
:
1764 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
1765 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key_orig
)->privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
1767 pgnutls_perror( ret
);
1768 return STATUS_INTERNAL_ERROR
;
1770 ret
= pgnutls_privkey_import_rsa_raw( key_data(key_copy
)->privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
);
1771 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
1772 free( e1
.data
); free( e2
.data
);
1775 pgnutls_perror( ret
);
1776 return STATUS_INTERNAL_ERROR
;
1782 gnutls_datum_t p
, q
, g
, y
, x
;
1783 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key_orig
)->privkey
, &p
, &q
, &g
, &y
, &x
)))
1785 pgnutls_perror( ret
);
1786 return STATUS_INTERNAL_ERROR
;
1788 ret
= pgnutls_privkey_import_dsa_raw( key_data(key_copy
)->privkey
, &p
, &q
, &g
, &y
, &x
);
1789 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1792 pgnutls_perror( ret
);
1793 return STATUS_INTERNAL_ERROR
;
1797 case ALG_ID_ECDH_P256
:
1798 case ALG_ID_ECDSA_P256
:
1799 case ALG_ID_ECDSA_P384
:
1801 gnutls_ecc_curve_t curve
;
1802 gnutls_datum_t x
, y
, k
;
1803 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key_orig
)->privkey
, &curve
, &x
, &y
, &k
)))
1805 pgnutls_perror( ret
);
1806 return STATUS_INTERNAL_ERROR
;
1808 ret
= pgnutls_privkey_import_ecc_raw( key_data(key_copy
)->privkey
, curve
, &x
, &y
, &k
);
1809 free( x
.data
); free( y
.data
); free( k
.data
);
1812 pgnutls_perror( ret
);
1813 return STATUS_INTERNAL_ERROR
;
1818 ERR( "unhandled algorithm %u\n", key_orig
->alg_id
);
1819 return STATUS_INTERNAL_ERROR
;
1822 return STATUS_SUCCESS
;
1825 static NTSTATUS
key_asymmetric_decrypt( void *args
)
1827 const struct key_asymmetric_decrypt_params
*params
= args
;
1828 gnutls_datum_t e
, d
= { 0 };
1829 NTSTATUS status
= STATUS_SUCCESS
;
1832 e
.data
= params
->input
;
1833 e
.size
= params
->input_len
;
1834 if ((ret
= pgnutls_privkey_decrypt_data( key_data(params
->key
)->privkey
, 0, &e
, &d
)))
1836 pgnutls_perror( ret
);
1837 return STATUS_INTERNAL_ERROR
;
1840 *params
->ret_len
= d
.size
;
1841 if (params
->output_len
>= d
.size
) memcpy( params
->output
, d
.data
, *params
->ret_len
);
1842 else status
= STATUS_BUFFER_TOO_SMALL
;
1848 const unixlib_entry_t __wine_unix_call_funcs
[] =
1850 gnutls_process_attach
,
1851 gnutls_process_detach
,
1852 key_symmetric_vector_reset
,
1853 key_symmetric_set_auth_data
,
1854 key_symmetric_encrypt
,
1855 key_symmetric_decrypt
,
1856 key_symmetric_get_tag
,
1857 key_symmetric_destroy
,
1858 key_asymmetric_generate
,
1859 key_asymmetric_decrypt
,
1860 key_asymmetric_duplicate
,
1861 key_asymmetric_sign
,
1862 key_asymmetric_verify
,
1863 key_asymmetric_destroy
,
1864 key_export_dsa_capi
,
1867 key_import_dsa_capi
,
1874 typedef ULONG PTR32
;
1876 struct key_symmetric32
1887 struct key_asymmetric32
1889 ULONG bitlen
; /* ignored for ECC keys */
1900 UINT64
private[2]; /* private data for backend */
1903 struct key_symmetric32 s
;
1904 struct key_asymmetric32 a
;
1908 static struct key
*get_symmetric_key( struct key32
*key32
, struct key
*key
)
1910 key
->hdr
= key32
->hdr
;
1911 key
->alg_id
= key32
->alg_id
;
1912 key
->private[0] = key32
->private[0];
1913 key
->private[1] = key32
->private[1];
1914 key
->u
.s
.mode
= key32
->u
.s
.mode
;
1915 key
->u
.s
.block_size
= key32
->u
.s
.block_size
;
1916 key
->u
.s
.vector
= ULongToPtr(key32
->u
.s
.vector
);
1917 key
->u
.s
.vector_len
= key32
->u
.s
.vector_len
;
1918 key
->u
.s
.secret
= ULongToPtr(key32
->u
.s
.secret
);
1919 key
->u
.s
.secret_len
= key32
->u
.s
.secret_len
;
1923 static struct key
*get_asymmetric_key( struct key32
*key32
, struct key
*key
)
1925 key
->hdr
= key32
->hdr
;
1926 key
->alg_id
= key32
->alg_id
;
1927 key
->private[0] = key32
->private[0];
1928 key
->private[1] = key32
->private[1];
1929 key
->u
.a
.bitlen
= key32
->u
.a
.bitlen
;
1930 key
->u
.a
.flags
= key32
->u
.a
.flags
;
1931 key
->u
.a
.pubkey
= ULongToPtr(key32
->u
.a
.pubkey
);
1932 key
->u
.a
.pubkey_len
= key32
->u
.a
.pubkey_len
;
1933 key
->u
.a
.dss_seed
= key32
->u
.a
.dss_seed
;
1937 static void put_symmetric_key32( struct key
*key
, struct key32
*key32
)
1939 key32
->private[0] = key
->private[0];
1940 key32
->private[1] = key
->private[1];
1943 static void put_asymmetric_key32( struct key
*key
, struct key32
*key32
)
1945 key32
->private[0] = key
->private[0];
1946 key32
->private[1] = key
->private[1];
1947 key32
->u
.a
.flags
= key
->u
.a
.flags
;
1948 key32
->u
.a
.pubkey_len
= key
->u
.a
.pubkey_len
;
1949 key32
->u
.a
.dss_seed
= key
->u
.a
.dss_seed
;
1952 static NTSTATUS
wow64_key_symmetric_vector_reset( void *args
)
1956 struct key32
*key32
= args
;
1958 ret
= key_symmetric_vector_reset( get_symmetric_key( key32
, &key
));
1959 put_symmetric_key32( &key
, key32
);
1963 static NTSTATUS
wow64_key_symmetric_set_auth_data( void *args
)
1970 } const *params32
= args
;
1974 struct key32
*key32
= ULongToPtr( params32
->key
);
1975 struct key_symmetric_set_auth_data_params params
=
1977 get_symmetric_key( key32
, &key
),
1978 ULongToPtr(params32
->auth_data
),
1982 ret
= key_symmetric_set_auth_data( ¶ms
);
1983 put_symmetric_key32( &key
, key32
);
1987 static NTSTATUS
wow64_key_symmetric_encrypt( void *args
)
1996 } const *params32
= args
;
2000 struct key32
*key32
= ULongToPtr( params32
->key
);
2001 struct key_symmetric_encrypt_params params
=
2003 get_symmetric_key( key32
, &key
),
2004 ULongToPtr(params32
->input
),
2005 params32
->input_len
,
2006 ULongToPtr(params32
->output
),
2007 params32
->output_len
2010 ret
= key_symmetric_encrypt( ¶ms
);
2011 put_symmetric_key32( &key
, key32
);
2015 static NTSTATUS
wow64_key_symmetric_decrypt( void *args
)
2024 } const *params32
= args
;
2028 struct key32
*key32
= ULongToPtr( params32
->key
);
2029 struct key_symmetric_decrypt_params params
=
2031 get_symmetric_key( key32
, &key
),
2032 ULongToPtr(params32
->input
),
2033 params32
->input_len
,
2034 ULongToPtr(params32
->output
),
2035 params32
->output_len
2038 ret
= key_symmetric_decrypt( ¶ms
);
2039 put_symmetric_key32( &key
, key32
);
2043 static NTSTATUS
wow64_key_symmetric_get_tag( void *args
)
2050 } const *params32
= args
;
2054 struct key32
*key32
= ULongToPtr( params32
->key
);
2055 struct key_symmetric_get_tag_params params
=
2057 get_symmetric_key( key32
, &key
),
2058 ULongToPtr(params32
->tag
),
2062 ret
= key_symmetric_get_tag( ¶ms
);
2063 put_symmetric_key32( &key
, key32
);
2067 static NTSTATUS
wow64_key_symmetric_destroy( void *args
)
2069 struct key32
*key32
= args
;
2072 return key_symmetric_destroy( get_symmetric_key( key32
, &key
));
2075 static NTSTATUS
wow64_key_asymmetric_generate( void *args
)
2077 struct key32
*key32
= args
;
2081 ret
= key_asymmetric_generate( get_asymmetric_key( key32
, &key
));
2082 put_asymmetric_key32( &key
, key32
);
2086 static NTSTATUS
wow64_key_asymmetric_decrypt( void *args
)
2096 } const *params32
= args
;
2100 struct key32
*key32
= ULongToPtr( params32
->key
);
2101 struct key_asymmetric_decrypt_params params
=
2103 get_asymmetric_key( key32
, &key
),
2104 ULongToPtr(params32
->input
),
2105 params32
->input_len
,
2106 ULongToPtr(params32
->output
),
2107 params32
->output_len
,
2108 ULongToPtr(params32
->ret_len
)
2111 ret
= key_asymmetric_decrypt( ¶ms
);
2112 put_asymmetric_key32( &key
, key32
);
2116 static NTSTATUS
wow64_key_asymmetric_duplicate( void *args
)
2122 } const *params32
= args
;
2125 struct key key_orig
, key_copy
;
2126 struct key32
*key_orig32
= ULongToPtr( params32
->key_orig
);
2127 struct key32
*key_copy32
= ULongToPtr( params32
->key_copy
);
2128 struct key_asymmetric_duplicate_params params
=
2130 get_asymmetric_key( key_orig32
, &key_orig
),
2131 get_asymmetric_key( key_copy32
, &key_copy
)
2134 ret
= key_asymmetric_duplicate( ¶ms
);
2135 put_asymmetric_key32( &key_copy
, key_copy32
);
2139 static NTSTATUS
wow64_key_asymmetric_sign( void *args
)
2151 } const *params32
= args
;
2155 BCRYPT_PKCS1_PADDING_INFO padding
;
2156 struct key32
*key32
= ULongToPtr( params32
->key
);
2157 struct key_asymmetric_sign_params params
=
2159 get_asymmetric_key( key32
, &key
),
2161 ULongToPtr(params32
->input
),
2162 params32
->input_len
,
2163 ULongToPtr(params32
->output
),
2164 params32
->output_len
,
2165 ULongToPtr(params32
->ret_len
),
2169 if (params32
->flags
& BCRYPT_PAD_PKCS1
)
2171 PTR32
*info
= ULongToPtr( params32
->padding
);
2172 if (!info
) return STATUS_INVALID_PARAMETER
;
2173 padding
.pszAlgId
= ULongToPtr( *info
);
2174 params
.padding
= &padding
;
2177 ret
= key_asymmetric_sign( ¶ms
);
2178 put_asymmetric_key32( &key
, key32
);
2182 static NTSTATUS
wow64_key_asymmetric_verify( void *args
)
2191 ULONG signature_len
;
2193 } const *params32
= args
;
2197 BCRYPT_PKCS1_PADDING_INFO padding
;
2198 struct key32
*key32
= ULongToPtr( params32
->key
);
2199 struct key_asymmetric_verify_params params
=
2201 get_asymmetric_key( key32
, &key
),
2203 ULongToPtr(params32
->hash
),
2205 ULongToPtr(params32
->signature
),
2206 params32
->signature_len
,
2210 if (params32
->flags
& BCRYPT_PAD_PKCS1
)
2212 PTR32
*info
= ULongToPtr( params32
->padding
);
2213 if (!info
) return STATUS_INVALID_PARAMETER
;
2214 padding
.pszAlgId
= ULongToPtr( *info
);
2215 params
.padding
= &padding
;
2218 ret
= key_asymmetric_verify( ¶ms
);
2219 put_asymmetric_key32( &key
, key32
);
2223 static NTSTATUS
wow64_key_asymmetric_destroy( void *args
)
2225 struct key32
*key32
= args
;
2228 return key_asymmetric_destroy( get_asymmetric_key( key32
, &key
));
2231 static NTSTATUS
wow64_key_export_dsa_capi( void *args
)
2239 } const *params32
= args
;
2243 struct key32
*key32
= ULongToPtr( params32
->key
);
2244 struct key_export_params params
=
2246 get_asymmetric_key( key32
, &key
),
2247 ULongToPtr(params32
->buf
),
2249 ULongToPtr(params32
->ret_len
)
2252 ret
= key_export_dsa_capi( ¶ms
);
2253 put_asymmetric_key32( &key
, key32
);
2257 static NTSTATUS
wow64_key_export_ecc( void *args
)
2265 } const *params32
= args
;
2269 struct key32
*key32
= ULongToPtr( params32
->key
);
2270 struct key_export_params params
=
2272 get_asymmetric_key( key32
, &key
),
2273 ULongToPtr(params32
->buf
),
2275 ULongToPtr(params32
->ret_len
)
2278 ret
= key_export_ecc( ¶ms
);
2279 put_asymmetric_key32( &key
, key32
);
2283 static NTSTATUS
wow64_key_import_dsa_capi( void *args
)
2290 } const *params32
= args
;
2294 struct key32
*key32
= ULongToPtr( params32
->key
);
2295 struct key_import_params params
=
2297 get_asymmetric_key( key32
, &key
),
2298 ULongToPtr(params32
->buf
),
2302 ret
= key_import_dsa_capi( ¶ms
);
2303 put_asymmetric_key32( &key
, key32
);
2307 static NTSTATUS
wow64_key_import_ecc( void *args
)
2314 } const *params32
= args
;
2318 struct key32
*key32
= ULongToPtr( params32
->key
);
2319 struct key_import_params params
=
2321 get_asymmetric_key( key32
, &key
),
2322 ULongToPtr(params32
->buf
),
2326 ret
= key_import_ecc( ¶ms
);
2327 put_asymmetric_key32( &key
, key32
);
2331 static NTSTATUS
wow64_key_export_rsa( void *args
)
2340 } const *params32
= args
;
2344 struct key32
*key32
= ULongToPtr( params32
->key
);
2345 struct key_export_params params
=
2347 get_asymmetric_key( key32
, &key
),
2348 ULongToPtr(params32
->buf
),
2350 ULongToPtr(params32
->ret_len
),
2354 ret
= key_export_rsa( ¶ms
);
2355 put_asymmetric_key32( &key
, key32
);
2359 static NTSTATUS
wow64_key_import_rsa( void *args
)
2366 } const *params32
= args
;
2370 struct key32
*key32
= ULongToPtr( params32
->key
);
2371 struct key_import_params params
=
2373 get_asymmetric_key( key32
, &key
),
2374 ULongToPtr(params32
->buf
),
2378 ret
= key_import_rsa( ¶ms
);
2379 put_asymmetric_key32( &key
, key32
);
2383 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
2385 gnutls_process_attach
,
2386 gnutls_process_detach
,
2387 wow64_key_symmetric_vector_reset
,
2388 wow64_key_symmetric_set_auth_data
,
2389 wow64_key_symmetric_encrypt
,
2390 wow64_key_symmetric_decrypt
,
2391 wow64_key_symmetric_get_tag
,
2392 wow64_key_symmetric_destroy
,
2393 wow64_key_asymmetric_generate
,
2394 wow64_key_asymmetric_decrypt
,
2395 wow64_key_asymmetric_duplicate
,
2396 wow64_key_asymmetric_sign
,
2397 wow64_key_asymmetric_verify
,
2398 wow64_key_asymmetric_destroy
,
2399 wow64_key_export_dsa_capi
,
2400 wow64_key_export_ecc
,
2401 wow64_key_export_rsa
,
2402 wow64_key_import_dsa_capi
,
2403 wow64_key_import_ecc
,
2404 wow64_key_import_rsa
2409 #endif /* HAVE_GNUTLS_CIPHER_INIT */