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
);
716 else if (key_data(key
)->a
.privkey
)
717 ret
= pgnutls_privkey_export_rsa_raw( key_data(key
)->a
.privkey
, &m
, &e
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
719 return STATUS_INVALID_PARAMETER
;
723 pgnutls_perror( ret
);
724 return STATUS_INTERNAL_ERROR
;
727 *ret_len
= sizeof(*rsa_blob
) + EXPORT_SIZE( e
, size
, 0 ) + EXPORT_SIZE( m
, size
, 1 );
728 if (len
>= *ret_len
&& buf
)
730 dst
= (UCHAR
*)(rsa_blob
+ 1);
731 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, size
, &e
, 0 );
733 dst
+= rsa_blob
->cbPublicExp
;
734 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, size
, &m
, 1 );
736 rsa_blob
->Magic
= BCRYPT_RSAPUBLIC_MAGIC
;
737 rsa_blob
->BitLength
= key
->u
.a
.bitlen
;
738 rsa_blob
->cbPrime1
= 0;
739 rsa_blob
->cbPrime2
= 0;
742 free( e
.data
); free( m
.data
);
743 return STATUS_SUCCESS
;
746 static NTSTATUS
key_export_ecc_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
748 BCRYPT_ECCKEY_BLOB
*ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
749 gnutls_ecc_curve_t curve
;
757 case ALG_ID_ECDH_P256
:
758 magic
= BCRYPT_ECDH_PUBLIC_P256_MAGIC
;
762 case ALG_ID_ECDH_P384
:
763 magic
= BCRYPT_ECDH_PUBLIC_P384_MAGIC
;
767 case ALG_ID_ECDSA_P256
:
768 magic
= BCRYPT_ECDSA_PUBLIC_P256_MAGIC
;
772 case ALG_ID_ECDSA_P384
:
773 magic
= BCRYPT_ECDSA_PUBLIC_P384_MAGIC
;
778 FIXME( "algorithm %u not supported\n", key
->alg_id
);
779 return STATUS_NOT_IMPLEMENTED
;
782 if (key_data(key
)->a
.pubkey
)
783 ret
= pgnutls_pubkey_export_ecc_raw( key_data(key
)->a
.pubkey
, &curve
, &x
, &y
);
784 else if (key_data(key
)->a
.privkey
)
785 ret
= pgnutls_privkey_export_ecc_raw( key_data(key
)->a
.privkey
, &curve
, &x
, &y
, NULL
);
787 return STATUS_INVALID_PARAMETER
;
791 pgnutls_perror( ret
);
792 return STATUS_INTERNAL_ERROR
;
795 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
&& curve
!= GNUTLS_ECC_CURVE_SECP384R1
)
797 FIXME( "curve %u not supported\n", curve
);
798 free( x
.data
); free( y
.data
);
799 return STATUS_NOT_IMPLEMENTED
;
802 *ret_len
= sizeof(*ecc_blob
) + EXPORT_SIZE( x
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
803 if (len
>= *ret_len
&& buf
)
805 ecc_blob
->dwMagic
= magic
;
806 ecc_blob
->cbKey
= size
;
808 dst
= (UCHAR
*)(ecc_blob
+ 1);
809 dst
+= export_gnutls_datum( dst
, size
, &x
, 1 );
810 export_gnutls_datum( dst
, size
, &y
, 1 );
813 free( x
.data
); free( y
.data
);
814 return STATUS_SUCCESS
;
817 static NTSTATUS
key_export_dsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
819 BCRYPT_DSA_KEY_BLOB
*dsa_blob
= (BCRYPT_DSA_KEY_BLOB
*)buf
;
820 gnutls_datum_t p
, q
, g
, y
;
821 ULONG size
= key
->u
.a
.bitlen
/ 8;
822 NTSTATUS status
= STATUS_SUCCESS
;
826 if (key
->u
.a
.bitlen
> 1024)
828 FIXME( "bitlen > 1024 not supported\n" );
829 return STATUS_NOT_IMPLEMENTED
;
832 if (key_data(key
)->a
.pubkey
)
833 ret
= pgnutls_pubkey_export_dsa_raw( key_data(key
)->a
.pubkey
, &p
, &q
, &g
, &y
);
834 else if (key_data(key
)->a
.privkey
)
835 ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->a
.privkey
, &p
, &q
, &g
, &y
, NULL
);
837 return STATUS_INVALID_PARAMETER
;
841 pgnutls_perror( ret
);
842 return STATUS_INTERNAL_ERROR
;
845 if (EXPORT_SIZE( q
, sizeof(dsa_blob
->q
), 1 ) > sizeof(dsa_blob
->q
))
847 status
= STATUS_INVALID_PARAMETER
;
851 *ret_len
= sizeof(*dsa_blob
) + EXPORT_SIZE( p
, size
, 1 ) + EXPORT_SIZE( g
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
852 if (len
>= *ret_len
&& buf
)
854 dst
= (UCHAR
*)(dsa_blob
+ 1);
855 dst
+= export_gnutls_datum( dst
, size
, &p
, 1 );
856 dst
+= export_gnutls_datum( dst
, size
, &g
, 1 );
857 export_gnutls_datum( dst
, size
, &y
, 1 );
860 export_gnutls_datum( dst
, sizeof(dsa_blob
->q
), &q
, 1 );
862 dsa_blob
->dwMagic
= BCRYPT_DSA_PUBLIC_MAGIC
;
863 dsa_blob
->cbKey
= size
;
864 memset( dsa_blob
->Count
, 0, sizeof(dsa_blob
->Count
) ); /* FIXME */
865 memset( dsa_blob
->Seed
, 0, sizeof(dsa_blob
->Seed
) ); /* FIXME */
869 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
873 static void reverse_bytes( UCHAR
*buf
, ULONG len
)
878 for (i
= 0; i
< len
/ 2; ++i
)
881 buf
[i
] = buf
[len
- i
- 1];
882 buf
[len
- i
- 1] = tmp
;
887 static NTSTATUS
key_export_dsa_capi_public( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
889 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
891 gnutls_datum_t p
, q
, g
, y
;
892 ULONG size
= key
->u
.a
.bitlen
/ 8;
893 NTSTATUS status
= STATUS_SUCCESS
;
897 if (key
->u
.a
.bitlen
> 1024)
899 FIXME( "bitlen > 1024 not supported\n" );
900 return STATUS_NOT_IMPLEMENTED
;
903 if (key_data(key
)->a
.pubkey
)
904 ret
= pgnutls_pubkey_export_dsa_raw( key_data(key
)->a
.pubkey
, &p
, &q
, &g
, &y
);
905 else if (key_data(key
)->a
.privkey
)
906 ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->a
.privkey
, &p
, &q
, &g
, &y
, NULL
);
908 return STATUS_INVALID_PARAMETER
;
912 pgnutls_perror( ret
);
913 return STATUS_INTERNAL_ERROR
;
916 if (EXPORT_SIZE( q
, Q_SIZE
, 1 ) > Q_SIZE
)
918 status
= STATUS_INVALID_PARAMETER
;
922 *ret_len
= sizeof(*hdr
) + sizeof(*dsskey
) + sizeof(key
->u
.a
.dss_seed
) +
923 EXPORT_SIZE( p
, size
, 1 ) + Q_SIZE
+ EXPORT_SIZE( g
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 );
924 if (len
>= *ret_len
&& buf
)
926 hdr
->bType
= PUBLICKEYBLOB
;
929 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
931 dsskey
= (DSSPUBKEY
*)(hdr
+ 1);
932 dsskey
->magic
= MAGIC_DSS1
;
933 dsskey
->bitlen
= key
->u
.a
.bitlen
;
935 dst
= (UCHAR
*)(dsskey
+ 1);
936 export_gnutls_datum( dst
, size
, &p
, 1 );
937 reverse_bytes( dst
, size
);
940 export_gnutls_datum( dst
, Q_SIZE
, &q
, 1 );
941 reverse_bytes( dst
, Q_SIZE
);
944 export_gnutls_datum( dst
, size
, &g
, 1 );
945 reverse_bytes( dst
, size
);
948 export_gnutls_datum( dst
, size
, &y
, 1 );
949 reverse_bytes( dst
, size
);
952 memcpy( dst
, &key
->u
.a
.dss_seed
, sizeof(key
->u
.a
.dss_seed
) );
956 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
960 static NTSTATUS
key_asymmetric_generate( void *args
)
962 struct key
*key
= args
;
963 gnutls_pk_algorithm_t pk_alg
;
964 gnutls_privkey_t privkey
;
965 gnutls_pubkey_t pubkey
;
969 if (!libgnutls_handle
) return STATUS_INTERNAL_ERROR
;
970 if (key_data(key
)->a
.privkey
) return STATUS_INVALID_HANDLE
;
975 case ALG_ID_RSA_SIGN
:
976 pk_alg
= GNUTLS_PK_RSA
;
977 bitlen
= key
->u
.a
.bitlen
;
981 pk_alg
= GNUTLS_PK_DSA
;
982 bitlen
= key
->u
.a
.bitlen
;
985 case ALG_ID_ECDH_P256
:
986 case ALG_ID_ECDSA_P256
:
987 pk_alg
= GNUTLS_PK_ECC
; /* compatible with ECDSA and ECDH */
988 bitlen
= GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1
);
991 case ALG_ID_ECDH_P384
:
992 case ALG_ID_ECDSA_P384
:
993 pk_alg
= GNUTLS_PK_ECC
; /* compatible with ECDSA and ECDH */
994 bitlen
= GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1
);
998 FIXME( "algorithm %u not supported\n", key
->alg_id
);
999 return STATUS_NOT_SUPPORTED
;
1002 if ((ret
= pgnutls_privkey_init( &privkey
)))
1004 pgnutls_perror( ret
);
1005 return STATUS_INTERNAL_ERROR
;
1007 if ((ret
= pgnutls_pubkey_init( &pubkey
)))
1009 pgnutls_perror( ret
);
1010 pgnutls_privkey_deinit( privkey
);
1011 return STATUS_INTERNAL_ERROR
;
1014 if ((ret
= pgnutls_privkey_generate( privkey
, pk_alg
, bitlen
, 0 )))
1016 pgnutls_perror( ret
);
1017 pgnutls_privkey_deinit( privkey
);
1018 pgnutls_pubkey_deinit( pubkey
);
1019 return STATUS_INTERNAL_ERROR
;
1021 if ((ret
= pgnutls_pubkey_import_privkey( pubkey
, privkey
, 0, 0 )))
1023 pgnutls_perror( ret
);
1024 pgnutls_privkey_deinit( privkey
);
1025 pgnutls_pubkey_deinit( pubkey
);
1026 return STATUS_INTERNAL_ERROR
;
1029 key_data(key
)->a
.privkey
= privkey
;
1030 key_data(key
)->a
.pubkey
= pubkey
;
1031 return STATUS_SUCCESS
;
1034 static NTSTATUS
key_export_ecc( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1036 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1037 gnutls_ecc_curve_t curve
;
1038 gnutls_datum_t x
, y
, d
;
1043 switch (key
->alg_id
)
1045 case ALG_ID_ECDH_P256
:
1046 magic
= BCRYPT_ECDH_PRIVATE_P256_MAGIC
;
1050 case ALG_ID_ECDH_P384
:
1051 magic
= BCRYPT_ECDH_PRIVATE_P384_MAGIC
;
1055 case ALG_ID_ECDSA_P256
:
1056 magic
= BCRYPT_ECDSA_PRIVATE_P256_MAGIC
;
1060 case ALG_ID_ECDSA_P384
:
1061 magic
= BCRYPT_ECDSA_PRIVATE_P384_MAGIC
;
1066 FIXME( "algorithm %u does not yet support exporting ecc blob\n", key
->alg_id
);
1067 return STATUS_NOT_IMPLEMENTED
;
1070 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1072 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key
)->a
.privkey
, &curve
, &x
, &y
, &d
)))
1074 pgnutls_perror( ret
);
1075 return STATUS_INTERNAL_ERROR
;
1078 if (curve
!= GNUTLS_ECC_CURVE_SECP256R1
)
1080 FIXME( "curve %u not supported\n", curve
);
1081 free( x
.data
); free( y
.data
); free( d
.data
);
1082 return STATUS_NOT_IMPLEMENTED
;
1085 *ret_len
= sizeof(*ecc_blob
) + EXPORT_SIZE( x
, size
, 1 ) + EXPORT_SIZE( y
, size
, 1 ) + EXPORT_SIZE( d
, size
, 1 );
1086 if (len
>= *ret_len
&& buf
)
1088 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1089 ecc_blob
->dwMagic
= magic
;
1090 ecc_blob
->cbKey
= size
;
1092 dst
= (UCHAR
*)(ecc_blob
+ 1);
1093 dst
+= export_gnutls_datum( dst
, size
, &x
, 1 );
1094 dst
+= export_gnutls_datum( dst
, size
, &y
, 1 );
1095 export_gnutls_datum( dst
, size
, &d
, 1 );
1098 free( x
.data
); free( y
.data
); free( d
.data
);
1099 return STATUS_SUCCESS
;
1102 static NTSTATUS
key_import_ecc( struct key
*key
, UCHAR
*buf
, ULONG len
)
1104 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1105 gnutls_ecc_curve_t curve
;
1106 gnutls_privkey_t handle
;
1107 gnutls_datum_t x
, y
, k
;
1110 switch (key
->alg_id
)
1112 case ALG_ID_ECDH_P256
:
1113 case ALG_ID_ECDSA_P256
:
1114 curve
= GNUTLS_ECC_CURVE_SECP256R1
;
1117 case ALG_ID_ECDH_P384
:
1118 case ALG_ID_ECDSA_P384
:
1119 curve
= GNUTLS_ECC_CURVE_SECP384R1
;
1123 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1124 return STATUS_NOT_IMPLEMENTED
;
1127 if ((ret
= pgnutls_privkey_init( &handle
)))
1129 pgnutls_perror( ret
);
1130 return STATUS_INTERNAL_ERROR
;
1133 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1134 x
.data
= (unsigned char *)(ecc_blob
+ 1);
1135 x
.size
= ecc_blob
->cbKey
;
1136 y
.data
= x
.data
+ ecc_blob
->cbKey
;
1137 y
.size
= ecc_blob
->cbKey
;
1138 k
.data
= y
.data
+ ecc_blob
->cbKey
;
1139 k
.size
= ecc_blob
->cbKey
;
1141 if ((ret
= pgnutls_privkey_import_ecc_raw( handle
, curve
, &x
, &y
, &k
)))
1143 pgnutls_perror( ret
);
1144 pgnutls_privkey_deinit( handle
);
1145 return STATUS_INTERNAL_ERROR
;
1148 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1149 key_data(key
)->a
.privkey
= handle
;
1150 return STATUS_SUCCESS
;
1153 static NTSTATUS
key_export_rsa( struct key
*key
, ULONG flags
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1155 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1156 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
1157 ULONG size
= key
->u
.a
.bitlen
/ 8;
1158 BOOL full
= (flags
& KEY_EXPORT_FLAG_RSA_FULL
);
1162 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1164 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key
)->a
.privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
1166 pgnutls_perror( ret
);
1167 return STATUS_INTERNAL_ERROR
;
1170 *ret_len
= sizeof(*rsa_blob
) + EXPORT_SIZE( e
, size
, 0 ) + EXPORT_SIZE( m
, size
, 1 ) +
1171 EXPORT_SIZE( p
, size
/ 2, 1 ) + EXPORT_SIZE( q
, size
/ 2, 1 );
1173 if (full
) *ret_len
+= EXPORT_SIZE( e1
, size
/ 2, 1 ) + EXPORT_SIZE( e2
, size
/ 2, 1 ) +
1174 EXPORT_SIZE( u
, size
/ 2, 1 ) + EXPORT_SIZE( d
, size
, 1 );
1176 if (len
>= *ret_len
&& buf
)
1178 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1179 rsa_blob
->Magic
= full
? BCRYPT_RSAFULLPRIVATE_MAGIC
: BCRYPT_RSAPRIVATE_MAGIC
;
1180 rsa_blob
->BitLength
= key
->u
.a
.bitlen
;
1182 dst
= (UCHAR
*)(rsa_blob
+ 1);
1183 rsa_blob
->cbPublicExp
= export_gnutls_datum( dst
, size
, &e
, 0 );
1185 dst
+= rsa_blob
->cbPublicExp
;
1186 rsa_blob
->cbModulus
= export_gnutls_datum( dst
, size
, &m
, 1 );
1188 dst
+= rsa_blob
->cbModulus
;
1189 rsa_blob
->cbPrime1
= export_gnutls_datum( dst
, size
/ 2, &p
, 1 );
1191 dst
+= rsa_blob
->cbPrime1
;
1192 rsa_blob
->cbPrime2
= export_gnutls_datum( dst
, size
/ 2, &q
, 1 );
1196 dst
+= rsa_blob
->cbPrime2
;
1197 export_gnutls_datum( dst
, size
/ 2, &e1
, 1 );
1199 dst
+= rsa_blob
->cbPrime1
;
1200 export_gnutls_datum( dst
, size
/ 2, &e2
, 1 );
1202 dst
+= rsa_blob
->cbPrime2
;
1203 export_gnutls_datum( dst
, size
/ 2, &u
, 1 );
1205 dst
+= rsa_blob
->cbPrime1
;
1206 export_gnutls_datum( dst
, size
, &d
, 1 );
1210 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
1211 free( e1
.data
); free( e2
.data
);
1212 return STATUS_SUCCESS
;
1215 static NTSTATUS
key_import_rsa( struct key
*key
, UCHAR
*buf
, ULONG len
)
1217 BCRYPT_RSAKEY_BLOB
*rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1218 gnutls_datum_t m
, e
, p
, q
;
1219 gnutls_privkey_t handle
;
1222 if ((ret
= pgnutls_privkey_init( &handle
)))
1224 pgnutls_perror( ret
);
1225 return STATUS_INTERNAL_ERROR
;
1228 e
.data
= (unsigned char *)(rsa_blob
+ 1);
1229 e
.size
= rsa_blob
->cbPublicExp
;
1230 m
.data
= e
.data
+ e
.size
;
1231 m
.size
= rsa_blob
->cbModulus
;
1232 p
.data
= m
.data
+ m
.size
;
1233 p
.size
= rsa_blob
->cbPrime1
;
1234 q
.data
= p
.data
+ p
.size
;
1235 q
.size
= rsa_blob
->cbPrime2
;
1237 if ((ret
= pgnutls_privkey_import_rsa_raw( handle
, &m
, &e
, NULL
, &p
, &q
, NULL
, NULL
, NULL
)))
1239 pgnutls_perror( ret
);
1240 pgnutls_privkey_deinit( handle
);
1241 return STATUS_INTERNAL_ERROR
;
1244 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1245 key_data(key
)->a
.privkey
= handle
;
1246 return STATUS_SUCCESS
;
1249 static NTSTATUS
key_export_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
1253 gnutls_datum_t p
, q
, g
, y
, x
;
1254 ULONG size
= key
->u
.a
.bitlen
/ 8;
1258 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1260 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key
)->a
.privkey
, &p
, &q
, &g
, &y
, &x
)))
1262 pgnutls_perror( ret
);
1263 return STATUS_INTERNAL_ERROR
;
1266 if (q
.size
> 21 || x
.size
> 21)
1268 ERR( "can't export key in this format\n" );
1269 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1270 return STATUS_NOT_SUPPORTED
;
1273 *ret_len
= sizeof(*hdr
) + sizeof(*pubkey
) + sizeof(key
->u
.a
.dss_seed
) +
1274 EXPORT_SIZE( p
, size
, 1 ) + 20 + EXPORT_SIZE( g
, size
, 1 ) + 20;
1275 if (len
>= *ret_len
&& buf
)
1277 hdr
= (BLOBHEADER
*)buf
;
1278 hdr
->bType
= PRIVATEKEYBLOB
;
1281 hdr
->aiKeyAlg
= CALG_DSS_SIGN
;
1283 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1284 pubkey
->magic
= MAGIC_DSS2
;
1285 pubkey
->bitlen
= key
->u
.a
.bitlen
;
1287 dst
= (UCHAR
*)(pubkey
+ 1);
1288 export_gnutls_datum( dst
, size
, &p
, 1 );
1289 reverse_bytes( dst
, size
);
1292 export_gnutls_datum( dst
, 20, &q
, 1 );
1293 reverse_bytes( dst
, 20 );
1296 export_gnutls_datum( dst
, size
, &g
, 1 );
1297 reverse_bytes( dst
, size
);
1300 export_gnutls_datum( dst
, 20, &x
, 1 );
1301 reverse_bytes( dst
, 20 );
1304 memcpy( dst
, &key
->u
.a
.dss_seed
, sizeof(key
->u
.a
.dss_seed
) );
1307 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
1308 return STATUS_SUCCESS
;
1311 static NTSTATUS
key_import_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
)
1313 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
1315 gnutls_privkey_t handle
;
1316 gnutls_datum_t p
, q
, g
, x
;
1317 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], x_data
[20];
1320 if ((ret
= pgnutls_privkey_init( &handle
)))
1322 pgnutls_perror( ret
);
1323 return STATUS_INTERNAL_ERROR
;
1326 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1327 if ((size
= pubkey
->bitlen
/ 8) > sizeof(p_data
))
1329 FIXME( "size %u not supported\n", size
);
1330 pgnutls_privkey_deinit( handle
);
1331 return STATUS_NOT_SUPPORTED
;
1333 data
= (unsigned char *)(pubkey
+ 1);
1337 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1341 q
.size
= sizeof(q_data
);
1342 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1347 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1351 x
.size
= sizeof(x_data
);
1352 for (i
= 0; i
< x
.size
; i
++) x
.data
[i
] = data
[x
.size
- i
- 1];
1355 if ((ret
= pgnutls_privkey_import_dsa_raw( handle
, &p
, &q
, &g
, NULL
, &x
)))
1357 pgnutls_perror( ret
);
1358 pgnutls_privkey_deinit( handle
);
1359 return STATUS_INTERNAL_ERROR
;
1362 memcpy( &key
->u
.a
.dss_seed
, data
, sizeof(key
->u
.a
.dss_seed
) );
1364 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
1365 key_data(key
)->a
.privkey
= handle
;
1366 return STATUS_SUCCESS
;
1369 static NTSTATUS
key_import_ecc_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1371 BCRYPT_ECCKEY_BLOB
*ecc_blob
;
1372 gnutls_ecc_curve_t curve
;
1373 gnutls_datum_t x
, y
;
1374 gnutls_pubkey_t handle
;
1377 switch (key
->alg_id
)
1379 case ALG_ID_ECDH_P256
:
1380 case ALG_ID_ECDSA_P256
:
1381 curve
= GNUTLS_ECC_CURVE_SECP256R1
; break;
1383 case ALG_ID_ECDH_P384
:
1384 case ALG_ID_ECDSA_P384
:
1385 curve
= GNUTLS_ECC_CURVE_SECP384R1
; break;
1388 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1389 return STATUS_NOT_IMPLEMENTED
;
1392 if ((ret
= pgnutls_pubkey_init( &handle
)))
1394 pgnutls_perror( ret
);
1395 return STATUS_INTERNAL_ERROR
;
1398 ecc_blob
= (BCRYPT_ECCKEY_BLOB
*)buf
;
1399 x
.data
= buf
+ sizeof(*ecc_blob
);
1400 x
.size
= ecc_blob
->cbKey
;
1401 y
.data
= buf
+ sizeof(*ecc_blob
) + ecc_blob
->cbKey
;
1402 y
.size
= ecc_blob
->cbKey
;
1404 if ((ret
= pgnutls_pubkey_import_ecc_raw( handle
, curve
, &x
, &y
)))
1406 pgnutls_perror( ret
);
1407 pgnutls_pubkey_deinit( handle
);
1408 return STATUS_INTERNAL_ERROR
;
1411 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1412 key_data(key
)->a
.pubkey
= handle
;
1413 return STATUS_SUCCESS
;
1416 static NTSTATUS
key_import_rsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1418 BCRYPT_RSAKEY_BLOB
*rsa_blob
;
1419 gnutls_pubkey_t handle
;
1420 gnutls_datum_t m
, e
;
1423 if ((ret
= pgnutls_pubkey_init( &handle
)))
1425 pgnutls_perror( ret
);
1426 return STATUS_INTERNAL_ERROR
;
1429 rsa_blob
= (BCRYPT_RSAKEY_BLOB
*)buf
;
1430 e
.data
= buf
+ sizeof(*rsa_blob
);
1431 e
.size
= rsa_blob
->cbPublicExp
;
1432 m
.data
= buf
+ sizeof(*rsa_blob
) + rsa_blob
->cbPublicExp
;
1433 m
.size
= rsa_blob
->cbModulus
;
1435 if ((ret
= pgnutls_pubkey_import_rsa_raw( handle
, &m
, &e
)))
1437 pgnutls_perror( ret
);
1438 pgnutls_pubkey_deinit( handle
);
1439 return STATUS_INTERNAL_ERROR
;
1442 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1443 key_data(key
)->a
.pubkey
= handle
;
1444 return STATUS_SUCCESS
;
1447 static NTSTATUS
key_import_dsa_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1449 BCRYPT_DSA_KEY_BLOB
*dsa_blob
;
1450 gnutls_datum_t p
, q
, g
, y
;
1451 gnutls_pubkey_t handle
;
1454 if ((ret
= pgnutls_pubkey_init( &handle
)))
1456 pgnutls_perror( ret
);
1457 return STATUS_INTERNAL_ERROR
;
1460 dsa_blob
= (BCRYPT_DSA_KEY_BLOB
*)buf
;
1461 p
.data
= buf
+ sizeof(*dsa_blob
);
1462 p
.size
= dsa_blob
->cbKey
;
1463 q
.data
= dsa_blob
->q
;
1464 q
.size
= sizeof(dsa_blob
->q
);
1465 g
.data
= buf
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
;
1466 g
.size
= dsa_blob
->cbKey
;
1467 y
.data
= buf
+ sizeof(*dsa_blob
) + dsa_blob
->cbKey
* 2;
1468 y
.size
= dsa_blob
->cbKey
;
1470 if ((ret
= pgnutls_pubkey_import_dsa_raw( handle
, &p
, &q
, &g
, &y
)))
1472 pgnutls_perror( ret
);
1473 pgnutls_pubkey_deinit( handle
);
1474 return STATUS_INTERNAL_ERROR
;
1477 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1478 key_data(key
)->a
.pubkey
= handle
;
1479 return STATUS_SUCCESS
;
1482 static NTSTATUS
key_import_dsa_capi_public( struct key
*key
, UCHAR
*buf
, ULONG len
)
1486 gnutls_datum_t p
, q
, g
, y
;
1487 gnutls_pubkey_t handle
;
1488 unsigned char *data
, p_data
[128], q_data
[20], g_data
[128], y_data
[128];
1491 if ((ret
= pgnutls_pubkey_init( &handle
)))
1493 pgnutls_perror( ret
);
1494 return STATUS_INTERNAL_ERROR
;
1497 hdr
= (BLOBHEADER
*)buf
;
1498 pubkey
= (DSSPUBKEY
*)(hdr
+ 1);
1499 size
= pubkey
->bitlen
/ 8;
1500 data
= (unsigned char *)(pubkey
+ 1);
1504 for (i
= 0; i
< p
.size
; i
++) p
.data
[i
] = data
[p
.size
- i
- 1];
1508 q
.size
= sizeof(q_data
);
1509 for (i
= 0; i
< q
.size
; i
++) q
.data
[i
] = data
[q
.size
- i
- 1];
1514 for (i
= 0; i
< g
.size
; i
++) g
.data
[i
] = data
[g
.size
- i
- 1];
1518 y
.size
= sizeof(y_data
);
1519 for (i
= 0; i
< y
.size
; i
++) y
.data
[i
] = data
[y
.size
- i
- 1];
1521 if ((ret
= pgnutls_pubkey_import_dsa_raw( handle
, &p
, &q
, &g
, &y
)))
1523 pgnutls_perror( ret
);
1524 pgnutls_pubkey_deinit( handle
);
1525 return STATUS_INTERNAL_ERROR
;
1528 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
1529 key_data(key
)->a
.pubkey
= handle
;
1530 return STATUS_SUCCESS
;
1533 static NTSTATUS
key_asymmetric_export( void *args
)
1535 const struct key_asymmetric_export_params
*params
= args
;
1536 struct key
*key
= params
->key
;
1537 unsigned flags
= params
->flags
;
1539 switch (key
->alg_id
)
1541 case ALG_ID_ECDH_P256
:
1542 case ALG_ID_ECDH_P384
:
1543 case ALG_ID_ECDSA_P256
:
1544 case ALG_ID_ECDSA_P384
:
1545 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1546 return key_export_ecc_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1547 return key_export_ecc( key
, params
->buf
, params
->len
, params
->ret_len
);
1550 case ALG_ID_RSA_SIGN
:
1551 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1552 return key_export_rsa_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1553 return key_export_rsa( key
, flags
, params
->buf
, params
->len
, params
->ret_len
);
1556 if (flags
& KEY_EXPORT_FLAG_PUBLIC
)
1558 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1559 return key_export_dsa_capi_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1560 return key_export_dsa_public( key
, params
->buf
, params
->len
, params
->ret_len
);
1562 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1563 return key_export_dsa_capi( key
, params
->buf
, params
->len
, params
->ret_len
);
1564 return STATUS_NOT_IMPLEMENTED
;
1567 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1568 return STATUS_NOT_IMPLEMENTED
;
1572 static NTSTATUS
key_asymmetric_import( void *args
)
1574 const struct key_asymmetric_import_params
*params
= args
;
1575 struct key
*key
= params
->key
;
1576 unsigned flags
= params
->flags
;
1578 switch (key
->alg_id
)
1580 case ALG_ID_ECDH_P256
:
1581 case ALG_ID_ECDH_P384
:
1582 case ALG_ID_ECDSA_P256
:
1583 case ALG_ID_ECDSA_P384
:
1584 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1585 return key_import_ecc_public( key
, params
->buf
, params
->len
);
1586 return key_import_ecc( key
, params
->buf
, params
->len
);
1589 case ALG_ID_RSA_SIGN
:
1590 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1591 return key_import_rsa_public( key
, params
->buf
, params
->len
);
1592 return key_import_rsa( key
, params
->buf
, params
->len
);
1595 if (flags
& KEY_IMPORT_FLAG_PUBLIC
)
1597 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1598 return key_import_dsa_capi_public( key
, params
->buf
, params
->len
);
1599 return key_import_dsa_public( key
, params
->buf
, params
->len
);
1601 if (key
->u
.a
.flags
& KEY_FLAG_LEGACY_DSA_V2
)
1602 return key_import_dsa_capi( key
, params
->buf
, params
->len
);
1603 FIXME( "DSA private key not supported\n" );
1604 return STATUS_NOT_IMPLEMENTED
;
1607 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1608 return STATUS_NOT_IMPLEMENTED
;
1612 static NTSTATUS
prepare_gnutls_signature_dsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1613 gnutls_datum_t
*gnutls_signature
)
1615 struct buffer buffer
;
1616 DWORD r_len
= signature_len
/ 2;
1617 DWORD s_len
= r_len
;
1618 BYTE
*r
= signature
;
1619 BYTE
*s
= signature
+ r_len
;
1621 buffer_init( &buffer
);
1622 buffer_append_asn1_r_s( &buffer
, r
, r_len
, s
, s_len
);
1625 buffer_free( &buffer
);
1626 return STATUS_NO_MEMORY
;
1629 gnutls_signature
->data
= buffer
.buffer
;
1630 gnutls_signature
->size
= buffer
.pos
;
1631 return STATUS_SUCCESS
;
1634 static NTSTATUS
prepare_gnutls_signature_rsa( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1635 gnutls_datum_t
*gnutls_signature
)
1637 gnutls_signature
->data
= signature
;
1638 gnutls_signature
->size
= signature_len
;
1639 return STATUS_SUCCESS
;
1642 static NTSTATUS
prepare_gnutls_signature( struct key
*key
, UCHAR
*signature
, ULONG signature_len
,
1643 gnutls_datum_t
*gnutls_signature
)
1645 switch (key
->alg_id
)
1647 case ALG_ID_ECDSA_P256
:
1648 case ALG_ID_ECDSA_P384
:
1650 return prepare_gnutls_signature_dsa( key
, signature
, signature_len
, gnutls_signature
);
1653 case ALG_ID_RSA_SIGN
:
1654 return prepare_gnutls_signature_rsa( key
, signature
, signature_len
, gnutls_signature
);
1657 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1658 return STATUS_NOT_IMPLEMENTED
;
1662 static gnutls_digest_algorithm_t
get_digest_from_id( const WCHAR
*alg_id
)
1664 if (!wcscmp( alg_id
, BCRYPT_SHA1_ALGORITHM
)) return GNUTLS_DIG_SHA1
;
1665 if (!wcscmp( alg_id
, BCRYPT_SHA256_ALGORITHM
)) return GNUTLS_DIG_SHA256
;
1666 if (!wcscmp( alg_id
, BCRYPT_SHA384_ALGORITHM
)) return GNUTLS_DIG_SHA384
;
1667 if (!wcscmp( alg_id
, BCRYPT_SHA512_ALGORITHM
)) return GNUTLS_DIG_SHA512
;
1668 if (!wcscmp( alg_id
, BCRYPT_MD2_ALGORITHM
)) return GNUTLS_DIG_MD2
;
1669 if (!wcscmp( alg_id
, BCRYPT_MD5_ALGORITHM
)) return GNUTLS_DIG_MD5
;
1670 return GNUTLS_DIG_UNKNOWN
;
1673 static NTSTATUS
pubkey_set_rsa_pss_params( gnutls_pubkey_t key
, gnutls_digest_algorithm_t dig
, unsigned int salt_size
)
1675 gnutls_x509_spki_t spki
;
1678 if (((ret
= pgnutls_x509_spki_init( &spki
) < 0)))
1680 pgnutls_perror( ret
);
1681 return STATUS_INTERNAL_ERROR
;
1683 pgnutls_x509_spki_set_rsa_pss_params( spki
, dig
, salt_size
);
1684 ret
= pgnutls_pubkey_set_spki( key
, spki
, 0 );
1685 pgnutls_x509_spki_deinit( spki
);
1688 pgnutls_perror( ret
);
1689 return STATUS_INTERNAL_ERROR
;
1691 return STATUS_SUCCESS
;
1694 static NTSTATUS
key_asymmetric_verify( void *args
)
1696 const struct key_asymmetric_verify_params
*params
= args
;
1697 struct key
*key
= params
->key
;
1698 unsigned flags
= params
->flags
;
1699 gnutls_digest_algorithm_t hash_alg
;
1700 gnutls_sign_algorithm_t sign_alg
;
1701 gnutls_datum_t gnutls_hash
, gnutls_signature
;
1702 gnutls_pk_algorithm_t pk_alg
;
1706 switch (key
->alg_id
)
1708 case ALG_ID_ECDSA_P256
:
1709 case ALG_ID_ECDSA_P384
:
1711 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1713 /* only the hash size must match, not the actual hash function */
1714 switch (params
->hash_len
)
1716 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1717 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1718 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1721 FIXME( "hash size %u not yet supported\n", params
->hash_len
);
1722 return STATUS_INVALID_SIGNATURE
;
1724 pk_alg
= GNUTLS_PK_ECC
;
1728 case ALG_ID_RSA_SIGN
:
1730 if (flags
& BCRYPT_PAD_PKCS1
)
1732 BCRYPT_PKCS1_PADDING_INFO
*info
= params
->padding
;
1734 if (!info
) return STATUS_INVALID_PARAMETER
;
1735 if (!info
->pszAlgId
) return STATUS_INVALID_SIGNATURE
;
1736 if ((hash_alg
= get_digest_from_id(info
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1738 FIXME( "hash algorithm %s not supported\n", debugstr_w(info
->pszAlgId
) );
1739 return STATUS_NOT_SUPPORTED
;
1741 pk_alg
= GNUTLS_PK_RSA
;
1743 else if (flags
& BCRYPT_PAD_PSS
)
1745 BCRYPT_PSS_PADDING_INFO
*info
= params
->padding
;
1747 if (!info
) return STATUS_INVALID_PARAMETER
;
1748 if (!info
->pszAlgId
) return STATUS_INVALID_SIGNATURE
;
1749 if ((hash_alg
= get_digest_from_id(info
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1751 FIXME( "hash algorithm %s not supported\n", debugstr_w(info
->pszAlgId
) );
1752 return STATUS_NOT_SUPPORTED
;
1754 if ((status
= pubkey_set_rsa_pss_params( key_data(key
)->a
.pubkey
, hash_alg
, info
->cbSalt
))) return status
;
1755 pk_alg
= GNUTLS_PK_RSA_PSS
;
1757 else return STATUS_INVALID_PARAMETER
;
1762 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1763 if (params
->hash_len
!= 20)
1765 FIXME( "hash size %u not supported\n", params
->hash_len
);
1766 return STATUS_INVALID_PARAMETER
;
1768 hash_alg
= GNUTLS_DIG_SHA1
;
1769 pk_alg
= GNUTLS_PK_DSA
;
1773 FIXME( "algorithm %u not yet supported\n", key
->alg_id
);
1774 return STATUS_NOT_IMPLEMENTED
;
1777 if ((sign_alg
= pgnutls_pk_to_sign( pk_alg
, hash_alg
)) == GNUTLS_SIGN_UNKNOWN
)
1779 FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key
->alg_id
, params
->hash_len
);
1780 return STATUS_NOT_IMPLEMENTED
;
1783 if ((status
= prepare_gnutls_signature( key
, params
->signature
, params
->signature_len
, &gnutls_signature
)))
1786 gnutls_hash
.data
= params
->hash
;
1787 gnutls_hash
.size
= params
->hash_len
;
1788 ret
= pgnutls_pubkey_verify_hash2( key_data(key
)->a
.pubkey
, sign_alg
, 0, &gnutls_hash
, &gnutls_signature
);
1790 if (gnutls_signature
.data
!= params
->signature
) free( gnutls_signature
.data
);
1791 return (ret
< 0) ? STATUS_INVALID_SIGNATURE
: STATUS_SUCCESS
;
1794 static unsigned int get_signature_length( enum alg_id id
)
1798 case ALG_ID_ECDSA_P256
: return 64;
1799 case ALG_ID_ECDSA_P384
: return 96;
1800 case ALG_ID_DSA
: return 40;
1802 FIXME( "unhandled algorithm %u\n", id
);
1807 static NTSTATUS
format_gnutls_signature( enum alg_id type
, gnutls_datum_t signature
,
1808 UCHAR
*output
, ULONG output_len
, ULONG
*ret_len
)
1813 case ALG_ID_RSA_SIGN
:
1815 *ret_len
= signature
.size
;
1816 if (output_len
< signature
.size
) return STATUS_BUFFER_TOO_SMALL
;
1817 if (output
) memcpy( output
, signature
.data
, signature
.size
);
1818 return STATUS_SUCCESS
;
1820 case ALG_ID_ECDSA_P256
:
1821 case ALG_ID_ECDSA_P384
:
1825 unsigned int sig_len
= get_signature_length( type
);
1826 gnutls_datum_t r
, s
; /* format as r||s */
1828 if ((err
= pgnutls_decode_rs_value( &signature
, &r
, &s
)))
1830 pgnutls_perror( err
);
1831 return STATUS_INTERNAL_ERROR
;
1835 if (output_len
< sig_len
) return STATUS_BUFFER_TOO_SMALL
;
1837 if (r
.size
> sig_len
/ 2 + 1 || s
.size
> sig_len
/ 2 + 1)
1839 ERR( "we didn't get a correct signature\n" );
1840 return STATUS_INTERNAL_ERROR
;
1845 export_gnutls_datum( output
, sig_len
/ 2, &r
, 1 );
1846 export_gnutls_datum( output
+ sig_len
/ 2, sig_len
/ 2, &s
, 1 );
1849 free( r
.data
); free( s
.data
);
1850 return STATUS_SUCCESS
;
1853 return STATUS_INTERNAL_ERROR
;
1857 static NTSTATUS
privkey_set_rsa_pss_params( gnutls_privkey_t key
, gnutls_digest_algorithm_t dig
, unsigned int salt_size
)
1859 gnutls_x509_spki_t spki
;
1862 if (((ret
= pgnutls_x509_spki_init( &spki
) < 0)))
1864 pgnutls_perror( ret
);
1865 return STATUS_INTERNAL_ERROR
;
1867 pgnutls_x509_spki_set_rsa_pss_params( spki
, dig
, salt_size
);
1868 ret
= pgnutls_privkey_set_spki( key
, spki
, 0 );
1869 pgnutls_x509_spki_deinit( spki
);
1872 pgnutls_perror( ret
);
1873 return STATUS_INTERNAL_ERROR
;
1875 return STATUS_SUCCESS
;
1878 static NTSTATUS
key_asymmetric_sign( void *args
)
1880 const struct key_asymmetric_sign_params
*params
= args
;
1881 struct key
*key
= params
->key
;
1882 unsigned int flags
= params
->flags
, gnutls_flags
= 0;
1883 gnutls_datum_t hash
, signature
;
1884 gnutls_digest_algorithm_t hash_alg
;
1888 if (key
->alg_id
== ALG_ID_ECDSA_P256
|| key
->alg_id
== ALG_ID_ECDSA_P384
)
1890 /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
1891 switch (params
->input_len
)
1893 case 20: hash_alg
= GNUTLS_DIG_SHA1
; break;
1894 case 32: hash_alg
= GNUTLS_DIG_SHA256
; break;
1895 case 48: hash_alg
= GNUTLS_DIG_SHA384
; break;
1896 case 64: hash_alg
= GNUTLS_DIG_SHA512
; break;
1899 FIXME( "hash size %u not yet supported\n", params
->input_len
);
1900 return STATUS_INVALID_PARAMETER
;
1903 if (flags
== BCRYPT_PAD_PKCS1
)
1905 BCRYPT_PKCS1_PADDING_INFO
*pad
= params
->padding
;
1906 if (pad
&& pad
->pszAlgId
&& get_digest_from_id( pad
->pszAlgId
) != hash_alg
)
1908 WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad
->pszAlgId
), hash_alg
);
1909 return STATUS_INVALID_PARAMETER
;
1913 else if (key
->alg_id
== ALG_ID_DSA
)
1915 if (flags
) FIXME( "flags %#x not supported\n", flags
);
1916 if (params
->input_len
!= 20)
1918 FIXME( "hash size %u not supported\n", params
->input_len
);
1919 return STATUS_INVALID_PARAMETER
;
1921 hash_alg
= GNUTLS_DIG_SHA1
;
1923 else if (flags
== BCRYPT_PAD_PKCS1
)
1925 BCRYPT_PKCS1_PADDING_INFO
*pad
= params
->padding
;
1927 if (!pad
|| !pad
->pszAlgId
)
1929 WARN( "padding info not found\n" );
1930 return STATUS_INVALID_PARAMETER
;
1932 if ((hash_alg
= get_digest_from_id( pad
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1934 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad
->pszAlgId
) );
1935 return STATUS_NOT_SUPPORTED
;
1938 else if (flags
== BCRYPT_PAD_PSS
)
1940 BCRYPT_PSS_PADDING_INFO
*pad
= params
->padding
;
1942 if (!pad
|| !pad
->pszAlgId
)
1944 WARN( "padding info not found\n" );
1945 return STATUS_INVALID_PARAMETER
;
1947 if (key
->alg_id
!= ALG_ID_RSA
&& key
->alg_id
!= ALG_ID_RSA_SIGN
)
1949 FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key
->alg_id
);
1950 return STATUS_NOT_SUPPORTED
;
1952 if ((hash_alg
= get_digest_from_id( pad
->pszAlgId
)) == GNUTLS_DIG_UNKNOWN
)
1954 FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad
->pszAlgId
) );
1955 return STATUS_NOT_SUPPORTED
;
1958 if ((status
= privkey_set_rsa_pss_params( key_data(key
)->a
.privkey
, hash_alg
, pad
->cbSalt
))) return status
;
1959 gnutls_flags
= GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS
;
1963 WARN( "invalid flags %#x\n", flags
);
1964 return STATUS_INVALID_PARAMETER
;
1968 FIXME( "flags %#x not implemented\n", flags
);
1969 return STATUS_NOT_IMPLEMENTED
;
1972 if (!params
->output
)
1974 *params
->ret_len
= key
->u
.a
.bitlen
/ 8;
1975 return STATUS_SUCCESS
;
1977 if (!key_data(key
)->a
.privkey
) return STATUS_INVALID_PARAMETER
;
1979 hash
.data
= params
->input
;
1980 hash
.size
= params
->input_len
;
1982 signature
.data
= NULL
;
1985 if ((ret
= pgnutls_privkey_sign_hash( key_data(key
)->a
.privkey
, hash_alg
, gnutls_flags
, &hash
, &signature
)))
1987 pgnutls_perror( ret
);
1988 return STATUS_INTERNAL_ERROR
;
1991 status
= format_gnutls_signature( key
->alg_id
, signature
, params
->output
, params
->output_len
, params
->ret_len
);
1992 free( signature
.data
);
1996 static NTSTATUS
key_asymmetric_destroy( void *args
)
1998 struct key
*key
= args
;
2000 if (key_data(key
)->a
.privkey
) pgnutls_privkey_deinit( key_data(key
)->a
.privkey
);
2001 if (key_data(key
)->a
.pubkey
) pgnutls_pubkey_deinit( key_data(key
)->a
.pubkey
);
2002 return STATUS_SUCCESS
;
2005 static NTSTATUS
dup_privkey( struct key
*key_orig
, struct key
*key_copy
)
2007 gnutls_privkey_t privkey
;
2010 if ((ret
= pgnutls_privkey_init( &privkey
)))
2012 pgnutls_perror( ret
);
2013 return STATUS_INTERNAL_ERROR
;
2016 switch (key_orig
->alg_id
)
2019 case ALG_ID_RSA_SIGN
:
2021 gnutls_datum_t m
, e
, d
, p
, q
, u
, e1
, e2
;
2022 if ((ret
= pgnutls_privkey_export_rsa_raw( key_data(key_orig
)->a
.privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
)))
2024 pgnutls_perror( ret
);
2025 return STATUS_INTERNAL_ERROR
;
2027 ret
= pgnutls_privkey_import_rsa_raw( privkey
, &m
, &e
, &d
, &p
, &q
, &u
, &e1
, &e2
);
2028 free( m
.data
); free( e
.data
); free( d
.data
); free( p
.data
); free( q
.data
); free( u
.data
);
2029 free( e1
.data
); free( e2
.data
);
2032 pgnutls_perror( ret
);
2033 return STATUS_INTERNAL_ERROR
;
2039 gnutls_datum_t p
, q
, g
, y
, x
;
2040 if ((ret
= pgnutls_privkey_export_dsa_raw( key_data(key_orig
)->a
.privkey
, &p
, &q
, &g
, &y
, &x
)))
2042 pgnutls_perror( ret
);
2043 return STATUS_INTERNAL_ERROR
;
2045 ret
= pgnutls_privkey_import_dsa_raw( privkey
, &p
, &q
, &g
, &y
, &x
);
2046 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
); free( x
.data
);
2049 pgnutls_perror( ret
);
2050 return STATUS_INTERNAL_ERROR
;
2052 key_copy
->u
.a
.dss_seed
= key_orig
->u
.a
.dss_seed
;
2055 case ALG_ID_ECDH_P256
:
2056 case ALG_ID_ECDH_P384
:
2057 case ALG_ID_ECDSA_P256
:
2058 case ALG_ID_ECDSA_P384
:
2060 gnutls_ecc_curve_t curve
;
2061 gnutls_datum_t x
, y
, k
;
2062 if ((ret
= pgnutls_privkey_export_ecc_raw( key_data(key_orig
)->a
.privkey
, &curve
, &x
, &y
, &k
)))
2064 pgnutls_perror( ret
);
2065 return STATUS_INTERNAL_ERROR
;
2067 ret
= pgnutls_privkey_import_ecc_raw( privkey
, curve
, &x
, &y
, &k
);
2068 free( x
.data
); free( y
.data
); free( k
.data
);
2071 pgnutls_perror( ret
);
2072 return STATUS_INTERNAL_ERROR
;
2077 ERR( "unhandled algorithm %u\n", key_orig
->alg_id
);
2078 return STATUS_INTERNAL_ERROR
;
2081 key_data(key_copy
)->a
.privkey
= privkey
;
2082 return STATUS_SUCCESS
;
2085 static NTSTATUS
dup_pubkey( struct key
*key_orig
, struct key
*key_copy
)
2087 gnutls_pubkey_t pubkey
;
2090 if ((ret
= pgnutls_pubkey_init( &pubkey
)))
2092 pgnutls_perror( ret
);
2093 return STATUS_INTERNAL_ERROR
;
2096 switch (key_orig
->alg_id
)
2099 case ALG_ID_RSA_SIGN
:
2101 gnutls_datum_t m
, e
;
2102 if ((ret
= pgnutls_pubkey_export_rsa_raw( key_data(key_orig
)->a
.pubkey
, &m
, &e
)))
2104 pgnutls_perror( ret
);
2105 return STATUS_INTERNAL_ERROR
;
2107 ret
= pgnutls_pubkey_import_rsa_raw( pubkey
, &m
, &e
);
2108 free( m
.data
); free( e
.data
);
2111 pgnutls_perror( ret
);
2112 return STATUS_INTERNAL_ERROR
;
2118 gnutls_datum_t p
, q
, g
, y
;
2119 if ((ret
= pgnutls_pubkey_export_dsa_raw( key_data(key_orig
)->a
.pubkey
, &p
, &q
, &g
, &y
)))
2121 pgnutls_perror( ret
);
2122 return STATUS_INTERNAL_ERROR
;
2124 ret
= pgnutls_pubkey_import_dsa_raw( pubkey
, &p
, &q
, &g
, &y
);
2125 free( p
.data
); free( q
.data
); free( g
.data
); free( y
.data
);
2128 pgnutls_perror( ret
);
2129 return STATUS_INTERNAL_ERROR
;
2131 key_copy
->u
.a
.dss_seed
= key_orig
->u
.a
.dss_seed
;
2134 case ALG_ID_ECDH_P256
:
2135 case ALG_ID_ECDH_P384
:
2136 case ALG_ID_ECDSA_P256
:
2137 case ALG_ID_ECDSA_P384
:
2139 gnutls_ecc_curve_t curve
;
2140 gnutls_datum_t x
, y
;
2141 if ((ret
= pgnutls_pubkey_export_ecc_raw( key_data(key_orig
)->a
.pubkey
, &curve
, &x
, &y
)))
2143 pgnutls_perror( ret
);
2144 return STATUS_INTERNAL_ERROR
;
2146 ret
= pgnutls_pubkey_import_ecc_raw( pubkey
, curve
, &x
, &y
);
2147 free( x
.data
); free( y
.data
);
2150 pgnutls_perror( ret
);
2151 return STATUS_INTERNAL_ERROR
;
2156 ERR( "unhandled algorithm %u\n", key_orig
->alg_id
);
2157 return STATUS_INTERNAL_ERROR
;
2160 key_data(key_copy
)->a
.pubkey
= pubkey
;
2161 return STATUS_SUCCESS
;
2164 static NTSTATUS
key_asymmetric_duplicate( void *args
)
2166 const struct key_asymmetric_duplicate_params
*params
= args
;
2169 if (key_data(params
->key_orig
)->a
.privkey
&& (status
= dup_privkey( params
->key_orig
, params
->key_copy
)))
2172 if (key_data(params
->key_orig
)->a
.pubkey
&& (status
= dup_pubkey( params
->key_orig
, params
->key_copy
)))
2175 return STATUS_SUCCESS
;
2178 static NTSTATUS
key_asymmetric_decrypt( void *args
)
2180 const struct key_asymmetric_decrypt_params
*params
= args
;
2181 gnutls_datum_t e
, d
= { 0 };
2182 NTSTATUS status
= STATUS_SUCCESS
;
2185 e
.data
= params
->input
;
2186 e
.size
= params
->input_len
;
2187 if ((ret
= pgnutls_privkey_decrypt_data( key_data(params
->key
)->a
.privkey
, 0, &e
, &d
)))
2189 pgnutls_perror( ret
);
2190 return STATUS_INTERNAL_ERROR
;
2193 *params
->ret_len
= d
.size
;
2194 if (params
->output_len
>= d
.size
) memcpy( params
->output
, d
.data
, *params
->ret_len
);
2195 else status
= STATUS_BUFFER_TOO_SMALL
;
2201 static NTSTATUS
key_asymmetric_encrypt( void *args
)
2203 const struct key_asymmetric_encrypt_params
*params
= args
;
2204 gnutls_datum_t d
, e
= { 0 };
2205 NTSTATUS status
= STATUS_SUCCESS
;
2208 d
.data
= params
->input
;
2209 d
.size
= params
->input_len
;
2210 if ((ret
= pgnutls_pubkey_encrypt_data(key_data(params
->key
)->a
.pubkey
, 0, &d
, &e
)))
2212 pgnutls_perror( ret
);
2213 return STATUS_INTERNAL_ERROR
;
2216 *params
->ret_len
= e
.size
;
2217 if (params
->output_len
>= e
.size
) memcpy( params
->output
, e
.data
, *params
->ret_len
);
2218 else if (params
->output_len
== 0) status
= STATUS_SUCCESS
;
2219 else status
= STATUS_BUFFER_TOO_SMALL
;
2225 const unixlib_entry_t __wine_unix_call_funcs
[] =
2227 gnutls_process_attach
,
2228 gnutls_process_detach
,
2229 key_symmetric_vector_reset
,
2230 key_symmetric_set_auth_data
,
2231 key_symmetric_encrypt
,
2232 key_symmetric_decrypt
,
2233 key_symmetric_get_tag
,
2234 key_symmetric_destroy
,
2235 key_asymmetric_generate
,
2236 key_asymmetric_decrypt
,
2237 key_asymmetric_encrypt
,
2238 key_asymmetric_duplicate
,
2239 key_asymmetric_sign
,
2240 key_asymmetric_verify
,
2241 key_asymmetric_destroy
,
2242 key_asymmetric_export
,
2243 key_asymmetric_import
2248 typedef ULONG PTR32
;
2250 struct key_symmetric32
2252 enum chain_mode mode
;
2261 struct key_asymmetric32
2263 ULONG bitlen
; /* ignored for ECC keys */
2274 UINT64
private[2]; /* private data for backend */
2277 struct key_symmetric32 s
;
2278 struct key_asymmetric32 a
;
2282 static struct key
*get_symmetric_key( struct key32
*key32
, struct key
*key
)
2284 key
->hdr
= key32
->hdr
;
2285 key
->alg_id
= key32
->alg_id
;
2286 key
->private[0] = key32
->private[0];
2287 key
->private[1] = key32
->private[1];
2288 key
->u
.s
.mode
= key32
->u
.s
.mode
;
2289 key
->u
.s
.block_size
= key32
->u
.s
.block_size
;
2290 key
->u
.s
.vector
= ULongToPtr(key32
->u
.s
.vector
);
2291 key
->u
.s
.vector_len
= key32
->u
.s
.vector_len
;
2292 key
->u
.s
.secret
= ULongToPtr(key32
->u
.s
.secret
);
2293 key
->u
.s
.secret_len
= key32
->u
.s
.secret_len
;
2297 static struct key
*get_asymmetric_key( struct key32
*key32
, struct key
*key
)
2299 key
->hdr
= key32
->hdr
;
2300 key
->alg_id
= key32
->alg_id
;
2301 key
->private[0] = key32
->private[0];
2302 key
->private[1] = key32
->private[1];
2303 key
->u
.a
.bitlen
= key32
->u
.a
.bitlen
;
2304 key
->u
.a
.flags
= key32
->u
.a
.flags
;
2305 key
->u
.a
.dss_seed
= key32
->u
.a
.dss_seed
;
2309 static void put_symmetric_key32( struct key
*key
, struct key32
*key32
)
2311 key32
->private[0] = key
->private[0];
2312 key32
->private[1] = key
->private[1];
2315 static void put_asymmetric_key32( struct key
*key
, struct key32
*key32
)
2317 key32
->private[0] = key
->private[0];
2318 key32
->private[1] = key
->private[1];
2319 key32
->u
.a
.flags
= key
->u
.a
.flags
;
2320 key32
->u
.a
.dss_seed
= key
->u
.a
.dss_seed
;
2323 static NTSTATUS
wow64_key_symmetric_vector_reset( void *args
)
2327 struct key32
*key32
= args
;
2329 ret
= key_symmetric_vector_reset( get_symmetric_key( key32
, &key
));
2330 put_symmetric_key32( &key
, key32
);
2334 static NTSTATUS
wow64_key_symmetric_set_auth_data( void *args
)
2341 } const *params32
= args
;
2345 struct key32
*key32
= ULongToPtr( params32
->key
);
2346 struct key_symmetric_set_auth_data_params params
=
2348 get_symmetric_key( key32
, &key
),
2349 ULongToPtr(params32
->auth_data
),
2353 ret
= key_symmetric_set_auth_data( ¶ms
);
2354 put_symmetric_key32( &key
, key32
);
2358 static NTSTATUS
wow64_key_symmetric_encrypt( void *args
)
2367 } const *params32
= args
;
2371 struct key32
*key32
= ULongToPtr( params32
->key
);
2372 struct key_symmetric_encrypt_params params
=
2374 get_symmetric_key( key32
, &key
),
2375 ULongToPtr(params32
->input
),
2376 params32
->input_len
,
2377 ULongToPtr(params32
->output
),
2378 params32
->output_len
2381 ret
= key_symmetric_encrypt( ¶ms
);
2382 put_symmetric_key32( &key
, key32
);
2386 static NTSTATUS
wow64_key_symmetric_decrypt( void *args
)
2395 } const *params32
= args
;
2399 struct key32
*key32
= ULongToPtr( params32
->key
);
2400 struct key_symmetric_decrypt_params params
=
2402 get_symmetric_key( key32
, &key
),
2403 ULongToPtr(params32
->input
),
2404 params32
->input_len
,
2405 ULongToPtr(params32
->output
),
2406 params32
->output_len
2409 ret
= key_symmetric_decrypt( ¶ms
);
2410 put_symmetric_key32( &key
, key32
);
2414 static NTSTATUS
wow64_key_symmetric_get_tag( void *args
)
2421 } const *params32
= args
;
2425 struct key32
*key32
= ULongToPtr( params32
->key
);
2426 struct key_symmetric_get_tag_params params
=
2428 get_symmetric_key( key32
, &key
),
2429 ULongToPtr(params32
->tag
),
2433 ret
= key_symmetric_get_tag( ¶ms
);
2434 put_symmetric_key32( &key
, key32
);
2438 static NTSTATUS
wow64_key_symmetric_destroy( void *args
)
2440 struct key32
*key32
= args
;
2443 return key_symmetric_destroy( get_symmetric_key( key32
, &key
));
2446 static NTSTATUS
wow64_key_asymmetric_generate( void *args
)
2448 struct key32
*key32
= args
;
2452 ret
= key_asymmetric_generate( get_asymmetric_key( key32
, &key
));
2453 put_asymmetric_key32( &key
, key32
);
2457 static NTSTATUS
wow64_key_asymmetric_decrypt( void *args
)
2467 } const *params32
= args
;
2471 struct key32
*key32
= ULongToPtr( params32
->key
);
2472 struct key_asymmetric_decrypt_params params
=
2474 get_asymmetric_key( key32
, &key
),
2475 ULongToPtr(params32
->input
),
2476 params32
->input_len
,
2477 ULongToPtr(params32
->output
),
2478 params32
->output_len
,
2479 ULongToPtr(params32
->ret_len
)
2482 ret
= key_asymmetric_decrypt( ¶ms
);
2483 put_asymmetric_key32( &key
, key32
);
2487 static NTSTATUS
wow64_key_asymmetric_encrypt( void *args
)
2497 } const *params32
= args
;
2501 struct key32
*key32
= ULongToPtr( params32
->key
);
2502 struct key_asymmetric_encrypt_params params
=
2504 get_asymmetric_key( key32
, &key
),
2505 ULongToPtr(params32
->input
),
2506 params32
->input_len
,
2507 ULongToPtr(params32
->output
),
2508 params32
->output_len
,
2509 ULongToPtr(params32
->ret_len
)
2512 ret
= key_asymmetric_encrypt( ¶ms
);
2513 put_asymmetric_key32( &key
, key32
);
2517 static NTSTATUS
wow64_key_asymmetric_duplicate( void *args
)
2523 } const *params32
= args
;
2526 struct key key_orig
, key_copy
;
2527 struct key32
*key_orig32
= ULongToPtr( params32
->key_orig
);
2528 struct key32
*key_copy32
= ULongToPtr( params32
->key_copy
);
2529 struct key_asymmetric_duplicate_params params
=
2531 get_asymmetric_key( key_orig32
, &key_orig
),
2532 get_asymmetric_key( key_copy32
, &key_copy
)
2535 ret
= key_asymmetric_duplicate( ¶ms
);
2536 put_asymmetric_key32( &key_copy
, key_copy32
);
2540 static NTSTATUS
wow64_key_asymmetric_sign( void *args
)
2552 } const *params32
= args
;
2556 BCRYPT_PKCS1_PADDING_INFO padding
;
2557 struct key32
*key32
= ULongToPtr( params32
->key
);
2558 struct key_asymmetric_sign_params params
=
2560 get_asymmetric_key( key32
, &key
),
2562 ULongToPtr(params32
->input
),
2563 params32
->input_len
,
2564 ULongToPtr(params32
->output
),
2565 params32
->output_len
,
2566 ULongToPtr(params32
->ret_len
),
2570 if (params32
->flags
& BCRYPT_PAD_PKCS1
)
2572 PTR32
*info
= ULongToPtr( params32
->padding
);
2573 if (!info
) return STATUS_INVALID_PARAMETER
;
2574 padding
.pszAlgId
= ULongToPtr( *info
);
2575 params
.padding
= &padding
;
2578 ret
= key_asymmetric_sign( ¶ms
);
2579 put_asymmetric_key32( &key
, key32
);
2583 static NTSTATUS
wow64_key_asymmetric_verify( void *args
)
2592 ULONG signature_len
;
2594 } const *params32
= args
;
2598 BCRYPT_PKCS1_PADDING_INFO padding
;
2599 struct key32
*key32
= ULongToPtr( params32
->key
);
2600 struct key_asymmetric_verify_params params
=
2602 get_asymmetric_key( key32
, &key
),
2604 ULongToPtr(params32
->hash
),
2606 ULongToPtr(params32
->signature
),
2607 params32
->signature_len
,
2611 if (params32
->flags
& BCRYPT_PAD_PKCS1
)
2613 PTR32
*info
= ULongToPtr( params32
->padding
);
2614 if (!info
) return STATUS_INVALID_PARAMETER
;
2615 padding
.pszAlgId
= ULongToPtr( *info
);
2616 params
.padding
= &padding
;
2619 ret
= key_asymmetric_verify( ¶ms
);
2620 put_asymmetric_key32( &key
, key32
);
2624 static NTSTATUS
wow64_key_asymmetric_destroy( void *args
)
2626 struct key32
*key32
= args
;
2629 return key_asymmetric_destroy( get_asymmetric_key( key32
, &key
));
2632 static NTSTATUS
wow64_key_asymmetric_export( void *args
)
2641 } const *params32
= args
;
2645 struct key32
*key32
= ULongToPtr( params32
->key
);
2646 struct key_asymmetric_export_params params
=
2648 get_asymmetric_key( key32
, &key
),
2650 ULongToPtr(params32
->buf
),
2652 ULongToPtr(params32
->ret_len
),
2655 ret
= key_asymmetric_export( ¶ms
);
2656 put_asymmetric_key32( &key
, key32
);
2660 static NTSTATUS
wow64_key_asymmetric_import( void *args
)
2668 } const *params32
= args
;
2672 struct key32
*key32
= ULongToPtr( params32
->key
);
2673 struct key_asymmetric_import_params params
=
2675 get_asymmetric_key( key32
, &key
),
2677 ULongToPtr(params32
->buf
),
2681 ret
= key_asymmetric_import( ¶ms
);
2682 put_asymmetric_key32( &key
, key32
);
2686 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
2688 gnutls_process_attach
,
2689 gnutls_process_detach
,
2690 wow64_key_symmetric_vector_reset
,
2691 wow64_key_symmetric_set_auth_data
,
2692 wow64_key_symmetric_encrypt
,
2693 wow64_key_symmetric_decrypt
,
2694 wow64_key_symmetric_get_tag
,
2695 wow64_key_symmetric_destroy
,
2696 wow64_key_asymmetric_generate
,
2697 wow64_key_asymmetric_decrypt
,
2698 wow64_key_asymmetric_encrypt
,
2699 wow64_key_asymmetric_duplicate
,
2700 wow64_key_asymmetric_sign
,
2701 wow64_key_asymmetric_verify
,
2702 wow64_key_asymmetric_destroy
,
2703 wow64_key_asymmetric_export
,
2704 wow64_key_asymmetric_import
2709 #endif /* HAVE_GNUTLS_CIPHER_INIT */