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
,
72 #if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 6)
73 #define GNUTLS_CIPHER_AES_128_CFB8 29
74 #define GNUTLS_CIPHER_AES_192_CFB8 30
75 #define GNUTLS_CIPHER_AES_256_CFB8 31
77 #define GNUTLS_PK_RSA_PSS 6
78 #define GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS (1 << 7)
79 typedef struct gnutls_x509_spki_st
*gnutls_x509_spki_t
;
84 gnutls_cipher_hd_t cipher
;
87 gnutls_privkey_t privkey
;
88 gnutls_pubkey_t pubkey
;
91 C_ASSERT( sizeof(union key_data
) <= sizeof(((struct key
*)0)->private) );
93 static union key_data
*key_data( struct key
*key
)
95 return (union key_data
*)key
->private;
98 /* Not present in gnutls version < 3.0 */
99 static int (*pgnutls_cipher_tag
)(gnutls_cipher_hd_t
, void *, size_t);
100 static int (*pgnutls_cipher_add_auth
)(gnutls_cipher_hd_t
, const void *, size_t);
101 static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign
)(gnutls_pk_algorithm_t
, gnutls_digest_algorithm_t
);
102 static int (*pgnutls_pubkey_import_ecc_raw
)(gnutls_pubkey_t
, gnutls_ecc_curve_t
,
103 const gnutls_datum_t
*, const gnutls_datum_t
*);
104 static int (*pgnutls_pubkey_export_ecc_raw
)(gnutls_pubkey_t key
, gnutls_ecc_curve_t
*curve
,
105 gnutls_datum_t
*x
, gnutls_datum_t
*y
);
106 static int (*pgnutls_privkey_import_ecc_raw
)(gnutls_privkey_t
, gnutls_ecc_curve_t
, const gnutls_datum_t
*,
107 const gnutls_datum_t
*, const gnutls_datum_t
*);
108 static int (*pgnutls_pubkey_verify_hash2
)(gnutls_pubkey_t
, gnutls_sign_algorithm_t
, unsigned int,
109 const gnutls_datum_t
*, const gnutls_datum_t
*);
110 static int (*pgnutls_pubkey_encrypt_data
)(gnutls_pubkey_t
, unsigned int flags
, const gnutls_datum_t
*,
113 /* Not present in gnutls version < 2.11.0 */
114 static int (*pgnutls_pubkey_import_rsa_raw
)(gnutls_pubkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*);
116 /* Not present in gnutls version < 2.12.0 */
117 static int (*pgnutls_pubkey_import_dsa_raw
)(gnutls_pubkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*,
118 const gnutls_datum_t
*, const gnutls_datum_t
*);
119 static int (*pgnutls_pubkey_import_privkey
)(gnutls_pubkey_t
, gnutls_privkey_t
, unsigned int, unsigned int);
120 static int (*pgnutls_privkey_decrypt_data
)(gnutls_privkey_t
, unsigned int flags
, const gnutls_datum_t
*,
123 /* Not present in gnutls version < 3.3.0 */
124 static int (*pgnutls_pubkey_export_dsa_raw
)(gnutls_pubkey_t
, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
126 static int (*pgnutls_pubkey_export_rsa_raw
)(gnutls_pubkey_t
, gnutls_datum_t
*, gnutls_datum_t
*);
127 static int (*pgnutls_privkey_export_ecc_raw
)(gnutls_privkey_t
, gnutls_ecc_curve_t
*,
128 gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*);
129 static int (*pgnutls_privkey_export_rsa_raw
)(gnutls_privkey_t
, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
130 gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
132 static int (*pgnutls_privkey_export_dsa_raw
)(gnutls_privkey_t
, gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*,
133 gnutls_datum_t
*, gnutls_datum_t
*);
134 static int (*pgnutls_privkey_generate
)(gnutls_privkey_t
, gnutls_pk_algorithm_t
, unsigned int, unsigned int);
135 static int (*pgnutls_privkey_import_rsa_raw
)(gnutls_privkey_t
, const gnutls_datum_t
*, const gnutls_datum_t
*,
136 const gnutls_datum_t
*, const gnutls_datum_t
*, const gnutls_datum_t
*,
137 const gnutls_datum_t
*, const gnutls_datum_t
*, const gnutls_datum_t
*);
139 /* Not present in gnutls version < 3.6.0 */
140 static int (*pgnutls_decode_rs_value
)(const gnutls_datum_t
*, gnutls_datum_t
*, gnutls_datum_t
*);
141 static int (*pgnutls_x509_spki_init
)(gnutls_x509_spki_t
*);
142 static void (*pgnutls_x509_spki_deinit
)(gnutls_x509_spki_t
);
143 static void (*pgnutls_x509_spki_set_rsa_pss_params
)(gnutls_x509_spki_t
, gnutls_digest_algorithm_t
, unsigned int);
144 static int (*pgnutls_pubkey_set_spki
)(gnutls_pubkey_t
, const gnutls_x509_spki_t
, unsigned int);
145 static int (*pgnutls_privkey_set_spki
)(gnutls_privkey_t
, const gnutls_x509_spki_t
, unsigned int);
147 static void *libgnutls_handle
;
148 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
149 MAKE_FUNCPTR(gnutls_cipher_decrypt2
);
150 MAKE_FUNCPTR(gnutls_cipher_deinit
);
151 MAKE_FUNCPTR(gnutls_cipher_encrypt2
);
152 MAKE_FUNCPTR(gnutls_cipher_init
);
153 MAKE_FUNCPTR(gnutls_global_deinit
);
154 MAKE_FUNCPTR(gnutls_global_init
);
155 MAKE_FUNCPTR(gnutls_global_set_log_function
);
156 MAKE_FUNCPTR(gnutls_global_set_log_level
);
157 MAKE_FUNCPTR(gnutls_perror
);
158 MAKE_FUNCPTR(gnutls_privkey_decrypt_data
);
159 MAKE_FUNCPTR(gnutls_privkey_deinit
);
160 MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw
);
161 MAKE_FUNCPTR(gnutls_privkey_init
);
162 MAKE_FUNCPTR(gnutls_privkey_sign_hash
);
163 MAKE_FUNCPTR(gnutls_pubkey_deinit
);
164 MAKE_FUNCPTR(gnutls_pubkey_encrypt_data
);
165 MAKE_FUNCPTR(gnutls_pubkey_import_privkey
);
166 MAKE_FUNCPTR(gnutls_pubkey_init
);
169 static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle
, void *tag
, size_t tag_size
)
171 return GNUTLS_E_UNKNOWN_CIPHER_TYPE
;
174 static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle
, const void *ptext
, size_t ptext_size
)
176 return GNUTLS_E_UNKNOWN_CIPHER_TYPE
;
179 static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key
, gnutls_ecc_curve_t curve
,
180 const gnutls_datum_t
*x
, const gnutls_datum_t
*y
)
182 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
185 static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key
, gnutls_ecc_curve_t
*curve
,
186 gnutls_datum_t
*x
, gnutls_datum_t
*y
)
188 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
191 static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key
, gnutls_datum_t
*p
, gnutls_datum_t
*q
,
192 gnutls_datum_t
*g
, gnutls_datum_t
*y
)
194 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
197 static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key
, gnutls_datum_t
*m
, gnutls_datum_t
*e
)
199 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
202 static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key
, gnutls_datum_t
*m
, gnutls_datum_t
*e
,
203 gnutls_datum_t
*d
, gnutls_datum_t
*p
, gnutls_datum_t
*q
,
204 gnutls_datum_t
*u
, gnutls_datum_t
*e1
, gnutls_datum_t
*e2
)
206 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
209 static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key
, gnutls_ecc_curve_t
*curve
,
210 gnutls_datum_t
*x
, gnutls_datum_t
*y
, gnutls_datum_t
*k
)
212 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
215 static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key
, gnutls_ecc_curve_t curve
,
216 const gnutls_datum_t
*x
, const gnutls_datum_t
*y
,
217 const gnutls_datum_t
*k
)
219 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
222 static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key
, gnutls_datum_t
*p
, gnutls_datum_t
*q
,
223 gnutls_datum_t
*g
, gnutls_datum_t
*y
, gnutls_datum_t
*x
)
225 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
228 static gnutls_sign_algorithm_t
compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk
, gnutls_digest_algorithm_t hash
)
230 return GNUTLS_SIGN_UNKNOWN
;
233 static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key
, gnutls_sign_algorithm_t algo
,
234 unsigned int flags
, const gnutls_datum_t
*hash
,
235 const gnutls_datum_t
*signature
)
237 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
240 static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key
, const gnutls_datum_t
*m
, const gnutls_datum_t
*e
)
242 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
245 static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key
, const gnutls_datum_t
*p
, const gnutls_datum_t
*q
,
246 const gnutls_datum_t
*g
, const gnutls_datum_t
*y
)
248 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
251 static int compat_gnutls_privkey_generate(gnutls_privkey_t key
, gnutls_pk_algorithm_t algo
, unsigned int bits
,
254 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
257 static int compat_gnutls_decode_rs_value(const gnutls_datum_t
* sig_value
, gnutls_datum_t
* r
, gnutls_datum_t
* s
)
259 return GNUTLS_E_INTERNAL_ERROR
;
262 static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key
, const gnutls_datum_t
*m
, const gnutls_datum_t
*e
,
263 const gnutls_datum_t
*d
, const gnutls_datum_t
*p
, const gnutls_datum_t
*q
,
264 const gnutls_datum_t
*u
, const gnutls_datum_t
*e1
, const gnutls_datum_t
*e2
)
266 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
269 static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key
, unsigned int flags
, const gnutls_datum_t
*cipher_text
,
270 gnutls_datum_t
*plain_text
)
272 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
275 static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key
, unsigned int flags
, const gnutls_datum_t
*cipher_text
,
276 gnutls_datum_t
*plain_text
)
278 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
281 static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t
*spki
)
283 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
286 static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki
)
290 static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki
, gnutls_digest_algorithm_t dig
,
291 unsigned int salt_size
)
295 static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key
, const gnutls_x509_spki_t spki
, unsigned int flags
)
297 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
300 static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key
, const gnutls_x509_spki_t spki
, unsigned int flags
)
302 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
305 static void gnutls_log( int level
, const char *msg
)
307 TRACE( "<%d> %s", level
, msg
);
310 static NTSTATUS
gnutls_process_attach( void *args
)
315 if ((env_str
= getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
317 WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str
));
321 WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
322 setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
325 if (!(libgnutls_handle
= dlopen( SONAME_LIBGNUTLS
, RTLD_NOW
)))
327 ERR_(winediag
)( "failed to load libgnutls, no support for encryption\n" );
328 return STATUS_DLL_NOT_FOUND
;
331 #define LOAD_FUNCPTR(f) \
332 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
334 ERR( "failed to load %s\n", #f ); \
338 LOAD_FUNCPTR(gnutls_cipher_decrypt2
)
339 LOAD_FUNCPTR(gnutls_cipher_deinit
)
340 LOAD_FUNCPTR(gnutls_cipher_encrypt2
)
341 LOAD_FUNCPTR(gnutls_cipher_init
)
342 LOAD_FUNCPTR(gnutls_global_deinit
)
343 LOAD_FUNCPTR(gnutls_global_init
)
344 LOAD_FUNCPTR(gnutls_global_set_log_function
)
345 LOAD_FUNCPTR(gnutls_global_set_log_level
)
346 LOAD_FUNCPTR(gnutls_perror
)
347 LOAD_FUNCPTR(gnutls_privkey_deinit
);
348 LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw
);
349 LOAD_FUNCPTR(gnutls_privkey_init
);
350 LOAD_FUNCPTR(gnutls_privkey_sign_hash
);
351 LOAD_FUNCPTR(gnutls_pubkey_deinit
);
352 LOAD_FUNCPTR(gnutls_pubkey_import_privkey
);
353 LOAD_FUNCPTR(gnutls_pubkey_init
);
356 #define LOAD_FUNCPTR_OPT(f) \
357 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
359 WARN( "failed to load %s\n", #f ); \
363 LOAD_FUNCPTR_OPT(gnutls_cipher_tag
)
364 LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth
)
365 LOAD_FUNCPTR_OPT(gnutls_decode_rs_value
)
366 LOAD_FUNCPTR_OPT(gnutls_pk_to_sign
)
367 LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data
)
368 LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw
)
369 LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw
)
370 LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw
)
371 LOAD_FUNCPTR_OPT(gnutls_privkey_generate
)
372 LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw
)
373 LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw
)
374 LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki
)
375 LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data
)
376 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw
)
377 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw
)
378 LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw
)
379 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw
)
380 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw
)
381 LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw
)
382 LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki
)
383 LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2
)
384 LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit
)
385 LOAD_FUNCPTR_OPT(gnutls_x509_spki_init
)
386 LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params
)
388 #undef LOAD_FUNCPTR_OPT
390 if ((ret
= pgnutls_global_init()) != GNUTLS_E_SUCCESS
)
392 pgnutls_perror( ret
);
396 if (TRACE_ON( bcrypt
))
398 pgnutls_global_set_log_level( 4 );
399 pgnutls_global_set_log_function( gnutls_log
);
402 return STATUS_SUCCESS
;
405 dlclose( libgnutls_handle
);
406 libgnutls_handle
= NULL
;
407 return STATUS_DLL_NOT_FOUND
;
410 static NTSTATUS
gnutls_process_detach( void *args
)
412 if (libgnutls_handle
)
414 pgnutls_global_deinit();
415 dlclose( libgnutls_handle
);
416 libgnutls_handle
= NULL
;
418 return STATUS_SUCCESS
;
429 static void buffer_init( struct buffer
*buffer
)
431 buffer
->buffer
= NULL
;
434 buffer
->error
= FALSE
;
437 static void buffer_free( struct buffer
*buffer
)
439 free( buffer
->buffer
);
442 static void buffer_append( struct buffer
*buffer
, BYTE
*data
, DWORD len
)
446 if (buffer
->pos
+ len
> buffer
->length
)
448 DWORD new_length
= max( max( buffer
->pos
+ len
, buffer
->length
* 2 ), 64 );
451 if (!(new_buffer
= realloc( buffer
->buffer
, new_length
)))
453 ERR( "out of memory\n" );
454 buffer
->error
= TRUE
;
458 buffer
->buffer
= new_buffer
;
459 buffer
->length
= new_length
;
462 memcpy( &buffer
->buffer
[buffer
->pos
], data
, len
);
466 static void buffer_append_byte( struct buffer
*buffer
, BYTE value
)
468 buffer_append( buffer
, &value
, sizeof(value
) );
471 static void buffer_append_asn1_length( struct buffer
*buffer
, DWORD length
)
477 buffer_append_byte( buffer
, length
);
481 if (length
<= 0xff) num_bytes
= 1;
482 else if (length
<= 0xffff) num_bytes
= 2;
483 else if (length
<= 0xffffff) num_bytes
= 3;
486 buffer_append_byte( buffer
, 0x80 | num_bytes
);
487 while (num_bytes
--) buffer_append_byte( buffer
, length
>> (num_bytes
* 8) );
490 static void buffer_append_asn1_integer( struct buffer
*buffer
, BYTE
*data
, DWORD len
)
492 DWORD leading_zero
= (*data
& 0x80) != 0;
494 buffer_append_byte( buffer
, 0x02 ); /* tag */
495 buffer_append_asn1_length( buffer
, len
+ leading_zero
);
496 if (leading_zero
) buffer_append_byte( buffer
, 0 );
497 buffer_append( buffer
, data
, len
);
500 static void buffer_append_asn1_sequence( struct buffer
*buffer
, struct buffer
*content
)
504 buffer
->error
= TRUE
;
508 buffer_append_byte( buffer
, 0x30 ); /* tag */
509 buffer_append_asn1_length( buffer
, content
->pos
);
510 buffer_append( buffer
, content
->buffer
, content
->pos
);
513 static void buffer_append_asn1_r_s( struct buffer
*buffer
, BYTE
*r
, DWORD r_len
, BYTE
*s
, DWORD s_len
)
517 buffer_init( &value
);
518 buffer_append_asn1_integer( &value
, r
, r_len
);
519 buffer_append_asn1_integer( &value
, s
, s_len
);
520 buffer_append_asn1_sequence( buffer
, &value
);
521 buffer_free( &value
);
524 static gnutls_cipher_algorithm_t
get_gnutls_cipher( const struct key
*key
)
529 WARN( "handle block size\n" );
530 switch (key
->u
.s
.mode
)
533 return GNUTLS_CIPHER_3DES_CBC
;
537 FIXME( "3DES mode %u with key length %u not supported\n", key
->u
.s
.mode
, key
->u
.s
.secret_len
);
538 return GNUTLS_CIPHER_UNKNOWN
;
541 WARN( "handle block size\n" );
542 switch (key
->u
.s
.mode
)
545 if (key
->u
.s
.secret_len
== 16) return GNUTLS_CIPHER_AES_128_GCM
;
546 if (key
->u
.s
.secret_len
== 32) return GNUTLS_CIPHER_AES_256_GCM
;
548 case CHAIN_MODE_ECB
: /* can be emulated with CBC + empty IV */
550 if (key
->u
.s
.secret_len
== 16) return GNUTLS_CIPHER_AES_128_CBC
;
551 if (key
->u
.s
.secret_len
== 24) return GNUTLS_CIPHER_AES_192_CBC
;
552 if (key
->u
.s
.secret_len
== 32) return GNUTLS_CIPHER_AES_256_CBC
;
555 if (key
->u
.s
.secret_len
== 16) return GNUTLS_CIPHER_AES_128_CFB8
;
556 if (key
->u
.s
.secret_len
== 24) return GNUTLS_CIPHER_AES_192_CFB8
;
557 if (key
->u
.s
.secret_len
== 32) return GNUTLS_CIPHER_AES_256_CFB8
;
562 FIXME( "AES mode %u with key length %u not supported\n", key
->u
.s
.mode
, key
->u
.s
.secret_len
);
563 return GNUTLS_CIPHER_UNKNOWN
;
566 FIXME( "algorithm %u not supported\n", key
->alg_id
);
567 return GNUTLS_CIPHER_UNKNOWN
;
571 static NTSTATUS
key_symmetric_vector_reset( void *args
)
573 struct key
*key
= args
;
575 if (!key_data(key
)->cipher
) return STATUS_SUCCESS
;
576 TRACE( "invalidating cipher handle\n" );
577 pgnutls_cipher_deinit( key_data(key
)->cipher
);
578 key_data(key
)->cipher
= NULL
;
579 return STATUS_SUCCESS
;
582 static NTSTATUS
init_cipher_handle( struct key
*key
)
584 gnutls_cipher_algorithm_t cipher
;
585 gnutls_datum_t secret
, vector
;
588 if (key_data(key
)->cipher
) return STATUS_SUCCESS
;
589 if ((cipher
= get_gnutls_cipher( key
)) == GNUTLS_CIPHER_UNKNOWN
) return STATUS_NOT_SUPPORTED
;
591 secret
.data
= key
->u
.s
.secret
;
592 secret
.size
= key
->u
.s
.secret_len
;
594 vector
.data
= key
->u
.s
.vector
;
595 vector
.size
= key
->u
.s
.vector_len
;
597 if ((ret
= pgnutls_cipher_init( &key_data(key
)->cipher
, cipher
, &secret
, key
->u
.s
.vector
? &vector
: NULL
)))
599 pgnutls_perror( ret
);
600 return STATUS_INTERNAL_ERROR
;
603 return STATUS_SUCCESS
;
606 static NTSTATUS
key_symmetric_set_auth_data( void *args
)
608 const struct key_symmetric_set_auth_data_params
*params
= args
;
612 if (!params
->auth_data
) return STATUS_SUCCESS
;
613 if ((status
= init_cipher_handle( params
->key
))) return status
;
615 if ((ret
= pgnutls_cipher_add_auth( key_data(params
->key
)->cipher
, params
->auth_data
, params
->len
)))
617 pgnutls_perror( ret
);
618 return STATUS_INTERNAL_ERROR
;
620 return STATUS_SUCCESS
;
623 static NTSTATUS
key_symmetric_encrypt( void *args
)
625 const struct key_symmetric_encrypt_params
*params
= args
;
629 if ((status
= init_cipher_handle( params
->key
))) return status
;
631 if ((ret
= pgnutls_cipher_encrypt2( key_data(params
->key
)->cipher
, params
->input
, params
->input_len
,
632 params
->output
, params
->output_len
)))
634 pgnutls_perror( ret
);
635 return STATUS_INTERNAL_ERROR
;
637 return STATUS_SUCCESS
;
640 static NTSTATUS
key_symmetric_decrypt( void *args
)
642 const struct key_symmetric_decrypt_params
*params
= args
;
646 if ((status
= init_cipher_handle( params
->key
))) return status
;
648 if ((ret
= pgnutls_cipher_decrypt2( key_data(params
->key
)->cipher
, params
->input
, params
->input_len
,
649 params
->output
, params
->output_len
)))
651 pgnutls_perror( ret
);
652 return STATUS_INTERNAL_ERROR
;
654 return STATUS_SUCCESS
;
657 static NTSTATUS
key_symmetric_get_tag( void *args
)
659 const struct key_symmetric_get_tag_params
*params
= args
;
663 if ((status
= init_cipher_handle( params
->key
))) return status
;
665 if ((ret
= pgnutls_cipher_tag( key_data(params
->key
)->cipher
, params
->tag
, params
->len
)))
667 pgnutls_perror( ret
);
668 return STATUS_INTERNAL_ERROR
;
670 return STATUS_SUCCESS
;
673 static NTSTATUS
key_symmetric_destroy( void *args
)
675 struct key
*key
= args
;
677 if (key_data(key
)->cipher
) pgnutls_cipher_deinit( key_data(key
)->cipher
);
678 return STATUS_SUCCESS
;
681 static ULONG
export_gnutls_datum( UCHAR
*buffer
, ULONG buflen
, gnutls_datum_t
*d
, BOOL zero_pad
)
683 ULONG size
= d
->size
;
684 UCHAR
*src
= d
->data
;
687 assert( size
<= buflen
+ 1 );
688 if (size
== buflen
+ 1)
696 offset
= buflen
- size
;
697 if (buffer
) memset( buffer
, 0, offset
);
701 if (buffer
) memcpy( buffer
+ offset
, src
, size
- offset
);
705 #define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
706 static NTSTATUS
key_export_rsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
708 BCRYPT_RSAKEY_BLOB
*rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
710 ULONG size
= key
->u
.a
.bitlen
/ 8;
714 if (key_data(key
)->a
.pubkey
)
715 ret
= pgnutls_pubkey_export_rsa_raw( key_data(key
)->a
.pubkey
, &m
, &e
);
717 return STATUS_INVALID_PARAMETER
;
721 pgnutls_perror( ret
);
722 return STATUS_INTERNAL_ERROR
;
725 *ret_len
= sizeof(*rsa_blob
) + EXPORT_SIZE( e
, size
, 0 ) + EXPORT_SIZE( m
, size
, 1 );
726 if (len
>= *ret_len
&& buf
)
728 dst
= (UCHAR
*)(rsa_blob
+ 1);
729 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, size
, &e
, 0 );
731 dst
+= rsa_blob
->cbPublicExp
;
732 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, size
, &m
, 1 );
734 rsa_blob
->Magic
= BCRYPT_RSAPUBLIC_MAGIC
;
735 rsa_blob
->BitLength
= key
->u
.a
.bitlen
;
736 rsa_blob
->cbPrime1
= 0;
737 rsa_blob
->cbPrime2
= 0;
740 free( e
.data
); free( m
.data
);
741 return STATUS_SUCCESS
;
744 static NTSTATUS
key_export_ecc_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
746 BCRYPT_ECCKEY_BLOB
*ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
747 gnutls_ecc_curve_t curve
;
755 case ALG_ID_ECDH_P256
:
756 magic
= BCRYPT_ECDH_PUBLIC_P256_MAGIC
;
760 case ALG_ID_ECDH_P384
:
761 magic
= BCRYPT_ECDH_PUBLIC_P384_MAGIC
;
765 case ALG_ID_ECDSA_P256
:
766 magic
= BCRYPT_ECDSA_PUBLIC_P256_MAGIC
;
770 case ALG_ID_ECDSA_P384
:
771 magic
= BCRYPT_ECDSA_PUBLIC_P384_MAGIC
;
776 FIXME( "algorithm %u not supported\n", key
->alg_id
);
777 return STATUS_NOT_IMPLEMENTED
;
780 if (key_data(key
)->a
.pubkey
)
781 ret
= pgnutls_pubkey_export_ecc_raw( key_data(key
)->a
.pubkey
, &curve
, &x
, &y
);
783 return STATUS_INVALID_PARAMETER
;
787 pgnutls_perror( ret
);
788 return STATUS_INTERNAL_ERROR
;
791 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
&& curve
!= GNUTLS_ECC_CURVE_SECP384R1
)
793 FIXME( "curve %u not supported\n", curve
);
794 free( x
.data
); free( y
.data
);
795 return STATUS_NOT_IMPLEMENTED
;
798 *ret_len
= sizeof(*ecc_blob
) + EXPORT_SIZE( x
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
799 if (len
>= *ret_len
&& buf
)
801 ecc_blob
->dwMagic
= magic
;
802 ecc_blob
->cbKey
= size
;
804 dst
= (UCHAR
*)(ecc_blob
+ 1);
805 dst
+= export_gnutls_datum( dst
, size
, &x
, 1 );
806 export_gnutls_datum( dst
, size
, &y
, 1 );
809 free( x
.data
); free( y
.data
);
810 return STATUS_SUCCESS
;
813 static NTSTATUS
key_export_dsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
815 BCRYPT_DSA_KEY_BLOB
*dsa_blob
= (BCRYPT_DSA_KEY_BLOB
*)buf
;
816 gnutls_datum_t p
, q
, g
, y
;
817 ULONG size
= key
->u
.a
.bitlen
/ 8;
818 NTSTATUS status
= STATUS_SUCCESS
;
822 if (key
->u
.a
.bitlen
> 1024)
824 FIXME( "bitlen > 1024 not supported\n" );
825 return STATUS_NOT_IMPLEMENTED
;
828 if (key_data(key
)->a
.pubkey
)
829 ret
= pgnutls_pubkey_export_dsa_raw( key_data(key
)->a
.pubkey
, &p
, &q
, &g
, &y
);
831 return STATUS_INVALID_PARAMETER
;
835 pgnutls_perror( ret
);
836 return STATUS_INTERNAL_ERROR
;
839 if (EXPORT_SIZE( q
, sizeof(dsa_blob
->q
), 1 ) > sizeof(dsa_blob
->q
))
841 status
= STATUS_INVALID_PARAMETER
;
845 *ret_len
= sizeof(*dsa_blob
) + EXPORT_SIZE( p
, size
, 1 ) + EXPORT_SIZE( g
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
846 if (len
>= *ret_len
&& buf
)
848 dst
= (UCHAR
*)(dsa_blob
+ 1);
849 dst
+= export_gnutls_datum( dst
, size
, &p
, 1 );
850 dst
+= export_gnutls_datum( dst
, size
, &g
, 1 );
851 export_gnutls_datum( dst
, size
, &y
, 1 );
854 export_gnutls_datum( dst
, sizeof(dsa_blob
->q
), &q
, 1 );
856 dsa_blob
->dwMagic
= BCRYPT_DSA_PUBLIC_MAGIC
;
857 dsa_blob
->cbKey
= size
;
858 memset( dsa_blob
->Count
, 0, sizeof(dsa_blob
->Count
) ); /* FIXME */
859 memset( dsa_blob
->Seed
, 0, sizeof(dsa_blob
->Seed
) ); /* FIXME */
863 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
867 static void reverse_bytes( UCHAR
*buf
, ULONG len
)
872 for (i
= 0; i
< len
/ 2; ++i
)
875 buf
[i
] = buf
[len
- i
- 1];
876 buf
[len
- i
- 1] = tmp
;
881 static NTSTATUS
key_export_dsa_capi_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
883 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
885 gnutls_datum_t p
, q
, g
, y
;
886 ULONG size
= key
->u
.a
.bitlen
/ 8;
887 NTSTATUS status
= STATUS_SUCCESS
;
891 if (key
->u
.a
.bitlen
> 1024)
893 FIXME( "bitlen > 1024 not supported\n" );
894 return STATUS_NOT_IMPLEMENTED
;
897 if (key_data(key
)->a
.pubkey
)
898 ret
= pgnutls_pubkey_export_dsa_raw( key_data(key
)->a
.pubkey
, &p
, &q
, &g
, &y
);
899 else if (key_data(key
)->a
.privkey
)
900 ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->a
.privkey
, &p
, &q
, &g
, &y
, NULL
);
902 return STATUS_INVALID_PARAMETER
;
906 pgnutls_perror( ret
);
907 return STATUS_INTERNAL_ERROR
;
910 if (EXPORT_SIZE( q
, Q_SIZE
, 1 ) > Q_SIZE
)
912 status
= STATUS_INVALID_PARAMETER
;
916 *ret_len
= sizeof(*hdr
) + sizeof(*dsskey
) + sizeof(key
->u
.a
.dss_seed
) +
917 EXPORT_SIZE( p
, size
, 1 ) + Q_SIZE
+ EXPORT_SIZE( g
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
918 if (len
>= *ret_len
&& buf
)
920 hdr
->bType
= PUBLICKEYBLOB
;
923 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
925 dsskey
= (DSSPUBKEY
*)(hdr
+ 1);
926 dsskey
->magic
= MAGIC_DSS1
;
927 dsskey
->bitlen
= key
->u
.a
.bitlen
;
929 dst
= (UCHAR
*)(dsskey
+ 1);
930 export_gnutls_datum( dst
, size
, &p
, 1 );
931 reverse_bytes( dst
, size
);
934 export_gnutls_datum( dst
, Q_SIZE
, &q
, 1 );
935 reverse_bytes( dst
, Q_SIZE
);
938 export_gnutls_datum( dst
, size
, &g
, 1 );
939 reverse_bytes( dst
, size
);
942 export_gnutls_datum( dst
, size
, &y
, 1 );
943 reverse_bytes( dst
, size
);
946 memcpy( dst
, &key
->u
.a
.dss_seed
, sizeof(key
->u
.a
.dss_seed
) );
950 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
954 static NTSTATUS
key_asymmetric_generate( void *args
)
956 struct key
*key
= args
;
957 gnutls_pk_algorithm_t pk_alg
;
958 gnutls_privkey_t privkey
;
959 gnutls_pubkey_t pubkey
;
963 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
964 if (key_data(key
)->a
.privkey
) return STATUS_INVALID_HANDLE
;
969 case ALG_ID_RSA_SIGN
:
970 pk_alg
= GNUTLS_PK_RSA
;
971 bitlen
= key
->u
.a
.bitlen
;
975 pk_alg
= GNUTLS_PK_DSA
;
976 bitlen
= key
->u
.a
.bitlen
;
979 case ALG_ID_ECDH_P256
:
980 case ALG_ID_ECDSA_P256
:
981 pk_alg
= GNUTLS_PK_ECC
; /* compatible with ECDSA and ECDH */
982 bitlen
= GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1
);
985 case ALG_ID_ECDH_P384
:
986 case ALG_ID_ECDSA_P384
:
987 pk_alg
= GNUTLS_PK_ECC
; /* compatible with ECDSA and ECDH */
988 bitlen
= GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1
);
992 FIXME( "algorithm %u not supported\n", key
->alg_id
);
993 return STATUS_NOT_SUPPORTED
;
996 if ((ret
= pgnutls_privkey_init( &privkey
)))
998 pgnutls_perror( ret
);
999 return STATUS_INTERNAL_ERROR
;
1001 if ((ret
= pgnutls_pubkey_init( &pubkey
)))
1003 pgnutls_perror( ret
);
1004 pgnutls_privkey_deinit( privkey
);
1005 return STATUS_INTERNAL_ERROR
;
1008 if ((ret
= pgnutls_privkey_generate( privkey
, pk_alg
, bitlen
, 0 )))
1010 pgnutls_perror( ret
);
1011 pgnutls_privkey_deinit( privkey
);
1012 pgnutls_pubkey_deinit( pubkey
);
1013 return STATUS_INTERNAL_ERROR
;
1015 if ((ret
= pgnutls_pubkey_import_privkey( pubkey
, privkey
, 0, 0 )))
1017 pgnutls_perror( ret
);
1018 pgnutls_privkey_deinit( privkey
);
1019 pgnutls_pubkey_deinit( pubkey
);
1020 return STATUS_INTERNAL_ERROR
;
1023 key_data(key
)->a
.privkey
= privkey
;
1024 key_data(key
)->a
.pubkey
= pubkey
;
1025 return STATUS_SUCCESS
;
1028 static NTSTATUS
key_export_ecc( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1030 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1031 gnutls_ecc_curve_t curve
;
1032 gnutls_datum_t x
, y
, d
;
1037 switch (key
->alg_id
)
1039 case ALG_ID_ECDH_P256
:
1040 magic
= BCRYPT_ECDH_PRIVATE_P256_MAGIC
;
1044 case ALG_ID_ECDH_P384
:
1045 magic
= BCRYPT_ECDH_PRIVATE_P384_MAGIC
;
1049 case ALG_ID_ECDSA_P256
:
1050 magic
= BCRYPT_ECDSA_PRIVATE_P256_MAGIC
;
1054 case ALG_ID_ECDSA_P384
:
1055 magic
= BCRYPT_ECDSA_PRIVATE_P384_MAGIC
;
1060 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key
->alg_id
);
1061 return STATUS_NOT_IMPLEMENTED
;
1064 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1066 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key
)->a
.privkey
, &curve
, &x
, &y
, &d
)))
1068 pgnutls_perror( ret
);
1069 return STATUS_INTERNAL_ERROR
;
1072 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
&& curve
!= GNUTLS_ECC_CURVE_SECP384R1
)
1074 FIXME( "curve %u not supported\n", curve
);
1075 free( x
.data
); free( y
.data
); free( d
.data
);
1076 return STATUS_NOT_IMPLEMENTED
;
1079 *ret_len
= sizeof(*ecc_blob
) + EXPORT_SIZE( x
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 ) + EXPORT_SIZE( d
, size
, 1 );
1080 if (len
>= *ret_len
&& buf
)
1082 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1083 ecc_blob
->dwMagic
= magic
;
1084 ecc_blob
->cbKey
= size
;
1086 dst
= (UCHAR
*)(ecc_blob
+ 1);
1087 dst
+= export_gnutls_datum( dst
, size
, &x
, 1 );
1088 dst
+= export_gnutls_datum( dst
, size
, &y
, 1 );
1089 export_gnutls_datum( dst
, size
, &d
, 1 );
1092 free( x
.data
); free( y
.data
); free( d
.data
);
1093 return STATUS_SUCCESS
;
1096 static NTSTATUS
key_import_ecc( struct key
*key
, UCHAR
*buf
, ULONG len
)
1098 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1099 gnutls_ecc_curve_t curve
;
1100 gnutls_privkey_t handle
;
1101 gnutls_datum_t x
, y
, k
;
1104 switch (key
->alg_id
)
1106 case ALG_ID_ECDH_P256
:
1107 case ALG_ID_ECDSA_P256
:
1108 curve
= GNUTLS_ECC_CURVE_SECP256R1
;
1111 case ALG_ID_ECDH_P384
:
1112 case ALG_ID_ECDSA_P384
:
1113 curve
= GNUTLS_ECC_CURVE_SECP384R1
;
1117 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1118 return STATUS_NOT_IMPLEMENTED
;
1121 if ((ret
= pgnutls_privkey_init( &handle
)))
1123 pgnutls_perror( ret
);
1124 return STATUS_INTERNAL_ERROR
;
1127 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1128 x
.data
= (unsigned char *)(ecc_blob
+ 1);
1129 x
.size
= ecc_blob
->cbKey
;
1130 y
.data
= x
.data
+ ecc_blob
->cbKey
;
1131 y
.size
= ecc_blob
->cbKey
;
1132 k
.data
= y
.data
+ ecc_blob
->cbKey
;
1133 k
.size
= ecc_blob
->cbKey
;
1135 if ((ret
= pgnutls_privkey_import_ecc_raw( handle
, curve
, &x
, &y
, &k
)))
1137 pgnutls_perror( ret
);
1138 pgnutls_privkey_deinit( handle
);
1139 return STATUS_INTERNAL_ERROR
;
1142 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1143 key_data(key
)->a
.privkey
= handle
;
1144 return STATUS_SUCCESS
;
1147 static NTSTATUS
key_export_rsa( struct key
*key
, ULONG flags
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1149 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1150 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
1151 ULONG size
= key
->u
.a
.bitlen
/ 8;
1152 BOOL full
= (flags
& KEY_EXPORT_FLAG_RSA_FULL
);
1156 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1158 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key
)->a
.privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
1160 pgnutls_perror( ret
);
1161 return STATUS_INTERNAL_ERROR
;
1164 *ret_len
= sizeof(*rsa_blob
) + EXPORT_SIZE( e
, size
, 0 ) + EXPORT_SIZE( m
, size
, 1 ) +
1165 EXPORT_SIZE( p
, size
/ 2, 1 ) + EXPORT_SIZE( q
, size
/ 2, 1 );
1167 if (full
) *ret_len
+= EXPORT_SIZE( e1
, size
/ 2, 1 ) + EXPORT_SIZE( e2
, size
/ 2, 1 ) +
1168 EXPORT_SIZE( u
, size
/ 2, 1 ) + EXPORT_SIZE( d
, size
, 1 );
1170 if (len
>= *ret_len
&& buf
)
1172 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1173 rsa_blob
->Magic
= full
? BCRYPT_RSAFULLPRIVATE_MAGIC
: BCRYPT_RSAPRIVATE_MAGIC
;
1174 rsa_blob
->BitLength
= key
->u
.a
.bitlen
;
1176 dst
= (UCHAR
*)(rsa_blob
+ 1);
1177 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, size
, &e
, 0 );
1179 dst
+= rsa_blob
->cbPublicExp
;
1180 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, size
, &m
, 1 );
1182 dst
+= rsa_blob
->cbModulus
;
1183 rsa_blob
->cbPrime1
= export_gnutls_datum( dst
, size
/ 2, &p
, 1 );
1185 dst
+= rsa_blob
->cbPrime1
;
1186 rsa_blob
->cbPrime2
= export_gnutls_datum( dst
, size
/ 2, &q
, 1 );
1190 dst
+= rsa_blob
->cbPrime2
;
1191 export_gnutls_datum( dst
, size
/ 2, &e1
, 1 );
1193 dst
+= rsa_blob
->cbPrime1
;
1194 export_gnutls_datum( dst
, size
/ 2, &e2
, 1 );
1196 dst
+= rsa_blob
->cbPrime2
;
1197 export_gnutls_datum( dst
, size
/ 2, &u
, 1 );
1199 dst
+= rsa_blob
->cbPrime1
;
1200 export_gnutls_datum( dst
, size
, &d
, 1 );
1204 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
1205 free( e1
.data
); free( e2
.data
);
1206 return STATUS_SUCCESS
;
1209 static NTSTATUS
key_import_rsa( struct key
*key
, UCHAR
*buf
, ULONG len
)
1211 BCRYPT_RSAKEY_BLOB
*rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1212 gnutls_datum_t m
, e
, p
, q
;
1213 gnutls_privkey_t handle
;
1216 if ((ret
= pgnutls_privkey_init( &handle
)))
1218 pgnutls_perror( ret
);
1219 return STATUS_INTERNAL_ERROR
;
1222 e
.data
= (unsigned char *)(rsa_blob
+ 1);
1223 e
.size
= rsa_blob
->cbPublicExp
;
1224 m
.data
= e
.data
+ e
.size
;
1225 m
.size
= rsa_blob
->cbModulus
;
1226 p
.data
= m
.data
+ m
.size
;
1227 p
.size
= rsa_blob
->cbPrime1
;
1228 q
.data
= p
.data
+ p
.size
;
1229 q
.size
= rsa_blob
->cbPrime2
;
1231 if ((ret
= pgnutls_privkey_import_rsa_raw( handle
, &m
, &e
, NULL
, &p
, &q
, NULL
, NULL
, NULL
)))
1233 pgnutls_perror( ret
);
1234 pgnutls_privkey_deinit( handle
);
1235 return STATUS_INTERNAL_ERROR
;
1238 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1239 key_data(key
)->a
.privkey
= handle
;
1240 return STATUS_SUCCESS
;
1243 static NTSTATUS
key_export_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1247 gnutls_datum_t p
, q
, g
, y
, x
;
1248 ULONG size
= key
->u
.a
.bitlen
/ 8;
1252 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1254 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->a
.privkey
, &p
, &q
, &g
, &y
, &x
)))
1256 pgnutls_perror( ret
);
1257 return STATUS_INTERNAL_ERROR
;
1260 if (q
.size
> 21 || x
.size
> 21)
1262 ERR( "can't export key in this format\n" );
1263 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1264 return STATUS_NOT_SUPPORTED
;
1267 *ret_len
= sizeof(*hdr
) + sizeof(*pubkey
) + sizeof(key
->u
.a
.dss_seed
) +
1268 EXPORT_SIZE( p
, size
, 1 ) + 20 + EXPORT_SIZE( g
, size
, 1 ) + 20;
1269 if (len
>= *ret_len
&& buf
)
1271 hdr
= (BLOBHEADER
*)buf
;
1272 hdr
->bType
= PRIVATEKEYBLOB
;
1275 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
1277 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1278 pubkey
->magic
= MAGIC_DSS2
;
1279 pubkey
->bitlen
= key
->u
.a
.bitlen
;
1281 dst
= (UCHAR
*)(pubkey
+ 1);
1282 export_gnutls_datum( dst
, size
, &p
, 1 );
1283 reverse_bytes( dst
, size
);
1286 export_gnutls_datum( dst
, 20, &q
, 1 );
1287 reverse_bytes( dst
, 20 );
1290 export_gnutls_datum( dst
, size
, &g
, 1 );
1291 reverse_bytes( dst
, size
);
1294 export_gnutls_datum( dst
, 20, &x
, 1 );
1295 reverse_bytes( dst
, 20 );
1298 memcpy( dst
, &key
->u
.a
.dss_seed
, sizeof(key
->u
.a
.dss_seed
) );
1301 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1302 return STATUS_SUCCESS
;
1305 static NTSTATUS
key_import_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
)
1307 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
1309 gnutls_privkey_t handle
;
1310 gnutls_datum_t p
, q
, g
, x
;
1311 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], x_data
[20];
1314 if ((ret
= pgnutls_privkey_init( &handle
)))
1316 pgnutls_perror( ret
);
1317 return STATUS_INTERNAL_ERROR
;
1320 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1321 if ((size
= pubkey
->bitlen
/ 8) > sizeof(p_data
))
1323 FIXME( "size %u not supported\n", size
);
1324 pgnutls_privkey_deinit( handle
);
1325 return STATUS_NOT_SUPPORTED
;
1327 data
= (unsigned char *)(pubkey
+ 1);
1331 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1335 q
.size
= sizeof(q_data
);
1336 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1341 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1345 x
.size
= sizeof(x_data
);
1346 for (i
= 0; i
< x
.size
; i
++) x
.data
[i
] = data
[x
.size
- i
- 1];
1349 if ((ret
= pgnutls_privkey_import_dsa_raw( handle
, &p
, &q
, &g
, NULL
, &x
)))
1351 pgnutls_perror( ret
);
1352 pgnutls_privkey_deinit( handle
);
1353 return STATUS_INTERNAL_ERROR
;
1356 memcpy( &key
->u
.a
.dss_seed
, data
, sizeof(key
->u
.a
.dss_seed
) );
1358 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1359 key_data(key
)->a
.privkey
= handle
;
1360 return STATUS_SUCCESS
;
1363 static NTSTATUS
key_import_ecc_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1365 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1366 gnutls_ecc_curve_t curve
;
1367 gnutls_datum_t x
, y
;
1368 gnutls_pubkey_t handle
;
1371 switch (key
->alg_id
)
1373 case ALG_ID_ECDH_P256
:
1374 case ALG_ID_ECDSA_P256
:
1375 curve
= GNUTLS_ECC_CURVE_SECP256R1
; break;
1377 case ALG_ID_ECDH_P384
:
1378 case ALG_ID_ECDSA_P384
:
1379 curve
= GNUTLS_ECC_CURVE_SECP384R1
; break;
1382 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1383 return STATUS_NOT_IMPLEMENTED
;
1386 if ((ret
= pgnutls_pubkey_init( &handle
)))
1388 pgnutls_perror( ret
);
1389 return STATUS_INTERNAL_ERROR
;
1392 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1393 x
.data
= buf
+ sizeof(*ecc_blob
);
1394 x
.size
= ecc_blob
->cbKey
;
1395 y
.data
= buf
+ sizeof(*ecc_blob
) + ecc_blob
->cbKey
;
1396 y
.size
= ecc_blob
->cbKey
;
1398 if ((ret
= pgnutls_pubkey_import_ecc_raw( handle
, curve
, &x
, &y
)))
1400 pgnutls_perror( ret
);
1401 pgnutls_pubkey_deinit( handle
);
1402 return STATUS_INTERNAL_ERROR
;
1405 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1406 key_data(key
)->a
.pubkey
= handle
;
1407 return STATUS_SUCCESS
;
1410 static NTSTATUS
key_import_rsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1412 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1413 gnutls_pubkey_t handle
;
1414 gnutls_datum_t m
, e
;
1417 if ((ret
= pgnutls_pubkey_init( &handle
)))
1419 pgnutls_perror( ret
);
1420 return STATUS_INTERNAL_ERROR
;
1423 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1424 e
.data
= buf
+ sizeof(*rsa_blob
);
1425 e
.size
= rsa_blob
->cbPublicExp
;
1426 m
.data
= buf
+ sizeof(*rsa_blob
) + rsa_blob
->cbPublicExp
;
1427 m
.size
= rsa_blob
->cbModulus
;
1429 if ((ret
= pgnutls_pubkey_import_rsa_raw( handle
, &m
, &e
)))
1431 pgnutls_perror( ret
);
1432 pgnutls_pubkey_deinit( handle
);
1433 return STATUS_INTERNAL_ERROR
;
1436 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1437 key_data(key
)->a
.pubkey
= handle
;
1438 return STATUS_SUCCESS
;
1441 static NTSTATUS
key_import_dsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1443 BCRYPT_DSA_KEY_BLOB
*dsa_blob
;
1444 gnutls_datum_t p
, q
, g
, y
;
1445 gnutls_pubkey_t handle
;
1448 if ((ret
= pgnutls_pubkey_init( &handle
)))
1450 pgnutls_perror( ret
);
1451 return STATUS_INTERNAL_ERROR
;
1454 dsa_blob
= (BCRYPT_DSA_KEY_BLOB
*)buf
;
1455 p
.data
= buf
+ sizeof(*dsa_blob
);
1456 p
.size
= dsa_blob
->cbKey
;
1457 q
.data
= dsa_blob
->q
;
1458 q
.size
= sizeof(dsa_blob
->q
);
1459 g
.data
= buf
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
;
1460 g
.size
= dsa_blob
->cbKey
;
1461 y
.data
= buf
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
* 2;
1462 y
.size
= dsa_blob
->cbKey
;
1464 if ((ret
= pgnutls_pubkey_import_dsa_raw( handle
, &p
, &q
, &g
, &y
)))
1466 pgnutls_perror( ret
);
1467 pgnutls_pubkey_deinit( handle
);
1468 return STATUS_INTERNAL_ERROR
;
1471 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1472 key_data(key
)->a
.pubkey
= handle
;
1473 return STATUS_SUCCESS
;
1476 static NTSTATUS
key_import_dsa_capi_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1480 gnutls_datum_t p
, q
, g
, y
;
1481 gnutls_pubkey_t handle
;
1482 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], y_data
[128];
1485 if ((ret
= pgnutls_pubkey_init( &handle
)))
1487 pgnutls_perror( ret
);
1488 return STATUS_INTERNAL_ERROR
;
1491 hdr
= (BLOBHEADER
*)buf
;
1492 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1493 size
= pubkey
->bitlen
/ 8;
1494 data
= (unsigned char *)(pubkey
+ 1);
1498 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1502 q
.size
= sizeof(q_data
);
1503 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1508 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1512 y
.size
= sizeof(y_data
);
1513 for (i
= 0; i
< y
.size
; i
++) y
.data
[i
] = data
[y
.size
- i
- 1];
1515 if ((ret
= pgnutls_pubkey_import_dsa_raw( handle
, &p
, &q
, &g
, &y
)))
1517 pgnutls_perror( ret
);
1518 pgnutls_pubkey_deinit( handle
);
1519 return STATUS_INTERNAL_ERROR
;
1522 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1523 key_data(key
)->a
.pubkey
= handle
;
1524 return STATUS_SUCCESS
;
1527 static NTSTATUS
key_asymmetric_export( void *args
)
1529 const struct key_asymmetric_export_params
*params
= args
;
1530 struct key
*key
= params
->key
;
1531 unsigned flags
= params
->flags
;
1533 switch (key
->alg_id
)
1535 case ALG_ID_ECDH_P256
:
1536 case ALG_ID_ECDH_P384
:
1537 case ALG_ID_ECDSA_P256
:
1538 case ALG_ID_ECDSA_P384
:
1539 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1540 return key_export_ecc_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1541 return key_export_ecc( key
, params
->buf
, params
->len
, params
->ret_len
);
1544 case ALG_ID_RSA_SIGN
:
1545 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1546 return key_export_rsa_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1547 return key_export_rsa( key
, flags
, params
->buf
, params
->len
, params
->ret_len
);
1550 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1552 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1553 return key_export_dsa_capi_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1554 return key_export_dsa_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1556 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1557 return key_export_dsa_capi( key
, params
->buf
, params
->len
, params
->ret_len
);
1558 return STATUS_NOT_IMPLEMENTED
;
1561 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1562 return STATUS_NOT_IMPLEMENTED
;
1566 static NTSTATUS
key_asymmetric_import( void *args
)
1568 const struct key_asymmetric_import_params
*params
= args
;
1569 struct key
*key
= params
->key
;
1570 unsigned flags
= params
->flags
;
1571 gnutls_pubkey_t pubkey
;
1574 switch (key
->alg_id
)
1576 case ALG_ID_ECDH_P256
:
1577 case ALG_ID_ECDH_P384
:
1578 case ALG_ID_ECDSA_P256
:
1579 case ALG_ID_ECDSA_P384
:
1580 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1581 return key_import_ecc_public( key
, params
->buf
, params
->len
);
1582 ret
= key_import_ecc( key
, params
->buf
, params
->len
);
1586 case ALG_ID_RSA_SIGN
:
1587 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1588 return key_import_rsa_public( key
, params
->buf
, params
->len
);
1589 ret
= key_import_rsa( key
, params
->buf
, params
->len
);
1593 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1595 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1596 return key_import_dsa_capi_public( key
, params
->buf
, params
->len
);
1597 return key_import_dsa_public( key
, params
->buf
, params
->len
);
1599 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1601 ret
= key_import_dsa_capi( key
, params
->buf
, params
->len
);
1604 FIXME( "DSA private key not supported\n" );
1605 return STATUS_NOT_IMPLEMENTED
;
1608 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1609 return STATUS_NOT_IMPLEMENTED
;
1612 if (ret
) return ret
;
1614 if ((ret
= pgnutls_pubkey_init( &pubkey
)))
1616 pgnutls_perror( ret
);
1617 return STATUS_INTERNAL_ERROR
;
1620 if (pgnutls_pubkey_import_privkey( pubkey
, key_data(params
->key
)->a
.privkey
, 0, 0 ))
1622 /* Imported private key may be legitimately missing public key, so ignore the failure here. */
1623 pgnutls_pubkey_deinit( pubkey
);
1627 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1628 key_data(key
)->a
.pubkey
= pubkey
;
1630 return STATUS_SUCCESS
;
1633 static NTSTATUS
prepare_gnutls_signature_dsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1634 gnutls_datum_t
*gnutls_signature
)
1636 struct buffer buffer
;
1637 DWORD r_len
= signature_len
/ 2;
1638 DWORD s_len
= r_len
;
1639 BYTE
*r
= signature
;
1640 BYTE
*s
= signature
+ r_len
;
1642 buffer_init( &buffer
);
1643 buffer_append_asn1_r_s( &buffer
, r
, r_len
, s
, s_len
);
1646 buffer_free( &buffer
);
1647 return STATUS_NO_MEMORY
;
1650 gnutls_signature
->data
= buffer
.buffer
;
1651 gnutls_signature
->size
= buffer
.pos
;
1652 return STATUS_SUCCESS
;
1655 static NTSTATUS
prepare_gnutls_signature_rsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1656 gnutls_datum_t
*gnutls_signature
)
1658 gnutls_signature
->data
= signature
;
1659 gnutls_signature
->size
= signature_len
;
1660 return STATUS_SUCCESS
;
1663 static NTSTATUS
prepare_gnutls_signature( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1664 gnutls_datum_t
*gnutls_signature
)
1666 switch (key
->alg_id
)
1668 case ALG_ID_ECDSA_P256
:
1669 case ALG_ID_ECDSA_P384
:
1671 return prepare_gnutls_signature_dsa( key
, signature
, signature_len
, gnutls_signature
);
1674 case ALG_ID_RSA_SIGN
:
1675 return prepare_gnutls_signature_rsa( key
, signature
, signature_len
, gnutls_signature
);
1678 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1679 return STATUS_NOT_IMPLEMENTED
;
1683 static gnutls_digest_algorithm_t
get_digest_from_id( const WCHAR
*alg_id
)
1685 if (!wcscmp( alg_id
, BCRYPT_SHA1_ALGORITHM
)) return GNUTLS_DIG_SHA1
;
1686 if (!wcscmp( alg_id
, BCRYPT_SHA256_ALGORITHM
)) return GNUTLS_DIG_SHA256
;
1687 if (!wcscmp( alg_id
, BCRYPT_SHA384_ALGORITHM
)) return GNUTLS_DIG_SHA384
;
1688 if (!wcscmp( alg_id
, BCRYPT_SHA512_ALGORITHM
)) return GNUTLS_DIG_SHA512
;
1689 if (!wcscmp( alg_id
, BCRYPT_MD2_ALGORITHM
)) return GNUTLS_DIG_MD2
;
1690 if (!wcscmp( alg_id
, BCRYPT_MD5_ALGORITHM
)) return GNUTLS_DIG_MD5
;
1691 return GNUTLS_DIG_UNKNOWN
;
1694 static NTSTATUS
pubkey_set_rsa_pss_params( gnutls_pubkey_t key
, gnutls_digest_algorithm_t dig
, unsigned int salt_size
)
1696 gnutls_x509_spki_t spki
;
1699 if (((ret
= pgnutls_x509_spki_init( &spki
) < 0)))
1701 pgnutls_perror( ret
);
1702 return STATUS_INTERNAL_ERROR
;
1704 pgnutls_x509_spki_set_rsa_pss_params( spki
, dig
, salt_size
);
1705 ret
= pgnutls_pubkey_set_spki( key
, spki
, 0 );
1706 pgnutls_x509_spki_deinit( spki
);
1709 pgnutls_perror( ret
);
1710 return STATUS_INTERNAL_ERROR
;
1712 return STATUS_SUCCESS
;
1715 static NTSTATUS
key_asymmetric_verify( void *args
)
1717 const struct key_asymmetric_verify_params
*params
= args
;
1718 struct key
*key
= params
->key
;
1719 unsigned flags
= params
->flags
;
1720 gnutls_digest_algorithm_t hash_alg
;
1721 gnutls_sign_algorithm_t sign_alg
;
1722 gnutls_datum_t gnutls_hash
, gnutls_signature
;
1723 gnutls_pk_algorithm_t pk_alg
;
1727 switch (key
->alg_id
)
1729 case ALG_ID_ECDSA_P256
:
1730 case ALG_ID_ECDSA_P384
:
1732 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1734 /* only the hash size must match, not the actual hash function */
1735 switch (params
->hash_len
)
1737 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1738 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1739 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1742 FIXME( "hash size %u not yet supported\n", params
->hash_len
);
1743 return STATUS_INVALID_SIGNATURE
;
1745 pk_alg
= GNUTLS_PK_ECC
;
1749 case ALG_ID_RSA_SIGN
:
1751 if (flags
& BCRYPT_PAD_PKCS1
)
1753 BCRYPT_PKCS1_PADDING_INFO
*info
= params
->padding
;
1755 if (!info
) return STATUS_INVALID_PARAMETER
;
1756 if (!info
->pszAlgId
) return STATUS_INVALID_SIGNATURE
;
1757 if ((hash_alg
= get_digest_from_id(info
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1759 FIXME( "hash algorithm %s not supported\n", debugstr_w(info
->pszAlgId
) );
1760 return STATUS_NOT_SUPPORTED
;
1762 pk_alg
= GNUTLS_PK_RSA
;
1764 else if (flags
& BCRYPT_PAD_PSS
)
1766 BCRYPT_PSS_PADDING_INFO
*info
= params
->padding
;
1768 if (!info
) return STATUS_INVALID_PARAMETER
;
1769 if (!info
->pszAlgId
) return STATUS_INVALID_SIGNATURE
;
1770 if ((hash_alg
= get_digest_from_id(info
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1772 FIXME( "hash algorithm %s not supported\n", debugstr_w(info
->pszAlgId
) );
1773 return STATUS_NOT_SUPPORTED
;
1775 if ((status
= pubkey_set_rsa_pss_params( key_data(key
)->a
.pubkey
, hash_alg
, info
->cbSalt
))) return status
;
1776 pk_alg
= GNUTLS_PK_RSA_PSS
;
1778 else return STATUS_INVALID_PARAMETER
;
1783 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1784 if (params
->hash_len
!= 20)
1786 FIXME( "hash size %u not supported\n", params
->hash_len
);
1787 return STATUS_INVALID_PARAMETER
;
1789 hash_alg
= GNUTLS_DIG_SHA1
;
1790 pk_alg
= GNUTLS_PK_DSA
;
1794 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1795 return STATUS_NOT_IMPLEMENTED
;
1798 if ((sign_alg
= pgnutls_pk_to_sign( pk_alg
, hash_alg
)) == GNUTLS_SIGN_UNKNOWN
)
1800 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key
->alg_id
, params
->hash_len
);
1801 return STATUS_NOT_IMPLEMENTED
;
1804 if ((status
= prepare_gnutls_signature( key
, params
->signature
, params
->signature_len
, &gnutls_signature
)))
1807 gnutls_hash
.data
= params
->hash
;
1808 gnutls_hash
.size
= params
->hash_len
;
1809 ret
= pgnutls_pubkey_verify_hash2( key_data(key
)->a
.pubkey
, sign_alg
, 0, &gnutls_hash
, &gnutls_signature
);
1811 if (gnutls_signature
.data
!= params
->signature
) free( gnutls_signature
.data
);
1812 return (ret
< 0) ? STATUS_INVALID_SIGNATURE
: STATUS_SUCCESS
;
1815 static unsigned int get_signature_length( enum alg_id id
)
1819 case ALG_ID_ECDSA_P256
: return 64;
1820 case ALG_ID_ECDSA_P384
: return 96;
1821 case ALG_ID_DSA
: return 40;
1823 FIXME( "unhandled algorithm %u\n", id
);
1828 static NTSTATUS
format_gnutls_signature( enum alg_id type
, gnutls_datum_t signature
,
1829 UCHAR
*output
, ULONG output_len
, ULONG
*ret_len
)
1834 case ALG_ID_RSA_SIGN
:
1836 *ret_len
= signature
.size
;
1837 if (output_len
< signature
.size
) return STATUS_BUFFER_TOO_SMALL
;
1838 if (output
) memcpy( output
, signature
.data
, signature
.size
);
1839 return STATUS_SUCCESS
;
1841 case ALG_ID_ECDSA_P256
:
1842 case ALG_ID_ECDSA_P384
:
1846 unsigned int sig_len
= get_signature_length( type
);
1847 gnutls_datum_t r
, s
; /* format as r||s */
1849 if ((err
= pgnutls_decode_rs_value( &signature
, &r
, &s
)))
1851 pgnutls_perror( err
);
1852 return STATUS_INTERNAL_ERROR
;
1856 if (output_len
< sig_len
) return STATUS_BUFFER_TOO_SMALL
;
1858 if (r
.size
> sig_len
/ 2 + 1 || s
.size
> sig_len
/ 2 + 1)
1860 ERR( "we didn't get a correct signature\n" );
1861 return STATUS_INTERNAL_ERROR
;
1866 export_gnutls_datum( output
, sig_len
/ 2, &r
, 1 );
1867 export_gnutls_datum( output
+ sig_len
/ 2, sig_len
/ 2, &s
, 1 );
1870 free( r
.data
); free( s
.data
);
1871 return STATUS_SUCCESS
;
1874 return STATUS_INTERNAL_ERROR
;
1878 static NTSTATUS
privkey_set_rsa_pss_params( gnutls_privkey_t key
, gnutls_digest_algorithm_t dig
, unsigned int salt_size
)
1880 gnutls_x509_spki_t spki
;
1883 if (((ret
= pgnutls_x509_spki_init( &spki
) < 0)))
1885 pgnutls_perror( ret
);
1886 return STATUS_INTERNAL_ERROR
;
1888 pgnutls_x509_spki_set_rsa_pss_params( spki
, dig
, salt_size
);
1889 ret
= pgnutls_privkey_set_spki( key
, spki
, 0 );
1890 pgnutls_x509_spki_deinit( spki
);
1893 pgnutls_perror( ret
);
1894 return STATUS_INTERNAL_ERROR
;
1896 return STATUS_SUCCESS
;
1899 static NTSTATUS
key_asymmetric_sign( void *args
)
1901 const struct key_asymmetric_sign_params
*params
= args
;
1902 struct key
*key
= params
->key
;
1903 unsigned int flags
= params
->flags
, gnutls_flags
= 0;
1904 gnutls_datum_t hash
, signature
;
1905 gnutls_digest_algorithm_t hash_alg
;
1909 if (key
->alg_id
== ALG_ID_ECDSA_P256
|| key
->alg_id
== ALG_ID_ECDSA_P384
)
1911 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1912 switch (params
->input_len
)
1914 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1915 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1916 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1917 case 64: hash_alg
= GNUTLS_DIG_SHA512
; break;
1920 FIXME( "hash size %u not yet supported\n", params
->input_len
);
1921 return STATUS_INVALID_PARAMETER
;
1924 if (flags
== BCRYPT_PAD_PKCS1
)
1926 BCRYPT_PKCS1_PADDING_INFO
*pad
= params
->padding
;
1927 if (pad
&& pad
->pszAlgId
&& get_digest_from_id( pad
->pszAlgId
) != hash_alg
)
1929 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad
->pszAlgId
), hash_alg
);
1930 return STATUS_INVALID_PARAMETER
;
1934 else if (key
->alg_id
== ALG_ID_DSA
)
1936 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1937 if (params
->input_len
!= 20)
1939 FIXME( "hash size %u not supported\n", params
->input_len
);
1940 return STATUS_INVALID_PARAMETER
;
1942 hash_alg
= GNUTLS_DIG_SHA1
;
1944 else if (flags
== BCRYPT_PAD_PKCS1
)
1946 BCRYPT_PKCS1_PADDING_INFO
*pad
= params
->padding
;
1948 if (!pad
|| !pad
->pszAlgId
)
1950 WARN( "padding info not found\n" );
1951 return STATUS_INVALID_PARAMETER
;
1953 if ((hash_alg
= get_digest_from_id( pad
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1955 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad
->pszAlgId
) );
1956 return STATUS_NOT_SUPPORTED
;
1959 else if (flags
== BCRYPT_PAD_PSS
)
1961 BCRYPT_PSS_PADDING_INFO
*pad
= params
->padding
;
1963 if (!pad
|| !pad
->pszAlgId
)
1965 WARN( "padding info not found\n" );
1966 return STATUS_INVALID_PARAMETER
;
1968 if (key
->alg_id
!= ALG_ID_RSA
&& key
->alg_id
!= ALG_ID_RSA_SIGN
)
1970 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key
->alg_id
);
1971 return STATUS_NOT_SUPPORTED
;
1973 if ((hash_alg
= get_digest_from_id( pad
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1975 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad
->pszAlgId
) );
1976 return STATUS_NOT_SUPPORTED
;
1979 if ((status
= privkey_set_rsa_pss_params( key_data(key
)->a
.privkey
, hash_alg
, pad
->cbSalt
))) return status
;
1980 gnutls_flags
= GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS
;
1984 WARN( "invalid flags %#x\n", flags
);
1985 return STATUS_INVALID_PARAMETER
;
1989 FIXME( "flags %#x not implemented\n", flags
);
1990 return STATUS_NOT_IMPLEMENTED
;
1993 if (!params
->output
)
1995 *params
->ret_len
= key
->u
.a
.bitlen
/ 8;
1996 return STATUS_SUCCESS
;
1998 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
2000 hash
.data
= params
->input
;
2001 hash
.size
= params
->input_len
;
2003 signature
.data
= NULL
;
2006 if ((ret
= pgnutls_privkey_sign_hash( key_data(key
)->a
.privkey
, hash_alg
, gnutls_flags
, &hash
, &signature
)))
2008 pgnutls_perror( ret
);
2009 return STATUS_INTERNAL_ERROR
;
2012 status
= format_gnutls_signature( key
->alg_id
, signature
, params
->output
, params
->output_len
, params
->ret_len
);
2013 free( signature
.data
);
2017 static NTSTATUS
key_asymmetric_destroy( void *args
)
2019 struct key
*key
= args
;
2021 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
2022 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
2023 return STATUS_SUCCESS
;
2026 static NTSTATUS
dup_privkey( struct key
*key_orig
, struct key
*key_copy
)
2028 gnutls_privkey_t privkey
;
2031 if ((ret
= pgnutls_privkey_init( &privkey
)))
2033 pgnutls_perror( ret
);
2034 return STATUS_INTERNAL_ERROR
;
2037 switch (key_orig
->alg_id
)
2040 case ALG_ID_RSA_SIGN
:
2042 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
2043 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key_orig
)->a
.privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
2045 pgnutls_perror( ret
);
2046 return STATUS_INTERNAL_ERROR
;
2048 ret
= pgnutls_privkey_import_rsa_raw( privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
);
2049 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
2050 free( e1
.data
); free( e2
.data
);
2053 pgnutls_perror( ret
);
2054 return STATUS_INTERNAL_ERROR
;
2060 gnutls_datum_t p
, q
, g
, y
, x
;
2061 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key_orig
)->a
.privkey
, &p
, &q
, &g
, &y
, &x
)))
2063 pgnutls_perror( ret
);
2064 return STATUS_INTERNAL_ERROR
;
2066 ret
= pgnutls_privkey_import_dsa_raw( privkey
, &p
, &q
, &g
, &y
, &x
);
2067 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
2070 pgnutls_perror( ret
);
2071 return STATUS_INTERNAL_ERROR
;
2073 key_copy
->u
.a
.dss_seed
= key_orig
->u
.a
.dss_seed
;
2076 case ALG_ID_ECDH_P256
:
2077 case ALG_ID_ECDH_P384
:
2078 case ALG_ID_ECDSA_P256
:
2079 case ALG_ID_ECDSA_P384
:
2081 gnutls_ecc_curve_t curve
;
2082 gnutls_datum_t x
, y
, k
;
2083 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key_orig
)->a
.privkey
, &curve
, &x
, &y
, &k
)))
2085 pgnutls_perror( ret
);
2086 return STATUS_INTERNAL_ERROR
;
2088 ret
= pgnutls_privkey_import_ecc_raw( privkey
, curve
, &x
, &y
, &k
);
2089 free( x
.data
); free( y
.data
); free( k
.data
);
2092 pgnutls_perror( ret
);
2093 return STATUS_INTERNAL_ERROR
;
2098 ERR( "unhandled algorithm %u\n", key_orig
->alg_id
);
2099 return STATUS_INTERNAL_ERROR
;
2102 key_data(key_copy
)->a
.privkey
= privkey
;
2103 return STATUS_SUCCESS
;
2106 static NTSTATUS
dup_pubkey( struct key
*key_orig
, struct key
*key_copy
)
2108 gnutls_pubkey_t pubkey
;
2111 if ((ret
= pgnutls_pubkey_init( &pubkey
)))
2113 pgnutls_perror( ret
);
2114 return STATUS_INTERNAL_ERROR
;
2117 switch (key_orig
->alg_id
)
2120 case ALG_ID_RSA_SIGN
:
2122 gnutls_datum_t m
, e
;
2123 if ((ret
= pgnutls_pubkey_export_rsa_raw( key_data(key_orig
)->a
.pubkey
, &m
, &e
)))
2125 pgnutls_perror( ret
);
2126 return STATUS_INTERNAL_ERROR
;
2128 ret
= pgnutls_pubkey_import_rsa_raw( pubkey
, &m
, &e
);
2129 free( m
.data
); free( e
.data
);
2132 pgnutls_perror( ret
);
2133 return STATUS_INTERNAL_ERROR
;
2139 gnutls_datum_t p
, q
, g
, y
;
2140 if ((ret
= pgnutls_pubkey_export_dsa_raw( key_data(key_orig
)->a
.pubkey
, &p
, &q
, &g
, &y
)))
2142 pgnutls_perror( ret
);
2143 return STATUS_INTERNAL_ERROR
;
2145 ret
= pgnutls_pubkey_import_dsa_raw( pubkey
, &p
, &q
, &g
, &y
);
2146 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
2149 pgnutls_perror( ret
);
2150 return STATUS_INTERNAL_ERROR
;
2152 key_copy
->u
.a
.dss_seed
= key_orig
->u
.a
.dss_seed
;
2155 case ALG_ID_ECDH_P256
:
2156 case ALG_ID_ECDH_P384
:
2157 case ALG_ID_ECDSA_P256
:
2158 case ALG_ID_ECDSA_P384
:
2160 gnutls_ecc_curve_t curve
;
2161 gnutls_datum_t x
, y
;
2162 if ((ret
= pgnutls_pubkey_export_ecc_raw( key_data(key_orig
)->a
.pubkey
, &curve
, &x
, &y
)))
2164 pgnutls_perror( ret
);
2165 return STATUS_INTERNAL_ERROR
;
2167 ret
= pgnutls_pubkey_import_ecc_raw( pubkey
, curve
, &x
, &y
);
2168 free( x
.data
); free( y
.data
);
2171 pgnutls_perror( ret
);
2172 return STATUS_INTERNAL_ERROR
;
2177 ERR( "unhandled algorithm %u\n", key_orig
->alg_id
);
2178 return STATUS_INTERNAL_ERROR
;
2181 key_data(key_copy
)->a
.pubkey
= pubkey
;
2182 return STATUS_SUCCESS
;
2185 static NTSTATUS
key_asymmetric_duplicate( void *args
)
2187 const struct key_asymmetric_duplicate_params
*params
= args
;
2190 if (key_data(params
->key_orig
)->a
.privkey
&& (status
= dup_privkey( params
->key_orig
, params
->key_copy
)))
2193 if (key_data(params
->key_orig
)->a
.pubkey
&& (status
= dup_pubkey( params
->key_orig
, params
->key_copy
)))
2196 return STATUS_SUCCESS
;
2199 static NTSTATUS
key_asymmetric_decrypt( void *args
)
2201 const struct key_asymmetric_decrypt_params
*params
= args
;
2202 gnutls_datum_t e
, d
= { 0 };
2203 NTSTATUS status
= STATUS_SUCCESS
;
2206 e
.data
= params
->input
;
2207 e
.size
= params
->input_len
;
2208 if ((ret
= pgnutls_privkey_decrypt_data( key_data(params
->key
)->a
.privkey
, 0, &e
, &d
)))
2210 pgnutls_perror( ret
);
2211 return STATUS_INTERNAL_ERROR
;
2214 *params
->ret_len
= d
.size
;
2215 if (params
->output_len
>= d
.size
) memcpy( params
->output
, d
.data
, *params
->ret_len
);
2216 else status
= STATUS_BUFFER_TOO_SMALL
;
2222 static NTSTATUS
key_asymmetric_encrypt( void *args
)
2224 const struct key_asymmetric_encrypt_params
*params
= args
;
2225 gnutls_datum_t d
, e
= { 0 };
2226 NTSTATUS status
= STATUS_SUCCESS
;
2229 if (!key_data(params
->key
)->a
.pubkey
) return STATUS_INVALID_HANDLE
;
2231 d
.data
= params
->input
;
2232 d
.size
= params
->input_len
;
2233 if ((ret
= pgnutls_pubkey_encrypt_data(key_data(params
->key
)->a
.pubkey
, 0, &d
, &e
)))
2235 pgnutls_perror( ret
);
2236 return STATUS_INTERNAL_ERROR
;
2239 *params
->ret_len
= e
.size
;
2240 if (params
->output_len
>= e
.size
) memcpy( params
->output
, e
.data
, *params
->ret_len
);
2241 else if (params
->output_len
== 0) status
= STATUS_SUCCESS
;
2242 else status
= STATUS_BUFFER_TOO_SMALL
;
2248 const unixlib_entry_t __wine_unix_call_funcs
[] =
2250 gnutls_process_attach
,
2251 gnutls_process_detach
,
2252 key_symmetric_vector_reset
,
2253 key_symmetric_set_auth_data
,
2254 key_symmetric_encrypt
,
2255 key_symmetric_decrypt
,
2256 key_symmetric_get_tag
,
2257 key_symmetric_destroy
,
2258 key_asymmetric_generate
,
2259 key_asymmetric_decrypt
,
2260 key_asymmetric_encrypt
,
2261 key_asymmetric_duplicate
,
2262 key_asymmetric_sign
,
2263 key_asymmetric_verify
,
2264 key_asymmetric_destroy
,
2265 key_asymmetric_export
,
2266 key_asymmetric_import
2271 typedef ULONG PTR32
;
2273 struct key_symmetric32
2275 enum chain_mode mode
;
2284 struct key_asymmetric32
2286 ULONG bitlen
; /* ignored for ECC keys */
2295 UINT64
private[2]; /* private data for backend */
2298 struct key_symmetric32 s
;
2299 struct key_asymmetric32 a
;
2305 BCRYPT_PKCS1_PADDING_INFO pkcs1
;
2306 BCRYPT_PSS_PADDING_INFO pss
;
2322 static union padding
*get_padding( union padding32
*padding32
, union padding
*padding
, ULONG flags
)
2324 if (!padding32
) return NULL
;
2328 case BCRYPT_PAD_PKCS1
:
2329 padding
->pkcs1
.pszAlgId
= ULongToPtr( padding32
->pkcs1
.pszAlgId
);
2331 case BCRYPT_PAD_PSS
:
2332 padding
->pss
.pszAlgId
= ULongToPtr( padding32
->pss
.pszAlgId
);
2333 padding
->pss
.cbSalt
= padding32
->pss
.cbSalt
;
2341 static struct key
*get_symmetric_key( struct key32
*key32
, struct key
*key
)
2343 key
->hdr
= key32
->hdr
;
2344 key
->alg_id
= key32
->alg_id
;
2345 key
->private[0] = key32
->private[0];
2346 key
->private[1] = key32
->private[1];
2347 key
->u
.s
.mode
= key32
->u
.s
.mode
;
2348 key
->u
.s
.block_size
= key32
->u
.s
.block_size
;
2349 key
->u
.s
.vector
= ULongToPtr(key32
->u
.s
.vector
);
2350 key
->u
.s
.vector_len
= key32
->u
.s
.vector_len
;
2351 key
->u
.s
.secret
= ULongToPtr(key32
->u
.s
.secret
);
2352 key
->u
.s
.secret_len
= key32
->u
.s
.secret_len
;
2356 static struct key
*get_asymmetric_key( struct key32
*key32
, struct key
*key
)
2358 key
->hdr
= key32
->hdr
;
2359 key
->alg_id
= key32
->alg_id
;
2360 key
->private[0] = key32
->private[0];
2361 key
->private[1] = key32
->private[1];
2362 key
->u
.a
.bitlen
= key32
->u
.a
.bitlen
;
2363 key
->u
.a
.flags
= key32
->u
.a
.flags
;
2364 key
->u
.a
.dss_seed
= key32
->u
.a
.dss_seed
;
2368 static void put_symmetric_key32( struct key
*key
, struct key32
*key32
)
2370 key32
->private[0] = key
->private[0];
2371 key32
->private[1] = key
->private[1];
2374 static void put_asymmetric_key32( struct key
*key
, struct key32
*key32
)
2376 key32
->private[0] = key
->private[0];
2377 key32
->private[1] = key
->private[1];
2378 key32
->u
.a
.flags
= key
->u
.a
.flags
;
2379 key32
->u
.a
.dss_seed
= key
->u
.a
.dss_seed
;
2382 static NTSTATUS
wow64_key_symmetric_vector_reset( void *args
)
2386 struct key32
*key32
= args
;
2388 ret
= key_symmetric_vector_reset( get_symmetric_key( key32
, &key
));
2389 put_symmetric_key32( &key
, key32
);
2393 static NTSTATUS
wow64_key_symmetric_set_auth_data( void *args
)
2400 } const *params32
= args
;
2404 struct key32
*key32
= ULongToPtr( params32
->key
);
2405 struct key_symmetric_set_auth_data_params params
=
2407 get_symmetric_key( key32
, &key
),
2408 ULongToPtr(params32
->auth_data
),
2412 ret
= key_symmetric_set_auth_data( ¶ms
);
2413 put_symmetric_key32( &key
, key32
);
2417 static NTSTATUS
wow64_key_symmetric_encrypt( void *args
)
2426 } const *params32
= args
;
2430 struct key32
*key32
= ULongToPtr( params32
->key
);
2431 struct key_symmetric_encrypt_params params
=
2433 get_symmetric_key( key32
, &key
),
2434 ULongToPtr(params32
->input
),
2435 params32
->input_len
,
2436 ULongToPtr(params32
->output
),
2437 params32
->output_len
2440 ret
= key_symmetric_encrypt( ¶ms
);
2441 put_symmetric_key32( &key
, key32
);
2445 static NTSTATUS
wow64_key_symmetric_decrypt( void *args
)
2454 } const *params32
= args
;
2458 struct key32
*key32
= ULongToPtr( params32
->key
);
2459 struct key_symmetric_decrypt_params params
=
2461 get_symmetric_key( key32
, &key
),
2462 ULongToPtr(params32
->input
),
2463 params32
->input_len
,
2464 ULongToPtr(params32
->output
),
2465 params32
->output_len
2468 ret
= key_symmetric_decrypt( ¶ms
);
2469 put_symmetric_key32( &key
, key32
);
2473 static NTSTATUS
wow64_key_symmetric_get_tag( void *args
)
2480 } const *params32
= args
;
2484 struct key32
*key32
= ULongToPtr( params32
->key
);
2485 struct key_symmetric_get_tag_params params
=
2487 get_symmetric_key( key32
, &key
),
2488 ULongToPtr(params32
->tag
),
2492 ret
= key_symmetric_get_tag( ¶ms
);
2493 put_symmetric_key32( &key
, key32
);
2497 static NTSTATUS
wow64_key_symmetric_destroy( void *args
)
2499 struct key32
*key32
= args
;
2502 return key_symmetric_destroy( get_symmetric_key( key32
, &key
));
2505 static NTSTATUS
wow64_key_asymmetric_generate( void *args
)
2507 struct key32
*key32
= args
;
2511 ret
= key_asymmetric_generate( get_asymmetric_key( key32
, &key
));
2512 put_asymmetric_key32( &key
, key32
);
2516 static NTSTATUS
wow64_key_asymmetric_decrypt( void *args
)
2526 } const *params32
= args
;
2530 struct key32
*key32
= ULongToPtr( params32
->key
);
2531 struct key_asymmetric_decrypt_params params
=
2533 get_asymmetric_key( key32
, &key
),
2534 ULongToPtr(params32
->input
),
2535 params32
->input_len
,
2536 ULongToPtr(params32
->output
),
2537 params32
->output_len
,
2538 ULongToPtr(params32
->ret_len
)
2541 ret
= key_asymmetric_decrypt( ¶ms
);
2542 put_asymmetric_key32( &key
, key32
);
2546 static NTSTATUS
wow64_key_asymmetric_encrypt( void *args
)
2556 } const *params32
= args
;
2560 struct key32
*key32
= ULongToPtr( params32
->key
);
2561 struct key_asymmetric_encrypt_params params
=
2563 get_asymmetric_key( key32
, &key
),
2564 ULongToPtr(params32
->input
),
2565 params32
->input_len
,
2566 ULongToPtr(params32
->output
),
2567 params32
->output_len
,
2568 ULongToPtr(params32
->ret_len
)
2571 ret
= key_asymmetric_encrypt( ¶ms
);
2572 put_asymmetric_key32( &key
, key32
);
2576 static NTSTATUS
wow64_key_asymmetric_duplicate( void *args
)
2582 } const *params32
= args
;
2585 struct key key_orig
, key_copy
;
2586 struct key32
*key_orig32
= ULongToPtr( params32
->key_orig
);
2587 struct key32
*key_copy32
= ULongToPtr( params32
->key_copy
);
2588 struct key_asymmetric_duplicate_params params
=
2590 get_asymmetric_key( key_orig32
, &key_orig
),
2591 get_asymmetric_key( key_copy32
, &key_copy
)
2594 ret
= key_asymmetric_duplicate( ¶ms
);
2595 put_asymmetric_key32( &key_copy
, key_copy32
);
2599 static NTSTATUS
wow64_key_asymmetric_sign( void *args
)
2611 } const *params32
= args
;
2615 union padding padding
;
2616 struct key32
*key32
= ULongToPtr( params32
->key
);
2617 struct key_asymmetric_sign_params params
=
2619 get_asymmetric_key( key32
, &key
),
2620 get_padding(ULongToPtr( params32
->padding
), &padding
, params32
->flags
),
2621 ULongToPtr(params32
->input
),
2622 params32
->input_len
,
2623 ULongToPtr(params32
->output
),
2624 params32
->output_len
,
2625 ULongToPtr(params32
->ret_len
),
2629 ret
= key_asymmetric_sign( ¶ms
);
2630 put_asymmetric_key32( &key
, key32
);
2634 static NTSTATUS
wow64_key_asymmetric_verify( void *args
)
2643 ULONG signature_len
;
2645 } const *params32
= args
;
2649 union padding padding
;
2650 struct key32
*key32
= ULongToPtr( params32
->key
);
2651 struct key_asymmetric_verify_params params
=
2653 get_asymmetric_key( key32
, &key
),
2654 get_padding(ULongToPtr( params32
->padding
), &padding
, params32
->flags
),
2655 ULongToPtr(params32
->hash
),
2657 ULongToPtr(params32
->signature
),
2658 params32
->signature_len
,
2662 ret
= key_asymmetric_verify( ¶ms
);
2663 put_asymmetric_key32( &key
, key32
);
2667 static NTSTATUS
wow64_key_asymmetric_destroy( void *args
)
2669 struct key32
*key32
= args
;
2672 return key_asymmetric_destroy( get_asymmetric_key( key32
, &key
));
2675 static NTSTATUS
wow64_key_asymmetric_export( void *args
)
2684 } const *params32
= args
;
2688 struct key32
*key32
= ULongToPtr( params32
->key
);
2689 struct key_asymmetric_export_params params
=
2691 get_asymmetric_key( key32
, &key
),
2693 ULongToPtr(params32
->buf
),
2695 ULongToPtr(params32
->ret_len
),
2698 ret
= key_asymmetric_export( ¶ms
);
2699 put_asymmetric_key32( &key
, key32
);
2703 static NTSTATUS
wow64_key_asymmetric_import( void *args
)
2711 } const *params32
= args
;
2715 struct key32
*key32
= ULongToPtr( params32
->key
);
2716 struct key_asymmetric_import_params params
=
2718 get_asymmetric_key( key32
, &key
),
2720 ULongToPtr(params32
->buf
),
2724 ret
= key_asymmetric_import( ¶ms
);
2725 put_asymmetric_key32( &key
, key32
);
2729 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
2731 gnutls_process_attach
,
2732 gnutls_process_detach
,
2733 wow64_key_symmetric_vector_reset
,
2734 wow64_key_symmetric_set_auth_data
,
2735 wow64_key_symmetric_encrypt
,
2736 wow64_key_symmetric_decrypt
,
2737 wow64_key_symmetric_get_tag
,
2738 wow64_key_symmetric_destroy
,
2739 wow64_key_asymmetric_generate
,
2740 wow64_key_asymmetric_decrypt
,
2741 wow64_key_asymmetric_encrypt
,
2742 wow64_key_asymmetric_duplicate
,
2743 wow64_key_asymmetric_sign
,
2744 wow64_key_asymmetric_verify
,
2745 wow64_key_asymmetric_destroy
,
2746 wow64_key_asymmetric_export
,
2747 wow64_key_asymmetric_import
2752 #endif /* HAVE_GNUTLS_CIPHER_INIT */