Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/bcrypt/gnutls.c
8669 views
1
/*
2
* Copyright 2009 Henri Verbeet for CodeWeavers
3
* Copyright 2018 Hans Leidekker for CodeWeavers
4
*
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.
9
*
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.
14
*
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
18
*
19
*/
20
21
#if 0
22
#pragma makedep unix
23
#endif
24
25
#include "config.h"
26
27
#ifdef HAVE_GNUTLS_CIPHER_INIT
28
29
#include <stdarg.h>
30
#include <stdlib.h>
31
#include <assert.h>
32
#include <sys/types.h>
33
#include <dlfcn.h>
34
#include <gnutls/gnutls.h>
35
#include <gnutls/crypto.h>
36
#include <gnutls/abstract.h>
37
38
#include "ntstatus.h"
39
#define WIN32_NO_STATUS
40
#include "windef.h"
41
#include "winbase.h"
42
#include "winternl.h"
43
#include "ntsecapi.h"
44
#include "wincrypt.h"
45
#include "bcrypt.h"
46
47
#include "bcrypt_internal.h"
48
49
#include "wine/debug.h"
50
51
WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
52
WINE_DECLARE_DEBUG_CHANNEL(winediag);
53
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
59
60
#define GNUTLS_CURVE_TO_BITS(curve) (unsigned int)(((unsigned int)1<<31)|((unsigned int)(curve)))
61
62
typedef enum
63
{
64
GNUTLS_ECC_CURVE_INVALID,
65
GNUTLS_ECC_CURVE_SECP224R1,
66
GNUTLS_ECC_CURVE_SECP256R1,
67
GNUTLS_ECC_CURVE_SECP384R1,
68
GNUTLS_ECC_CURVE_SECP521R1,
69
} gnutls_ecc_curve_t;
70
#endif
71
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
76
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;
80
#endif
81
82
#if GUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 8)
83
#define GNUTLS_KEYGEN_DH 4
84
#endif
85
86
union key_data
87
{
88
gnutls_cipher_hd_t cipher;
89
struct
90
{
91
gnutls_privkey_t privkey;
92
gnutls_pubkey_t pubkey;
93
gnutls_dh_params_t dh_params;
94
} a;
95
};
96
C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
97
98
static union key_data *key_data( struct key *key )
99
{
100
return (union key_data *)key->private;
101
}
102
103
/* Not present in gnutls version < 3.0 */
104
static int (*pgnutls_cipher_tag)(gnutls_cipher_hd_t, void *, size_t);
105
static int (*pgnutls_cipher_add_auth)(gnutls_cipher_hd_t, const void *, size_t);
106
static gnutls_sign_algorithm_t (*pgnutls_pk_to_sign)(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
107
static int (*pgnutls_pubkey_import_ecc_raw)(gnutls_pubkey_t, gnutls_ecc_curve_t,
108
const gnutls_datum_t *, const gnutls_datum_t *);
109
static int (*pgnutls_pubkey_export_ecc_raw)(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
110
gnutls_datum_t *x, gnutls_datum_t *y);
111
static int (*pgnutls_privkey_import_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t, const gnutls_datum_t *,
112
const gnutls_datum_t *, const gnutls_datum_t *);
113
static int (*pgnutls_pubkey_verify_hash2)(gnutls_pubkey_t, gnutls_sign_algorithm_t, unsigned int,
114
const gnutls_datum_t *, const gnutls_datum_t *);
115
static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t, unsigned int flags, const gnutls_datum_t *,
116
gnutls_datum_t *);
117
118
/* Not present in gnutls version < 2.11.0 */
119
static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *);
120
121
/* Not present in gnutls version < 2.12.0 */
122
static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
123
const gnutls_datum_t *, const gnutls_datum_t *);
124
static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
125
static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *,
126
gnutls_datum_t *);
127
128
/* Not present in gnutls version < 3.3.0 */
129
static int (*pgnutls_pubkey_export_dsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
130
gnutls_datum_t *);
131
static int (*pgnutls_pubkey_export_rsa_raw)(gnutls_pubkey_t, gnutls_datum_t *, gnutls_datum_t *);
132
static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
133
gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
134
static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
135
gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
136
gnutls_datum_t *);
137
static int (*pgnutls_privkey_export_dsa_raw)(gnutls_privkey_t, gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *,
138
gnutls_datum_t *, gnutls_datum_t *);
139
static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
140
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
141
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
142
143
/* Not present in gnutls version < 3.5.0 */
144
static int (*pgnutls_privkey_generate2)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int,
145
const gnutls_keygen_data_st *, unsigned);
146
147
/* Not present in gnutls version < 3.6.0 */
148
static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
149
static int (*pgnutls_x509_spki_init)(gnutls_x509_spki_t *);
150
static void (*pgnutls_x509_spki_deinit)(gnutls_x509_spki_t);
151
static void (*pgnutls_x509_spki_set_rsa_pss_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, unsigned int);
152
static int (*pgnutls_pubkey_set_spki)(gnutls_pubkey_t, const gnutls_x509_spki_t, unsigned int);
153
static int (*pgnutls_privkey_set_spki)(gnutls_privkey_t, const gnutls_x509_spki_t, unsigned int);
154
155
/* Not present in gnutls version < 3.8.2 */
156
static int (*pgnutls_privkey_derive_secret)(gnutls_privkey_t, gnutls_pubkey_t, const gnutls_datum_t *,
157
gnutls_datum_t *, unsigned int);
158
static int (*pgnutls_privkey_export_dh_raw)(gnutls_privkey_t, gnutls_dh_params_t, gnutls_datum_t *, gnutls_datum_t *,
159
unsigned int);
160
static int (*pgnutls_pubkey_export_dh_raw)(gnutls_pubkey_t, gnutls_dh_params_t, gnutls_datum_t *, unsigned);
161
static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_params_t, const gnutls_datum_t *,
162
const gnutls_datum_t *);
163
static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
164
165
/* Not present in gnutls version < 3.8.4 */
166
static int (*pgnutls_x509_spki_set_rsa_oaep_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, gnutls_datum_t *);
167
168
static void *libgnutls_handle;
169
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
170
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
171
MAKE_FUNCPTR(gnutls_cipher_deinit);
172
MAKE_FUNCPTR(gnutls_cipher_encrypt2);
173
MAKE_FUNCPTR(gnutls_cipher_init);
174
MAKE_FUNCPTR(gnutls_dh_params_deinit);
175
MAKE_FUNCPTR(gnutls_dh_params_export_raw);
176
MAKE_FUNCPTR(gnutls_dh_params_import_raw);
177
MAKE_FUNCPTR(gnutls_dh_params_init);
178
MAKE_FUNCPTR(gnutls_global_deinit);
179
MAKE_FUNCPTR(gnutls_global_init);
180
MAKE_FUNCPTR(gnutls_global_set_log_function);
181
MAKE_FUNCPTR(gnutls_global_set_log_level);
182
MAKE_FUNCPTR(gnutls_perror);
183
MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
184
MAKE_FUNCPTR(gnutls_privkey_deinit);
185
MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
186
MAKE_FUNCPTR(gnutls_privkey_init);
187
MAKE_FUNCPTR(gnutls_privkey_sign_hash);
188
MAKE_FUNCPTR(gnutls_pubkey_deinit);
189
MAKE_FUNCPTR(gnutls_pubkey_encrypt_data);
190
MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
191
MAKE_FUNCPTR(gnutls_pubkey_init);
192
#undef MAKE_FUNCPTR
193
194
static int compat_gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
195
{
196
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
197
}
198
199
static int compat_gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext, size_t ptext_size)
200
{
201
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
202
}
203
204
static int compat_gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t curve,
205
const gnutls_datum_t *x, const gnutls_datum_t *y)
206
{
207
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
208
}
209
210
static int compat_gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
211
gnutls_datum_t *x, gnutls_datum_t *y)
212
{
213
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
214
}
215
216
static int compat_gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
217
gnutls_datum_t *g, gnutls_datum_t *y)
218
{
219
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
220
}
221
222
static int compat_gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key, gnutls_datum_t *m, gnutls_datum_t *e)
223
{
224
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
225
}
226
227
static int compat_gnutls_privkey_export_rsa_raw(gnutls_privkey_t key, gnutls_datum_t *m, gnutls_datum_t *e,
228
gnutls_datum_t *d, gnutls_datum_t *p, gnutls_datum_t *q,
229
gnutls_datum_t *u, gnutls_datum_t *e1, gnutls_datum_t *e2)
230
{
231
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
232
}
233
234
static int compat_gnutls_privkey_export_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t *curve,
235
gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k)
236
{
237
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
238
}
239
240
static int compat_gnutls_privkey_import_ecc_raw(gnutls_privkey_t key, gnutls_ecc_curve_t curve,
241
const gnutls_datum_t *x, const gnutls_datum_t *y,
242
const gnutls_datum_t *k)
243
{
244
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
245
}
246
247
static int compat_gnutls_privkey_export_dsa_raw(gnutls_privkey_t key, gnutls_datum_t *p, gnutls_datum_t *q,
248
gnutls_datum_t *g, gnutls_datum_t *y, gnutls_datum_t *x)
249
{
250
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
251
}
252
253
static gnutls_sign_algorithm_t compat_gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
254
{
255
return GNUTLS_SIGN_UNKNOWN;
256
}
257
258
static int compat_gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo,
259
unsigned int flags, const gnutls_datum_t *hash,
260
const gnutls_datum_t *signature)
261
{
262
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
263
}
264
265
static int compat_gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e)
266
{
267
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
268
}
269
270
static int compat_gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p, const gnutls_datum_t *q,
271
const gnutls_datum_t *g, const gnutls_datum_t *y)
272
{
273
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
274
}
275
276
static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
277
{
278
return GNUTLS_E_INTERNAL_ERROR;
279
}
280
281
static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
282
const gnutls_datum_t *d, const gnutls_datum_t *p, const gnutls_datum_t *q,
283
const gnutls_datum_t *u, const gnutls_datum_t *e1, const gnutls_datum_t *e2)
284
{
285
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
286
}
287
288
static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
289
gnutls_datum_t *plain_text)
290
{
291
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
292
}
293
294
static int compat_gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
295
gnutls_datum_t *plain_text)
296
{
297
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
298
}
299
300
static int compat_gnutls_x509_spki_init(gnutls_x509_spki_t *spki)
301
{
302
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
303
}
304
305
static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
306
{
307
}
308
309
static int compat_gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
310
gnutls_datum_t *label)
311
{
312
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
313
}
314
315
static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
316
unsigned int salt_size)
317
{
318
}
319
320
static int compat_gnutls_pubkey_set_spki(gnutls_pubkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
321
{
322
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
323
}
324
325
static int compat_gnutls_privkey_set_spki(gnutls_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
326
{
327
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
328
}
329
330
static int compat_gnutls_privkey_derive_secret(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey, const gnutls_datum_t *nonce,
331
gnutls_datum_t *secret, unsigned int flags)
332
{
333
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
334
}
335
336
static int compat_gnutls_privkey_export_dh_raw(gnutls_privkey_t privkey, gnutls_dh_params_t params, gnutls_datum_t *y,
337
gnutls_datum_t *x, unsigned int flags )
338
{
339
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
340
}
341
342
static int compat_gnutls_pubkey_export_dh_raw(gnutls_pubkey_t pubkey, gnutls_dh_params_t params, gnutls_datum_t *y,
343
unsigned flags)
344
{
345
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
346
}
347
348
static int compat_gnutls_privkey_import_dh_raw(gnutls_privkey_t privkey, const gnutls_dh_params_t params,
349
const gnutls_datum_t *y, const gnutls_datum_t *x)
350
{
351
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
352
}
353
354
static int compat_gnutls_pubkey_import_dh_raw(gnutls_pubkey_t pubkey, const gnutls_dh_params_t params,
355
const gnutls_datum_t *y)
356
{
357
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
358
}
359
360
static int compat_gnutls_privkey_generate2(gnutls_privkey_t privkey, gnutls_pk_algorithm_t alg, unsigned int bits,
361
unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
362
{
363
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
364
}
365
366
static void gnutls_log( int level, const char *msg )
367
{
368
TRACE( "<%d> %s", level, msg );
369
}
370
371
static NTSTATUS gnutls_process_attach( void *args )
372
{
373
const char *env_str;
374
int ret;
375
376
if ((env_str = getenv("GNUTLS_SYSTEM_PRIORITY_FILE")))
377
{
378
WARN("GNUTLS_SYSTEM_PRIORITY_FILE is %s.\n", debugstr_a(env_str));
379
}
380
else
381
{
382
WARN("Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
383
setenv("GNUTLS_SYSTEM_PRIORITY_FILE", "/dev/null", 0);
384
}
385
386
if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS, RTLD_NOW )))
387
{
388
ERR_(winediag)( "failed to load libgnutls, no support for encryption\n" );
389
return STATUS_DLL_NOT_FOUND;
390
}
391
392
#define LOAD_FUNCPTR(f) \
393
if (!(p##f = dlsym( libgnutls_handle, #f ))) \
394
{ \
395
ERR( "failed to load %s\n", #f ); \
396
goto fail; \
397
}
398
399
LOAD_FUNCPTR(gnutls_cipher_decrypt2)
400
LOAD_FUNCPTR(gnutls_cipher_deinit)
401
LOAD_FUNCPTR(gnutls_cipher_encrypt2)
402
LOAD_FUNCPTR(gnutls_cipher_init)
403
LOAD_FUNCPTR(gnutls_dh_params_deinit)
404
LOAD_FUNCPTR(gnutls_dh_params_export_raw)
405
LOAD_FUNCPTR(gnutls_dh_params_import_raw)
406
LOAD_FUNCPTR(gnutls_dh_params_init)
407
LOAD_FUNCPTR(gnutls_global_deinit)
408
LOAD_FUNCPTR(gnutls_global_init)
409
LOAD_FUNCPTR(gnutls_global_set_log_function)
410
LOAD_FUNCPTR(gnutls_global_set_log_level)
411
LOAD_FUNCPTR(gnutls_perror)
412
LOAD_FUNCPTR(gnutls_privkey_deinit);
413
LOAD_FUNCPTR(gnutls_privkey_import_dsa_raw);
414
LOAD_FUNCPTR(gnutls_privkey_init);
415
LOAD_FUNCPTR(gnutls_privkey_sign_hash);
416
LOAD_FUNCPTR(gnutls_pubkey_deinit);
417
LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
418
LOAD_FUNCPTR(gnutls_pubkey_init);
419
#undef LOAD_FUNCPTR
420
421
#define LOAD_FUNCPTR_OPT(f) \
422
if (!(p##f = dlsym( libgnutls_handle, #f ))) \
423
{ \
424
WARN( "failed to load %s\n", #f ); \
425
p##f = compat_##f; \
426
}
427
428
LOAD_FUNCPTR_OPT(gnutls_cipher_tag)
429
LOAD_FUNCPTR_OPT(gnutls_cipher_add_auth)
430
LOAD_FUNCPTR_OPT(gnutls_decode_rs_value)
431
LOAD_FUNCPTR_OPT(gnutls_pk_to_sign)
432
LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data)
433
LOAD_FUNCPTR_OPT(gnutls_privkey_derive_secret)
434
LOAD_FUNCPTR_OPT(gnutls_privkey_export_dh_raw)
435
LOAD_FUNCPTR_OPT(gnutls_privkey_export_dsa_raw)
436
LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
437
LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
438
LOAD_FUNCPTR_OPT(gnutls_privkey_generate2)
439
LOAD_FUNCPTR_OPT(gnutls_privkey_import_dh_raw)
440
LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
441
LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
442
LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki)
443
LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data)
444
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dh_raw)
445
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
446
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
447
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
448
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dh_raw)
449
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
450
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
451
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
452
LOAD_FUNCPTR_OPT(gnutls_pubkey_set_spki)
453
LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
454
LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
455
LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
456
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_oaep_params)
457
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
458
459
#undef LOAD_FUNCPTR_OPT
460
461
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
462
{
463
pgnutls_perror( ret );
464
goto fail;
465
}
466
467
if (TRACE_ON( bcrypt ))
468
{
469
char *env = getenv("GNUTLS_DEBUG_LEVEL");
470
int level = env ? atoi(env) : 4;
471
pgnutls_global_set_log_level(level);
472
pgnutls_global_set_log_function( gnutls_log );
473
}
474
475
return STATUS_SUCCESS;
476
477
fail:
478
dlclose( libgnutls_handle );
479
libgnutls_handle = NULL;
480
return STATUS_DLL_NOT_FOUND;
481
}
482
483
static NTSTATUS gnutls_process_detach( void *args )
484
{
485
if (libgnutls_handle)
486
{
487
if (TRACE_ON( bcrypt ))
488
pgnutls_global_set_log_function( NULL );
489
pgnutls_global_deinit();
490
dlclose( libgnutls_handle );
491
libgnutls_handle = NULL;
492
}
493
return STATUS_SUCCESS;
494
}
495
496
struct buffer
497
{
498
BYTE *buffer;
499
DWORD length;
500
DWORD pos;
501
BOOL error;
502
};
503
504
static void buffer_init( struct buffer *buffer )
505
{
506
buffer->buffer = NULL;
507
buffer->length = 0;
508
buffer->pos = 0;
509
buffer->error = FALSE;
510
}
511
512
static void buffer_free( struct buffer *buffer )
513
{
514
free( buffer->buffer );
515
}
516
517
static void buffer_append( struct buffer *buffer, BYTE *data, DWORD len )
518
{
519
if (!len) return;
520
521
if (buffer->pos + len > buffer->length)
522
{
523
DWORD new_length = max( max( buffer->pos + len, buffer->length * 2 ), 64 );
524
BYTE *new_buffer;
525
526
if (!(new_buffer = realloc( buffer->buffer, new_length )))
527
{
528
ERR( "out of memory\n" );
529
buffer->error = TRUE;
530
return;
531
}
532
533
buffer->buffer = new_buffer;
534
buffer->length = new_length;
535
}
536
537
memcpy( &buffer->buffer[buffer->pos], data, len );
538
buffer->pos += len;
539
}
540
541
static void buffer_append_byte( struct buffer *buffer, BYTE value )
542
{
543
buffer_append( buffer, &value, sizeof(value) );
544
}
545
546
static void buffer_append_asn1_length( struct buffer *buffer, DWORD length )
547
{
548
DWORD num_bytes;
549
550
if (length < 128)
551
{
552
buffer_append_byte( buffer, length );
553
return;
554
}
555
556
if (length <= 0xff) num_bytes = 1;
557
else if (length <= 0xffff) num_bytes = 2;
558
else if (length <= 0xffffff) num_bytes = 3;
559
else num_bytes = 4;
560
561
buffer_append_byte( buffer, 0x80 | num_bytes );
562
while (num_bytes--) buffer_append_byte( buffer, length >> (num_bytes * 8) );
563
}
564
565
static void buffer_append_asn1_integer( struct buffer *buffer, BYTE *data, DWORD len )
566
{
567
DWORD leading_zero = (*data & 0x80) != 0;
568
569
buffer_append_byte( buffer, 0x02 ); /* tag */
570
buffer_append_asn1_length( buffer, len + leading_zero );
571
if (leading_zero) buffer_append_byte( buffer, 0 );
572
buffer_append( buffer, data, len );
573
}
574
575
static void buffer_append_asn1_sequence( struct buffer *buffer, struct buffer *content )
576
{
577
if (content->error)
578
{
579
buffer->error = TRUE;
580
return;
581
}
582
583
buffer_append_byte( buffer, 0x30 ); /* tag */
584
buffer_append_asn1_length( buffer, content->pos );
585
buffer_append( buffer, content->buffer, content->pos );
586
}
587
588
static void buffer_append_asn1_r_s( struct buffer *buffer, BYTE *r, DWORD r_len, BYTE *s, DWORD s_len )
589
{
590
struct buffer value;
591
592
buffer_init( &value );
593
buffer_append_asn1_integer( &value, r, r_len );
594
buffer_append_asn1_integer( &value, s, s_len );
595
buffer_append_asn1_sequence( buffer, &value );
596
buffer_free( &value );
597
}
598
599
static gnutls_cipher_algorithm_t get_gnutls_cipher( const struct key *key )
600
{
601
switch (key->alg_id)
602
{
603
case ALG_ID_3DES:
604
WARN( "handle block size\n" );
605
switch (key->u.s.mode)
606
{
607
case CHAIN_MODE_CBC:
608
return GNUTLS_CIPHER_3DES_CBC;
609
default:
610
break;
611
}
612
FIXME( "3DES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
613
return GNUTLS_CIPHER_UNKNOWN;
614
615
case ALG_ID_AES:
616
WARN( "handle block size\n" );
617
switch (key->u.s.mode)
618
{
619
case CHAIN_MODE_GCM:
620
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_GCM;
621
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_GCM;
622
break;
623
case CHAIN_MODE_ECB: /* can be emulated with CBC + empty IV */
624
case CHAIN_MODE_CBC:
625
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CBC;
626
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CBC;
627
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CBC;
628
break;
629
case CHAIN_MODE_CFB:
630
if (key->u.s.secret_len == 16) return GNUTLS_CIPHER_AES_128_CFB8;
631
if (key->u.s.secret_len == 24) return GNUTLS_CIPHER_AES_192_CFB8;
632
if (key->u.s.secret_len == 32) return GNUTLS_CIPHER_AES_256_CFB8;
633
break;
634
default:
635
break;
636
}
637
FIXME( "AES mode %u with key length %u not supported\n", key->u.s.mode, key->u.s.secret_len );
638
return GNUTLS_CIPHER_UNKNOWN;
639
640
default:
641
FIXME( "algorithm %u not supported\n", key->alg_id );
642
return GNUTLS_CIPHER_UNKNOWN;
643
}
644
}
645
646
static NTSTATUS key_symmetric_vector_reset( void *args )
647
{
648
struct key *key = args;
649
650
if (!key_data(key)->cipher) return STATUS_SUCCESS;
651
TRACE( "invalidating cipher handle\n" );
652
pgnutls_cipher_deinit( key_data(key)->cipher );
653
key_data(key)->cipher = NULL;
654
return STATUS_SUCCESS;
655
}
656
657
static NTSTATUS init_cipher_handle( struct key *key )
658
{
659
gnutls_cipher_algorithm_t cipher;
660
gnutls_datum_t secret, vector;
661
int ret;
662
663
if (key_data(key)->cipher) return STATUS_SUCCESS;
664
if ((cipher = get_gnutls_cipher( key )) == GNUTLS_CIPHER_UNKNOWN) return STATUS_NOT_SUPPORTED;
665
666
secret.data = key->u.s.secret;
667
secret.size = key->u.s.secret_len;
668
669
vector.data = key->u.s.vector;
670
vector.size = key->u.s.vector_len;
671
672
if ((ret = pgnutls_cipher_init( &key_data(key)->cipher, cipher, &secret, key->u.s.vector ? &vector : NULL )))
673
{
674
pgnutls_perror( ret );
675
return STATUS_INTERNAL_ERROR;
676
}
677
678
return STATUS_SUCCESS;
679
}
680
681
static NTSTATUS key_symmetric_set_auth_data( void *args )
682
{
683
const struct key_symmetric_set_auth_data_params *params = args;
684
NTSTATUS status;
685
int ret;
686
687
if (!params->auth_data) return STATUS_SUCCESS;
688
if ((status = init_cipher_handle( params->key ))) return status;
689
690
if ((ret = pgnutls_cipher_add_auth( key_data(params->key)->cipher, params->auth_data, params->len )))
691
{
692
pgnutls_perror( ret );
693
return STATUS_INTERNAL_ERROR;
694
}
695
return STATUS_SUCCESS;
696
}
697
698
static NTSTATUS key_symmetric_encrypt( void *args )
699
{
700
const struct key_symmetric_encrypt_params *params = args;
701
NTSTATUS status;
702
int ret;
703
704
if ((status = init_cipher_handle( params->key ))) return status;
705
706
if ((ret = pgnutls_cipher_encrypt2( key_data(params->key)->cipher, params->input, params->input_len,
707
params->output, params->output_len )))
708
{
709
pgnutls_perror( ret );
710
return STATUS_INTERNAL_ERROR;
711
}
712
return STATUS_SUCCESS;
713
}
714
715
static NTSTATUS key_symmetric_decrypt( void *args )
716
{
717
const struct key_symmetric_decrypt_params *params = args;
718
NTSTATUS status;
719
int ret;
720
721
if ((status = init_cipher_handle( params->key ))) return status;
722
723
if ((ret = pgnutls_cipher_decrypt2( key_data(params->key)->cipher, params->input, params->input_len,
724
params->output, params->output_len )))
725
{
726
pgnutls_perror( ret );
727
return STATUS_INTERNAL_ERROR;
728
}
729
return STATUS_SUCCESS;
730
}
731
732
static NTSTATUS key_symmetric_get_tag( void *args )
733
{
734
const struct key_symmetric_get_tag_params *params = args;
735
NTSTATUS status;
736
int ret;
737
738
if ((status = init_cipher_handle( params->key ))) return status;
739
740
if ((ret = pgnutls_cipher_tag( key_data(params->key)->cipher, params->tag, params->len )))
741
{
742
pgnutls_perror( ret );
743
return STATUS_INTERNAL_ERROR;
744
}
745
return STATUS_SUCCESS;
746
}
747
748
static NTSTATUS key_symmetric_destroy( void *args )
749
{
750
struct key *key = args;
751
752
if (key_data(key)->cipher) pgnutls_cipher_deinit( key_data(key)->cipher );
753
return STATUS_SUCCESS;
754
}
755
756
static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d, BOOL zero_pad )
757
{
758
ULONG size = d->size;
759
UCHAR *src = d->data;
760
ULONG offset = 0;
761
762
assert( size <= buflen + 1 );
763
if (size == buflen + 1)
764
{
765
assert( !src[0] );
766
src++;
767
size--;
768
}
769
if (zero_pad)
770
{
771
offset = buflen - size;
772
if (buffer) memset( buffer, 0, offset );
773
size = buflen;
774
}
775
776
if (buffer) memcpy( buffer + offset, src, size - offset );
777
return size;
778
}
779
780
#define EXPORT_SIZE(d,l,p) export_gnutls_datum( NULL, l, &d, p )
781
static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
782
{
783
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
784
gnutls_datum_t m, e;
785
ULONG size = len_from_bitlen( key->u.a.bitlen );
786
UCHAR *dst;
787
int ret;
788
789
if (key_data(key)->a.pubkey)
790
ret = pgnutls_pubkey_export_rsa_raw( key_data(key)->a.pubkey, &m, &e );
791
else
792
return STATUS_INVALID_PARAMETER;
793
794
if (ret)
795
{
796
pgnutls_perror( ret );
797
return STATUS_INTERNAL_ERROR;
798
}
799
800
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 );
801
if (len >= *ret_len && buf)
802
{
803
dst = (UCHAR *)(rsa_blob + 1);
804
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
805
806
dst += rsa_blob->cbPublicExp;
807
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
808
809
rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
810
rsa_blob->BitLength = key->u.a.bitlen;
811
rsa_blob->cbPrime1 = 0;
812
rsa_blob->cbPrime2 = 0;
813
}
814
815
free( e.data ); free( m.data );
816
return STATUS_SUCCESS;
817
}
818
819
static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
820
{
821
BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
822
gnutls_ecc_curve_t curve;
823
gnutls_datum_t x, y;
824
DWORD magic, size;
825
UCHAR *dst;
826
int ret;
827
828
switch (key->alg_id)
829
{
830
case ALG_ID_ECDH:
831
switch (key->u.a.curve_id)
832
{
833
case ECC_CURVE_P256R1:
834
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
835
size = 32;
836
break;
837
case ECC_CURVE_P384R1:
838
magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
839
size = 48;
840
break;
841
case ECC_CURVE_P521R1:
842
magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC;
843
size = 66;
844
break;
845
default:
846
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
847
return STATUS_NOT_IMPLEMENTED;
848
}
849
break;
850
851
case ALG_ID_ECDH_P256:
852
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
853
size = 32;
854
break;
855
856
case ALG_ID_ECDH_P384:
857
magic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;
858
size = 48;
859
break;
860
861
case ALG_ID_ECDH_P521:
862
magic = BCRYPT_ECDH_PUBLIC_P521_MAGIC;
863
size = 66;
864
break;
865
866
case ALG_ID_ECDSA:
867
switch (key->u.a.curve_id)
868
{
869
case ECC_CURVE_P256R1:
870
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
871
size = 32;
872
break;
873
case ECC_CURVE_P384R1:
874
magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
875
size = 48;
876
break;
877
case ECC_CURVE_P521R1:
878
magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
879
size = 66;
880
break;
881
default:
882
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
883
return STATUS_NOT_IMPLEMENTED;
884
}
885
break;
886
887
case ALG_ID_ECDSA_P256:
888
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
889
size = 32;
890
break;
891
892
case ALG_ID_ECDSA_P384:
893
magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
894
size = 48;
895
break;
896
897
case ALG_ID_ECDSA_P521:
898
magic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
899
size = 66;
900
break;
901
902
default:
903
FIXME( "algorithm %u not supported\n", key->alg_id );
904
return STATUS_NOT_IMPLEMENTED;
905
}
906
907
if (key_data(key)->a.pubkey)
908
ret = pgnutls_pubkey_export_ecc_raw( key_data(key)->a.pubkey, &curve, &x, &y );
909
else
910
return STATUS_INVALID_PARAMETER;
911
912
if (ret)
913
{
914
pgnutls_perror( ret );
915
return STATUS_INTERNAL_ERROR;
916
}
917
918
if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
919
{
920
FIXME( "curve %u not supported\n", curve );
921
free( x.data ); free( y.data );
922
return STATUS_NOT_IMPLEMENTED;
923
}
924
925
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 );
926
if (len >= *ret_len && buf)
927
{
928
ecc_blob->dwMagic = magic;
929
ecc_blob->cbKey = size;
930
931
dst = (UCHAR *)(ecc_blob + 1);
932
dst += export_gnutls_datum( dst, size, &x, 1 );
933
export_gnutls_datum( dst, size, &y, 1 );
934
}
935
936
free( x.data ); free( y.data );
937
return STATUS_SUCCESS;
938
}
939
940
static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
941
{
942
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
943
gnutls_datum_t p, q, g, y;
944
ULONG size = len_from_bitlen( key->u.a.bitlen );
945
NTSTATUS status = STATUS_SUCCESS;
946
UCHAR *dst;
947
int ret;
948
949
if (key->u.a.bitlen > 1024)
950
{
951
FIXME( "bitlen > 1024 not supported\n" );
952
return STATUS_NOT_IMPLEMENTED;
953
}
954
955
if (key_data(key)->a.pubkey)
956
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
957
else
958
return STATUS_INVALID_PARAMETER;
959
960
if (ret)
961
{
962
pgnutls_perror( ret );
963
return STATUS_INTERNAL_ERROR;
964
}
965
966
if (EXPORT_SIZE( q, sizeof(dsa_blob->q), 1 ) > sizeof(dsa_blob->q))
967
{
968
status = STATUS_INVALID_PARAMETER;
969
goto done;
970
}
971
972
*ret_len = sizeof(*dsa_blob) + EXPORT_SIZE( p, size, 1 ) + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
973
if (len >= *ret_len && buf)
974
{
975
dst = (UCHAR *)(dsa_blob + 1);
976
dst += export_gnutls_datum( dst, size, &p, 1 );
977
dst += export_gnutls_datum( dst, size, &g, 1 );
978
export_gnutls_datum( dst, size, &y, 1 );
979
980
dst = dsa_blob->q;
981
export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
982
983
dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
984
dsa_blob->cbKey = size;
985
memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
986
memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
987
}
988
989
done:
990
free( p.data ); free( q.data ); free( g.data ); free( y.data );
991
return status;
992
}
993
994
static void reverse_bytes( UCHAR *buf, ULONG len )
995
{
996
unsigned int i;
997
UCHAR tmp;
998
999
for (i = 0; i < len / 2; ++i)
1000
{
1001
tmp = buf[i];
1002
buf[i] = buf[len - i - 1];
1003
buf[len - i - 1] = tmp;
1004
}
1005
}
1006
1007
#define Q_SIZE 20
1008
static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1009
{
1010
BLOBHEADER *hdr = (BLOBHEADER *)buf;
1011
DSSPUBKEY *dsskey;
1012
gnutls_datum_t p, q, g, y;
1013
ULONG size = len_from_bitlen( key->u.a.bitlen );
1014
NTSTATUS status = STATUS_SUCCESS;
1015
UCHAR *dst;
1016
int ret;
1017
1018
if (key->u.a.bitlen > 1024)
1019
{
1020
FIXME( "bitlen > 1024 not supported\n" );
1021
return STATUS_NOT_IMPLEMENTED;
1022
}
1023
1024
if (key_data(key)->a.pubkey)
1025
ret = pgnutls_pubkey_export_dsa_raw( key_data(key)->a.pubkey, &p, &q, &g, &y );
1026
else if (key_data(key)->a.privkey)
1027
ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL );
1028
else
1029
return STATUS_INVALID_PARAMETER;
1030
1031
if (ret)
1032
{
1033
pgnutls_perror( ret );
1034
return STATUS_INTERNAL_ERROR;
1035
}
1036
1037
if (EXPORT_SIZE( q, Q_SIZE, 1 ) > Q_SIZE)
1038
{
1039
status = STATUS_INVALID_PARAMETER;
1040
goto done;
1041
}
1042
1043
*ret_len = sizeof(*hdr) + sizeof(*dsskey) + sizeof(key->u.a.dss_seed) +
1044
EXPORT_SIZE( p, size, 1 ) + Q_SIZE + EXPORT_SIZE( g, size, 1 ) + EXPORT_SIZE( y, size, 1 );
1045
if (len >= *ret_len && buf)
1046
{
1047
hdr->bType = PUBLICKEYBLOB;
1048
hdr->bVersion = 2;
1049
hdr->reserved = 0;
1050
hdr->aiKeyAlg = CALG_DSS_SIGN;
1051
1052
dsskey = (DSSPUBKEY *)(hdr + 1);
1053
dsskey->magic = MAGIC_DSS1;
1054
dsskey->bitlen = key->u.a.bitlen;
1055
1056
dst = (UCHAR *)(dsskey + 1);
1057
export_gnutls_datum( dst, size, &p, 1 );
1058
reverse_bytes( dst, size );
1059
dst += size;
1060
1061
export_gnutls_datum( dst, Q_SIZE, &q, 1 );
1062
reverse_bytes( dst, Q_SIZE );
1063
dst += Q_SIZE;
1064
1065
export_gnutls_datum( dst, size, &g, 1 );
1066
reverse_bytes( dst, size );
1067
dst += size;
1068
1069
export_gnutls_datum( dst, size, &y, 1 );
1070
reverse_bytes( dst, size );
1071
dst += size;
1072
1073
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1074
}
1075
1076
done:
1077
free( p.data ); free( q.data ); free( g.data ); free( y.data );
1078
return status;
1079
}
1080
1081
static gnutls_privkey_t create_privkey( gnutls_pk_algorithm_t pk_alg, unsigned int bitlen,
1082
const gnutls_keygen_data_st *data, unsigned int data_size )
1083
{
1084
gnutls_privkey_t privkey;
1085
int ret;
1086
1087
if ((ret = pgnutls_privkey_init( &privkey )))
1088
{
1089
pgnutls_perror( ret );
1090
return NULL;
1091
}
1092
1093
if ((ret = pgnutls_privkey_generate2( privkey, pk_alg, bitlen, 0, data, data_size )))
1094
{
1095
pgnutls_perror( ret );
1096
pgnutls_privkey_deinit( privkey );
1097
return NULL;
1098
}
1099
1100
return privkey;
1101
}
1102
1103
static gnutls_pubkey_t create_pubkey_from_privkey( gnutls_privkey_t privkey )
1104
{
1105
gnutls_pubkey_t pubkey;
1106
int ret;
1107
1108
if ((ret = pgnutls_pubkey_init( &pubkey )))
1109
{
1110
pgnutls_perror( ret );
1111
return NULL;
1112
}
1113
1114
if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
1115
{
1116
pgnutls_perror( ret );
1117
pgnutls_pubkey_deinit( pubkey );
1118
return NULL;
1119
}
1120
1121
return pubkey;
1122
}
1123
1124
static gnutls_dh_params_t get_dh_params( gnutls_privkey_t privkey )
1125
{
1126
gnutls_dh_params_t params;
1127
gnutls_datum_t x;
1128
int ret;
1129
1130
if ((ret = pgnutls_dh_params_init( &params )))
1131
{
1132
pgnutls_perror( ret );
1133
return NULL;
1134
}
1135
1136
if ((ret = pgnutls_privkey_export_dh_raw( privkey, params, NULL, &x, 0 )))
1137
{
1138
pgnutls_perror( ret );
1139
pgnutls_dh_params_deinit( params );
1140
return NULL;
1141
}
1142
1143
free( x.data );
1144
return params;
1145
}
1146
1147
static NTSTATUS key_asymmetric_generate( void *args )
1148
{
1149
struct key *key = args;
1150
gnutls_pk_algorithm_t pk_alg;
1151
gnutls_privkey_t privkey;
1152
gnutls_pubkey_t pubkey;
1153
unsigned int bitlen;
1154
1155
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
1156
if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
1157
1158
switch (key->alg_id)
1159
{
1160
case ALG_ID_RSA:
1161
case ALG_ID_RSA_SIGN:
1162
pk_alg = GNUTLS_PK_RSA;
1163
bitlen = key->u.a.bitlen;
1164
break;
1165
1166
case ALG_ID_DH:
1167
pk_alg = GNUTLS_PK_DH;
1168
bitlen = key->u.a.bitlen;
1169
break;
1170
1171
case ALG_ID_DSA:
1172
pk_alg = GNUTLS_PK_DSA;
1173
bitlen = key->u.a.bitlen;
1174
break;
1175
1176
case ALG_ID_ECDH:
1177
case ALG_ID_ECDSA:
1178
pk_alg = GNUTLS_PK_ECC;
1179
switch (key->u.a.curve_id)
1180
{
1181
case ECC_CURVE_P256R1:
1182
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1183
break;
1184
case ECC_CURVE_P384R1:
1185
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1186
break;
1187
case ECC_CURVE_P521R1:
1188
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP521R1 );
1189
break;
1190
default:
1191
FIXME( "unsupported ECDH/ECDSA curve %u\n", key->u.a.curve_id );
1192
return STATUS_INVALID_PARAMETER;
1193
}
1194
break;
1195
1196
case ALG_ID_ECDH_P256:
1197
case ALG_ID_ECDSA_P256:
1198
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1199
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
1200
break;
1201
1202
case ALG_ID_ECDH_P384:
1203
case ALG_ID_ECDSA_P384:
1204
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1205
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP384R1 );
1206
break;
1207
1208
case ALG_ID_ECDH_P521:
1209
case ALG_ID_ECDSA_P521:
1210
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
1211
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP521R1 );
1212
break;
1213
1214
default:
1215
FIXME( "algorithm %u not supported\n", key->alg_id );
1216
return STATUS_NOT_SUPPORTED;
1217
}
1218
1219
if (key->alg_id == ALG_ID_DH && key_data(key)->a.dh_params)
1220
{
1221
gnutls_keygen_data_st data;
1222
1223
data.type = GNUTLS_KEYGEN_DH;
1224
data.data = (unsigned char *)key_data(key)->a.dh_params;
1225
data.size = 0;
1226
if (!(privkey = create_privkey( pk_alg, bitlen, &data, 1 ))) return STATUS_INTERNAL_ERROR;
1227
}
1228
else if (!(privkey = create_privkey( pk_alg, bitlen, NULL, 0 ))) return STATUS_INTERNAL_ERROR;
1229
1230
if (key->alg_id == ALG_ID_DH && !key_data(key)->a.dh_params &&
1231
!(key_data(key)->a.dh_params = get_dh_params( privkey )))
1232
{
1233
pgnutls_privkey_deinit( privkey );
1234
return STATUS_INTERNAL_ERROR;
1235
}
1236
1237
if (!(pubkey = create_pubkey_from_privkey( privkey )))
1238
{
1239
pgnutls_privkey_deinit( privkey );
1240
return STATUS_INTERNAL_ERROR;
1241
}
1242
1243
key_data(key)->a.privkey = privkey;
1244
key_data(key)->a.pubkey = pubkey;
1245
return STATUS_SUCCESS;
1246
}
1247
1248
static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1249
{
1250
BCRYPT_ECCKEY_BLOB *ecc_blob;
1251
gnutls_ecc_curve_t curve;
1252
gnutls_datum_t x, y, d;
1253
DWORD magic, size;
1254
UCHAR *dst;
1255
int ret;
1256
1257
switch (key->alg_id)
1258
{
1259
case ALG_ID_ECDH:
1260
switch (key->u.a.curve_id)
1261
{
1262
case ECC_CURVE_P256R1:
1263
magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1264
size = 32;
1265
break;
1266
case ECC_CURVE_P384R1:
1267
magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1268
size = 48;
1269
break;
1270
case ECC_CURVE_P521R1:
1271
magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC;
1272
size = 66;
1273
break;
1274
default:
1275
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
1276
return STATUS_NOT_IMPLEMENTED;
1277
}
1278
break;
1279
1280
case ALG_ID_ECDH_P256:
1281
magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
1282
size = 32;
1283
break;
1284
1285
case ALG_ID_ECDH_P384:
1286
magic = BCRYPT_ECDH_PRIVATE_P384_MAGIC;
1287
size = 48;
1288
break;
1289
1290
case ALG_ID_ECDH_P521:
1291
magic = BCRYPT_ECDH_PRIVATE_P521_MAGIC;
1292
size = 66;
1293
break;
1294
1295
case ALG_ID_ECDSA:
1296
switch (key->u.a.curve_id)
1297
{
1298
case ECC_CURVE_P256R1:
1299
magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1300
size = 32;
1301
break;
1302
case ECC_CURVE_P384R1:
1303
magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1304
size = 48;
1305
break;
1306
case ECC_CURVE_P521R1:
1307
magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
1308
size = 66;
1309
break;
1310
default:
1311
FIXME( "unsupported curve %u\n", key->u.a.curve_id );
1312
return STATUS_NOT_IMPLEMENTED;
1313
}
1314
break;
1315
1316
case ALG_ID_ECDSA_P256:
1317
magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
1318
size = 32;
1319
break;
1320
1321
case ALG_ID_ECDSA_P384:
1322
magic = BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
1323
size = 48;
1324
break;
1325
1326
case ALG_ID_ECDSA_P521:
1327
magic = BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
1328
size = 66;
1329
break;
1330
1331
default:
1332
FIXME( "algorithm %u does not yet support exporting ecc blob\n", key->alg_id );
1333
return STATUS_NOT_IMPLEMENTED;
1334
}
1335
1336
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1337
1338
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
1339
{
1340
pgnutls_perror( ret );
1341
return STATUS_INTERNAL_ERROR;
1342
}
1343
1344
if (curve != GNUTLS_ECC_CURVE_SECP256R1 && curve != GNUTLS_ECC_CURVE_SECP384R1 && curve != GNUTLS_ECC_CURVE_SECP521R1)
1345
{
1346
FIXME( "curve %u not supported\n", curve );
1347
free( x.data ); free( y.data ); free( d.data );
1348
return STATUS_NOT_IMPLEMENTED;
1349
}
1350
1351
*ret_len = sizeof(*ecc_blob) + EXPORT_SIZE( x, size, 1 ) + EXPORT_SIZE( y, size, 1 ) + EXPORT_SIZE( d, size, 1 );
1352
if (len >= *ret_len && buf)
1353
{
1354
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1355
ecc_blob->dwMagic = magic;
1356
ecc_blob->cbKey = size;
1357
1358
dst = (UCHAR *)(ecc_blob + 1);
1359
dst += export_gnutls_datum( dst, size, &x, 1 );
1360
dst += export_gnutls_datum( dst, size, &y, 1 );
1361
export_gnutls_datum( dst, size, &d, 1 );
1362
}
1363
1364
free( x.data ); free( y.data ); free( d.data );
1365
return STATUS_SUCCESS;
1366
}
1367
1368
static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
1369
{
1370
BCRYPT_ECCKEY_BLOB *ecc_blob;
1371
gnutls_ecc_curve_t curve;
1372
gnutls_privkey_t handle;
1373
gnutls_datum_t x, y, k;
1374
int ret;
1375
1376
switch (key->alg_id)
1377
{
1378
case ALG_ID_ECDH_P256:
1379
case ALG_ID_ECDSA_P256:
1380
curve = GNUTLS_ECC_CURVE_SECP256R1;
1381
break;
1382
1383
case ALG_ID_ECDH_P384:
1384
case ALG_ID_ECDSA_P384:
1385
curve = GNUTLS_ECC_CURVE_SECP384R1;
1386
break;
1387
1388
case ALG_ID_ECDH_P521:
1389
case ALG_ID_ECDSA_P521:
1390
curve = GNUTLS_ECC_CURVE_SECP521R1;
1391
break;
1392
1393
default:
1394
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1395
return STATUS_NOT_IMPLEMENTED;
1396
}
1397
1398
if ((ret = pgnutls_privkey_init( &handle )))
1399
{
1400
pgnutls_perror( ret );
1401
return STATUS_INTERNAL_ERROR;
1402
}
1403
1404
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1405
x.data = (unsigned char *)(ecc_blob + 1);
1406
x.size = ecc_blob->cbKey;
1407
y.data = x.data + ecc_blob->cbKey;
1408
y.size = ecc_blob->cbKey;
1409
k.data = y.data + ecc_blob->cbKey;
1410
k.size = ecc_blob->cbKey;
1411
1412
if ((ret = pgnutls_privkey_import_ecc_raw( handle, curve, &x, &y, &k )))
1413
{
1414
pgnutls_perror( ret );
1415
pgnutls_privkey_deinit( handle );
1416
return STATUS_INTERNAL_ERROR;
1417
}
1418
1419
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1420
key_data(key)->a.privkey = handle;
1421
return STATUS_SUCCESS;
1422
}
1423
1424
static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG len, ULONG *ret_len )
1425
{
1426
BCRYPT_RSAKEY_BLOB *rsa_blob;
1427
gnutls_datum_t m, e, d, p, q, u, e1, e2;
1428
ULONG size = len_from_bitlen( key->u.a.bitlen );
1429
BOOL full = (flags & KEY_EXPORT_FLAG_RSA_FULL);
1430
UCHAR *dst;
1431
int ret;
1432
1433
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1434
1435
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
1436
{
1437
pgnutls_perror( ret );
1438
return STATUS_INTERNAL_ERROR;
1439
}
1440
1441
*ret_len = sizeof(*rsa_blob) + EXPORT_SIZE( e, size, 0 ) + EXPORT_SIZE( m, size, 1 ) +
1442
EXPORT_SIZE( p, size / 2, 1 ) + EXPORT_SIZE( q, size / 2, 1 );
1443
1444
if (full) *ret_len += EXPORT_SIZE( e1, size / 2, 1 ) + EXPORT_SIZE( e2, size / 2, 1 ) +
1445
EXPORT_SIZE( u, size / 2, 1 ) + EXPORT_SIZE( d, size, 1 );
1446
1447
if (len >= *ret_len && buf)
1448
{
1449
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1450
rsa_blob->Magic = full ? BCRYPT_RSAFULLPRIVATE_MAGIC : BCRYPT_RSAPRIVATE_MAGIC;
1451
rsa_blob->BitLength = key->u.a.bitlen;
1452
1453
dst = (UCHAR *)(rsa_blob + 1);
1454
rsa_blob->cbPublicExp = export_gnutls_datum( dst, size, &e, 0 );
1455
1456
dst += rsa_blob->cbPublicExp;
1457
rsa_blob->cbModulus = export_gnutls_datum( dst, size, &m, 1 );
1458
1459
dst += rsa_blob->cbModulus;
1460
rsa_blob->cbPrime1 = export_gnutls_datum( dst, size / 2, &p, 1 );
1461
1462
dst += rsa_blob->cbPrime1;
1463
rsa_blob->cbPrime2 = export_gnutls_datum( dst, size / 2, &q, 1 );
1464
1465
if (full)
1466
{
1467
dst += rsa_blob->cbPrime2;
1468
export_gnutls_datum( dst, size / 2, &e1, 1 );
1469
1470
dst += rsa_blob->cbPrime1;
1471
export_gnutls_datum( dst, size / 2, &e2, 1 );
1472
1473
dst += rsa_blob->cbPrime2;
1474
export_gnutls_datum( dst, size / 2, &u, 1 );
1475
1476
dst += rsa_blob->cbPrime1;
1477
export_gnutls_datum( dst, size, &d, 1 );
1478
}
1479
}
1480
1481
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
1482
free( e1.data ); free( e2.data );
1483
return STATUS_SUCCESS;
1484
}
1485
1486
static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
1487
{
1488
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1489
gnutls_datum_t m, e, p, q;
1490
gnutls_privkey_t handle;
1491
int ret;
1492
1493
if ((ret = pgnutls_privkey_init( &handle )))
1494
{
1495
pgnutls_perror( ret );
1496
return STATUS_INTERNAL_ERROR;
1497
}
1498
1499
e.data = (unsigned char *)(rsa_blob + 1);
1500
e.size = rsa_blob->cbPublicExp;
1501
m.data = e.data + e.size;
1502
m.size = rsa_blob->cbModulus;
1503
p.data = m.data + m.size;
1504
p.size = rsa_blob->cbPrime1;
1505
q.data = p.data + p.size;
1506
q.size = rsa_blob->cbPrime2;
1507
1508
if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
1509
{
1510
pgnutls_perror( ret );
1511
pgnutls_privkey_deinit( handle );
1512
return STATUS_INTERNAL_ERROR;
1513
}
1514
1515
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1516
key_data(key)->a.privkey = handle;
1517
return STATUS_SUCCESS;
1518
}
1519
1520
static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1521
{
1522
BLOBHEADER *hdr;
1523
DSSPUBKEY *pubkey;
1524
gnutls_datum_t p, q, g, y, x;
1525
ULONG size = len_from_bitlen( key->u.a.bitlen );
1526
UCHAR *dst;
1527
int ret;
1528
1529
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1530
1531
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
1532
{
1533
pgnutls_perror( ret );
1534
return STATUS_INTERNAL_ERROR;
1535
}
1536
1537
if (q.size > 21 || x.size > 21)
1538
{
1539
ERR( "can't export key in this format\n" );
1540
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1541
return STATUS_NOT_SUPPORTED;
1542
}
1543
1544
*ret_len = sizeof(*hdr) + sizeof(*pubkey) + sizeof(key->u.a.dss_seed) +
1545
EXPORT_SIZE( p, size, 1 ) + 20 + EXPORT_SIZE( g, size, 1 ) + 20;
1546
if (len >= *ret_len && buf)
1547
{
1548
hdr = (BLOBHEADER *)buf;
1549
hdr->bType = PRIVATEKEYBLOB;
1550
hdr->bVersion = 2;
1551
hdr->reserved = 0;
1552
hdr->aiKeyAlg = CALG_DSS_SIGN;
1553
1554
pubkey = (DSSPUBKEY *)(hdr + 1);
1555
pubkey->magic = MAGIC_DSS2;
1556
pubkey->bitlen = key->u.a.bitlen;
1557
1558
dst = (UCHAR *)(pubkey + 1);
1559
export_gnutls_datum( dst, size, &p, 1 );
1560
reverse_bytes( dst, size );
1561
dst += size;
1562
1563
export_gnutls_datum( dst, 20, &q, 1 );
1564
reverse_bytes( dst, 20 );
1565
dst += 20;
1566
1567
export_gnutls_datum( dst, size, &g, 1 );
1568
reverse_bytes( dst, size );
1569
dst += size;
1570
1571
export_gnutls_datum( dst, 20, &x, 1 );
1572
reverse_bytes( dst, 20 );
1573
dst += 20;
1574
1575
memcpy( dst, &key->u.a.dss_seed, sizeof(key->u.a.dss_seed) );
1576
}
1577
1578
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
1579
return STATUS_SUCCESS;
1580
}
1581
1582
static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
1583
{
1584
BLOBHEADER *hdr = (BLOBHEADER *)buf;
1585
DSSPUBKEY *pubkey;
1586
gnutls_privkey_t handle;
1587
gnutls_datum_t p, q, g, x;
1588
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
1589
int i, ret, size;
1590
1591
if ((ret = pgnutls_privkey_init( &handle )))
1592
{
1593
pgnutls_perror( ret );
1594
return STATUS_INTERNAL_ERROR;
1595
}
1596
1597
pubkey = (DSSPUBKEY *)(hdr + 1);
1598
if ((size = len_from_bitlen( pubkey->bitlen )) > sizeof(p_data))
1599
{
1600
FIXME( "size %u not supported\n", size );
1601
pgnutls_privkey_deinit( handle );
1602
return STATUS_NOT_SUPPORTED;
1603
}
1604
data = (unsigned char *)(pubkey + 1);
1605
1606
p.data = p_data;
1607
p.size = size;
1608
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1609
data += p.size;
1610
1611
q.data = q_data;
1612
q.size = sizeof(q_data);
1613
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1614
data += q.size;
1615
1616
g.data = g_data;
1617
g.size = size;
1618
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1619
data += g.size;
1620
1621
x.data = x_data;
1622
x.size = sizeof(x_data);
1623
for (i = 0; i < x.size; i++) x.data[i] = data[x.size - i - 1];
1624
data += x.size;
1625
1626
if ((ret = pgnutls_privkey_import_dsa_raw( handle, &p, &q, &g, NULL, &x )))
1627
{
1628
pgnutls_perror( ret );
1629
pgnutls_privkey_deinit( handle );
1630
return STATUS_INTERNAL_ERROR;
1631
}
1632
1633
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
1634
1635
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
1636
key_data(key)->a.privkey = handle;
1637
return STATUS_SUCCESS;
1638
}
1639
1640
static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
1641
{
1642
BCRYPT_ECCKEY_BLOB *ecc_blob;
1643
gnutls_ecc_curve_t curve;
1644
gnutls_datum_t x, y;
1645
gnutls_pubkey_t handle;
1646
int ret;
1647
1648
switch (key->alg_id)
1649
{
1650
case ALG_ID_ECDH_P256:
1651
case ALG_ID_ECDSA_P256:
1652
curve = GNUTLS_ECC_CURVE_SECP256R1; break;
1653
1654
case ALG_ID_ECDH_P384:
1655
case ALG_ID_ECDSA_P384:
1656
curve = GNUTLS_ECC_CURVE_SECP384R1; break;
1657
1658
case ALG_ID_ECDH_P521:
1659
case ALG_ID_ECDSA_P521:
1660
curve = GNUTLS_ECC_CURVE_SECP521R1; break;
1661
1662
default:
1663
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1664
return STATUS_NOT_IMPLEMENTED;
1665
}
1666
1667
if ((ret = pgnutls_pubkey_init( &handle )))
1668
{
1669
pgnutls_perror( ret );
1670
return STATUS_INTERNAL_ERROR;
1671
}
1672
1673
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
1674
x.data = buf + sizeof(*ecc_blob);
1675
x.size = ecc_blob->cbKey;
1676
y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
1677
y.size = ecc_blob->cbKey;
1678
1679
if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
1680
{
1681
pgnutls_perror( ret );
1682
pgnutls_pubkey_deinit( handle );
1683
return STATUS_INTERNAL_ERROR;
1684
}
1685
1686
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1687
key_data(key)->a.pubkey = handle;
1688
return STATUS_SUCCESS;
1689
}
1690
1691
static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
1692
{
1693
BCRYPT_RSAKEY_BLOB *rsa_blob;
1694
gnutls_pubkey_t handle;
1695
gnutls_datum_t m, e;
1696
int ret;
1697
1698
if ((ret = pgnutls_pubkey_init( &handle )))
1699
{
1700
pgnutls_perror( ret );
1701
return STATUS_INTERNAL_ERROR;
1702
}
1703
1704
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
1705
e.data = buf + sizeof(*rsa_blob);
1706
e.size = rsa_blob->cbPublicExp;
1707
m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
1708
m.size = rsa_blob->cbModulus;
1709
1710
if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
1711
{
1712
pgnutls_perror( ret );
1713
pgnutls_pubkey_deinit( handle );
1714
return STATUS_INTERNAL_ERROR;
1715
}
1716
1717
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1718
key_data(key)->a.pubkey = handle;
1719
return STATUS_SUCCESS;
1720
}
1721
1722
static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
1723
{
1724
BCRYPT_DSA_KEY_BLOB *dsa_blob;
1725
gnutls_datum_t p, q, g, y;
1726
gnutls_pubkey_t handle;
1727
int ret;
1728
1729
if ((ret = pgnutls_pubkey_init( &handle )))
1730
{
1731
pgnutls_perror( ret );
1732
return STATUS_INTERNAL_ERROR;
1733
}
1734
1735
dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
1736
p.data = buf + sizeof(*dsa_blob);
1737
p.size = dsa_blob->cbKey;
1738
q.data = dsa_blob->q;
1739
q.size = sizeof(dsa_blob->q);
1740
g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
1741
g.size = dsa_blob->cbKey;
1742
y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
1743
y.size = dsa_blob->cbKey;
1744
1745
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1746
{
1747
pgnutls_perror( ret );
1748
pgnutls_pubkey_deinit( handle );
1749
return STATUS_INTERNAL_ERROR;
1750
}
1751
1752
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1753
key_data(key)->a.pubkey = handle;
1754
return STATUS_SUCCESS;
1755
}
1756
1757
static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
1758
{
1759
BLOBHEADER *hdr;
1760
DSSPUBKEY *pubkey;
1761
gnutls_datum_t p, q, g, y;
1762
gnutls_pubkey_t handle;
1763
unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
1764
int i, ret, size;
1765
1766
if ((ret = pgnutls_pubkey_init( &handle )))
1767
{
1768
pgnutls_perror( ret );
1769
return STATUS_INTERNAL_ERROR;
1770
}
1771
1772
hdr = (BLOBHEADER *)buf;
1773
pubkey = (DSSPUBKEY *)(hdr + 1);
1774
size = len_from_bitlen( pubkey->bitlen );
1775
data = (unsigned char *)(pubkey + 1);
1776
1777
p.data = p_data;
1778
p.size = size;
1779
for (i = 0; i < p.size; i++) p.data[i] = data[p.size - i - 1];
1780
data += p.size;
1781
1782
q.data = q_data;
1783
q.size = sizeof(q_data);
1784
for (i = 0; i < q.size; i++) q.data[i] = data[q.size - i - 1];
1785
data += q.size;
1786
1787
g.data = g_data;
1788
g.size = size;
1789
for (i = 0; i < g.size; i++) g.data[i] = data[g.size - i - 1];
1790
data += g.size;
1791
1792
y.data = y_data;
1793
y.size = sizeof(y_data);
1794
for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
1795
1796
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
1797
{
1798
pgnutls_perror( ret );
1799
pgnutls_pubkey_deinit( handle );
1800
return STATUS_INTERNAL_ERROR;
1801
}
1802
1803
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
1804
key_data(key)->a.pubkey = handle;
1805
return STATUS_SUCCESS;
1806
}
1807
1808
static NTSTATUS key_export_dh_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1809
{
1810
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1811
ULONG size = len_from_bitlen( key->u.a.bitlen );
1812
gnutls_dh_params_t params;
1813
gnutls_datum_t p, g, y;
1814
UCHAR *dst;
1815
int ret = GNUTLS_E_INVALID_REQUEST;
1816
1817
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1818
{
1819
pgnutls_perror( ret );
1820
return STATUS_INTERNAL_ERROR;
1821
}
1822
1823
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key)->a.pubkey, params, &y, 0 )))
1824
{
1825
pgnutls_perror( ret );
1826
pgnutls_dh_params_deinit( params );
1827
return STATUS_INTERNAL_ERROR;
1828
}
1829
1830
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1831
{
1832
pgnutls_perror( ret );
1833
free( y.data );
1834
pgnutls_dh_params_deinit( params );
1835
return STATUS_INTERNAL_ERROR;
1836
}
1837
1838
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) + EXPORT_SIZE(y, size, 1);
1839
if (len >= *ret_len && buf)
1840
{
1841
dst = (UCHAR *)(dh_blob + 1);
1842
dst += export_gnutls_datum( dst, size, &p, 1 );
1843
dst += export_gnutls_datum( dst, size, &g, 1 );
1844
dst += export_gnutls_datum( dst, size, &y, 1 );
1845
1846
dh_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
1847
dh_blob->cbKey = size;
1848
}
1849
1850
free( p.data ); free( g.data ); free( y.data );
1851
return STATUS_SUCCESS;
1852
}
1853
1854
static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1855
{
1856
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
1857
gnutls_datum_t p, g, y, x;
1858
gnutls_dh_params_t params;
1859
ULONG size = len_from_bitlen( key->u.a.bitlen );
1860
UCHAR *dst;
1861
int ret;
1862
1863
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
1864
1865
if ((ret = pgnutls_dh_params_init( &params )) < 0)
1866
{
1867
pgnutls_perror( ret );
1868
return STATUS_INTERNAL_ERROR;
1869
}
1870
1871
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 )))
1872
{
1873
pgnutls_perror( ret );
1874
pgnutls_dh_params_deinit( params );
1875
return STATUS_INTERNAL_ERROR;
1876
}
1877
1878
if ((ret = pgnutls_dh_params_export_raw( params, &p, &g, NULL )) < 0)
1879
{
1880
pgnutls_perror( ret );
1881
free( y.data ); free( x.data );
1882
pgnutls_dh_params_deinit( params );
1883
return STATUS_INTERNAL_ERROR;
1884
}
1885
1886
*ret_len = sizeof(*dh_blob) + EXPORT_SIZE(p, size, 1) + EXPORT_SIZE(g, size, 1) +
1887
EXPORT_SIZE(y, size, 1) + EXPORT_SIZE(x, size, 1);
1888
if (len >= *ret_len && buf)
1889
{
1890
dst = (UCHAR *)(dh_blob + 1);
1891
dst += export_gnutls_datum( dst, size, &p, 1 );
1892
dst += export_gnutls_datum( dst, size, &g, 1 );
1893
dst += export_gnutls_datum( dst, size, &y, 1 );
1894
dst += export_gnutls_datum( dst, size, &x, 1 );
1895
1896
dh_blob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
1897
dh_blob->cbKey = size;
1898
}
1899
1900
free( p.data ); free( g.data ); free( y.data ); free( x.data );
1901
pgnutls_dh_params_deinit( params );
1902
return STATUS_SUCCESS;
1903
}
1904
1905
static NTSTATUS key_export_dh_params( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
1906
{
1907
BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)buf;
1908
unsigned int size = sizeof(*hdr) + len_from_bitlen( key->u.a.bitlen ) * 2;
1909
gnutls_datum_t p, g;
1910
NTSTATUS status = STATUS_SUCCESS;
1911
UCHAR *dst;
1912
int ret;
1913
1914
if (!key_data(key)->a.dh_params) return STATUS_INVALID_PARAMETER;
1915
1916
if ((ret = pgnutls_dh_params_export_raw( key_data(key)->a.dh_params, &p, &g, NULL )))
1917
{
1918
pgnutls_perror( ret );
1919
return STATUS_INTERNAL_ERROR;
1920
}
1921
1922
*ret_len = size;
1923
if (len < size) status = STATUS_BUFFER_TOO_SMALL;
1924
else if (buf)
1925
{
1926
hdr->cbLength = size;
1927
hdr->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
1928
hdr->cbKeyLength = len_from_bitlen( key->u.a.bitlen );
1929
1930
dst = (UCHAR *)(hdr + 1);
1931
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &p, 1 );
1932
dst += export_gnutls_datum( dst, hdr->cbKeyLength, &g, 1 );
1933
}
1934
1935
free( p.data ); free( g.data );
1936
return status;
1937
}
1938
1939
static NTSTATUS key_asymmetric_export( void *args )
1940
{
1941
const struct key_asymmetric_export_params *params = args;
1942
struct key *key = params->key;
1943
unsigned flags = params->flags;
1944
1945
if (!(key->u.a.flags & KEY_FLAG_FINALIZED)) return STATUS_INVALID_HANDLE;
1946
1947
switch (key->alg_id)
1948
{
1949
case ALG_ID_ECDH:
1950
case ALG_ID_ECDH_P256:
1951
case ALG_ID_ECDH_P384:
1952
case ALG_ID_ECDH_P521:
1953
case ALG_ID_ECDSA:
1954
case ALG_ID_ECDSA_P256:
1955
case ALG_ID_ECDSA_P384:
1956
case ALG_ID_ECDSA_P521:
1957
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1958
return key_export_ecc_public( key, params->buf, params->len, params->ret_len );
1959
return key_export_ecc( key, params->buf, params->len, params->ret_len );
1960
1961
case ALG_ID_RSA:
1962
case ALG_ID_RSA_SIGN:
1963
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1964
return key_export_rsa_public( key, params->buf, params->len, params->ret_len );
1965
return key_export_rsa( key, flags, params->buf, params->len, params->ret_len );
1966
1967
case ALG_ID_DSA:
1968
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1969
{
1970
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1971
return key_export_dsa_capi_public( key, params->buf, params->len, params->ret_len );
1972
return key_export_dsa_public( key, params->buf, params->len, params->ret_len );
1973
}
1974
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
1975
return key_export_dsa_capi( key, params->buf, params->len, params->ret_len );
1976
return STATUS_NOT_IMPLEMENTED;
1977
1978
case ALG_ID_DH:
1979
if (flags & KEY_EXPORT_FLAG_DH_PARAMETERS)
1980
return key_export_dh_params( key, params->buf, params->len, params->ret_len );
1981
if (flags & KEY_EXPORT_FLAG_PUBLIC)
1982
return key_export_dh_public( key, params->buf, params->len, params->ret_len );
1983
return key_export_dh( key, params->buf, params->len, params->ret_len );
1984
1985
default:
1986
FIXME( "algorithm %u not yet supported\n", key->alg_id );
1987
return STATUS_NOT_IMPLEMENTED;
1988
}
1989
}
1990
1991
static NTSTATUS key_import_dh_public( struct key *key, UCHAR *buf, ULONG len )
1992
{
1993
BCRYPT_DH_KEY_BLOB *dh_blob;
1994
gnutls_dh_params_t params;
1995
gnutls_datum_t p, g, y;
1996
gnutls_pubkey_t handle;
1997
int ret;
1998
1999
if ((ret = pgnutls_pubkey_init( &handle )))
2000
{
2001
pgnutls_perror( ret );
2002
return STATUS_INTERNAL_ERROR;
2003
}
2004
2005
if ((ret = pgnutls_dh_params_init( &params )) < 0)
2006
{
2007
pgnutls_perror( ret );
2008
pgnutls_pubkey_deinit( handle );
2009
return STATUS_INTERNAL_ERROR;
2010
}
2011
2012
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
2013
p.data = buf + sizeof(*dh_blob);
2014
p.size = dh_blob->cbKey;
2015
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
2016
g.size = dh_blob->cbKey;
2017
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
2018
y.size = dh_blob->cbKey;
2019
2020
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
2021
{
2022
pgnutls_perror( ret );
2023
pgnutls_dh_params_deinit( params );
2024
pgnutls_pubkey_deinit( handle );
2025
return STATUS_INTERNAL_ERROR;
2026
}
2027
2028
if ((ret = pgnutls_pubkey_import_dh_raw( handle, params, &y )))
2029
{
2030
pgnutls_perror( ret );
2031
pgnutls_dh_params_deinit( params );
2032
pgnutls_pubkey_deinit( handle );
2033
return STATUS_INTERNAL_ERROR;
2034
}
2035
2036
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2037
key_data(key)->a.pubkey = handle;
2038
2039
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2040
key_data(key)->a.dh_params = params;
2041
return STATUS_SUCCESS;
2042
}
2043
2044
static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len )
2045
{
2046
BCRYPT_DH_KEY_BLOB *dh_blob;
2047
gnutls_dh_params_t params;
2048
gnutls_datum_t p, g, y, x;
2049
gnutls_privkey_t handle;
2050
int ret;
2051
2052
if ((ret = pgnutls_privkey_init( &handle )))
2053
{
2054
pgnutls_perror( ret );
2055
return STATUS_INTERNAL_ERROR;
2056
}
2057
2058
if ((ret = pgnutls_dh_params_init( &params )) < 0)
2059
{
2060
pgnutls_perror( ret );
2061
pgnutls_privkey_deinit( handle );
2062
return STATUS_INTERNAL_ERROR;
2063
}
2064
2065
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
2066
p.data = buf + sizeof(*dh_blob);
2067
p.size = dh_blob->cbKey;
2068
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
2069
g.size = dh_blob->cbKey;
2070
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
2071
y.size = dh_blob->cbKey;
2072
x.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 3;
2073
x.size = dh_blob->cbKey;
2074
2075
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
2076
{
2077
pgnutls_perror( ret );
2078
pgnutls_dh_params_deinit( params );
2079
pgnutls_privkey_deinit( handle );
2080
return STATUS_INTERNAL_ERROR;
2081
}
2082
2083
if ((ret = pgnutls_privkey_import_dh_raw( handle, params, &y, &x )))
2084
{
2085
pgnutls_perror( ret );
2086
pgnutls_dh_params_deinit( params );
2087
pgnutls_privkey_deinit( handle );
2088
return STATUS_INTERNAL_ERROR;
2089
}
2090
2091
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2092
key_data(key)->a.privkey = handle;
2093
2094
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2095
key_data(key)->a.dh_params = params;
2096
return STATUS_SUCCESS;
2097
}
2098
2099
static NTSTATUS key_import_dh_params( struct key *key, UCHAR *buf, ULONG len )
2100
{
2101
BCRYPT_DH_PARAMETER_HEADER *dh_header = (BCRYPT_DH_PARAMETER_HEADER *)buf;
2102
gnutls_dh_params_t params;
2103
gnutls_datum_t p, g;
2104
int ret;
2105
2106
if ((ret = pgnutls_dh_params_init( &params )))
2107
{
2108
pgnutls_perror( ret );
2109
return STATUS_INTERNAL_ERROR;
2110
}
2111
2112
p.data = (unsigned char *)(dh_header + 1);
2113
p.size = dh_header->cbKeyLength;
2114
g.data = p.data + dh_header->cbKeyLength;
2115
g.size = dh_header->cbKeyLength;
2116
2117
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )))
2118
{
2119
pgnutls_perror( ret );
2120
pgnutls_dh_params_deinit( params );
2121
return STATUS_INTERNAL_ERROR;
2122
}
2123
2124
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2125
key_data(key)->a.dh_params = params;
2126
return STATUS_SUCCESS;
2127
}
2128
2129
static NTSTATUS key_asymmetric_import( void *args )
2130
{
2131
const struct key_asymmetric_import_params *params = args;
2132
struct key *key = params->key;
2133
unsigned flags = params->flags;
2134
gnutls_pubkey_t pubkey;
2135
NTSTATUS ret;
2136
2137
switch (key->alg_id)
2138
{
2139
case ALG_ID_ECDH:
2140
case ALG_ID_ECDH_P256:
2141
case ALG_ID_ECDH_P384:
2142
case ALG_ID_ECDH_P521:
2143
case ALG_ID_ECDSA:
2144
case ALG_ID_ECDSA_P256:
2145
case ALG_ID_ECDSA_P384:
2146
case ALG_ID_ECDSA_P521:
2147
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2148
return key_import_ecc_public( key, params->buf, params->len );
2149
ret = key_import_ecc( key, params->buf, params->len );
2150
break;
2151
2152
case ALG_ID_RSA:
2153
case ALG_ID_RSA_SIGN:
2154
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2155
return key_import_rsa_public( key, params->buf, params->len );
2156
ret = key_import_rsa( key, params->buf, params->len );
2157
break;
2158
2159
case ALG_ID_DSA:
2160
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2161
{
2162
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2163
return key_import_dsa_capi_public( key, params->buf, params->len );
2164
return key_import_dsa_public( key, params->buf, params->len );
2165
}
2166
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
2167
{
2168
ret = key_import_dsa_capi( key, params->buf, params->len );
2169
break;
2170
}
2171
FIXME( "DSA private key not supported\n" );
2172
return STATUS_NOT_IMPLEMENTED;
2173
2174
case ALG_ID_DH:
2175
if (flags & KEY_IMPORT_FLAG_DH_PARAMETERS)
2176
return key_import_dh_params( key, params->buf, params->len );
2177
if (flags & KEY_IMPORT_FLAG_PUBLIC)
2178
return key_import_dh_public( key, params->buf, params->len );
2179
ret = key_import_dh( key, params->buf, params->len );
2180
break;
2181
2182
default:
2183
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2184
return STATUS_NOT_IMPLEMENTED;
2185
}
2186
2187
if (ret) return ret;
2188
2189
if ((ret = pgnutls_pubkey_init( &pubkey )))
2190
{
2191
pgnutls_perror( ret );
2192
return STATUS_INTERNAL_ERROR;
2193
}
2194
2195
if (pgnutls_pubkey_import_privkey( pubkey, key_data(params->key)->a.privkey, 0, 0 ))
2196
{
2197
/* Imported private key may be legitimately missing public key, so ignore the failure here. */
2198
pgnutls_pubkey_deinit( pubkey );
2199
}
2200
else
2201
{
2202
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2203
key_data(key)->a.pubkey = pubkey;
2204
}
2205
return STATUS_SUCCESS;
2206
}
2207
2208
static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len,
2209
gnutls_datum_t *gnutls_signature )
2210
{
2211
struct buffer buffer;
2212
DWORD r_len = signature_len / 2;
2213
DWORD s_len = r_len;
2214
BYTE *r = signature;
2215
BYTE *s = signature + r_len;
2216
2217
buffer_init( &buffer );
2218
buffer_append_asn1_r_s( &buffer, r, r_len, s, s_len );
2219
if (buffer.error)
2220
{
2221
buffer_free( &buffer );
2222
return STATUS_NO_MEMORY;
2223
}
2224
2225
gnutls_signature->data = buffer.buffer;
2226
gnutls_signature->size = buffer.pos;
2227
return STATUS_SUCCESS;
2228
}
2229
2230
static NTSTATUS prepare_gnutls_signature_rsa( struct key *key, UCHAR *signature, ULONG signature_len,
2231
gnutls_datum_t *gnutls_signature )
2232
{
2233
gnutls_signature->data = signature;
2234
gnutls_signature->size = signature_len;
2235
return STATUS_SUCCESS;
2236
}
2237
2238
static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULONG signature_len,
2239
gnutls_datum_t *gnutls_signature )
2240
{
2241
switch (key->alg_id)
2242
{
2243
case ALG_ID_ECDSA_P256:
2244
case ALG_ID_ECDSA_P384:
2245
case ALG_ID_ECDSA_P521:
2246
case ALG_ID_DSA:
2247
return prepare_gnutls_signature_dsa( key, signature, signature_len, gnutls_signature );
2248
2249
case ALG_ID_RSA:
2250
case ALG_ID_RSA_SIGN:
2251
return prepare_gnutls_signature_rsa( key, signature, signature_len, gnutls_signature );
2252
2253
default:
2254
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2255
return STATUS_NOT_IMPLEMENTED;
2256
}
2257
}
2258
2259
static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
2260
{
2261
if (!wcscmp( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
2262
if (!wcscmp( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
2263
if (!wcscmp( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
2264
if (!wcscmp( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
2265
if (!wcscmp( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
2266
if (!wcscmp( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
2267
return GNUTLS_DIG_UNKNOWN;
2268
}
2269
2270
static NTSTATUS pubkey_set_rsa_pss_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2271
{
2272
gnutls_x509_spki_t spki;
2273
int ret;
2274
2275
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2276
{
2277
pgnutls_perror( ret );
2278
return STATUS_INTERNAL_ERROR;
2279
}
2280
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2281
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2282
pgnutls_x509_spki_deinit( spki );
2283
if (ret < 0)
2284
{
2285
pgnutls_perror( ret );
2286
return STATUS_INTERNAL_ERROR;
2287
}
2288
return STATUS_SUCCESS;
2289
}
2290
2291
static NTSTATUS key_asymmetric_verify( void *args )
2292
{
2293
#ifdef GNUTLS_VERIFY_ALLOW_BROKEN
2294
unsigned int verify_flags = GNUTLS_VERIFY_ALLOW_BROKEN;
2295
#else
2296
unsigned int verify_flags = 0;
2297
#endif
2298
const struct key_asymmetric_verify_params *params = args;
2299
struct key *key = params->key;
2300
unsigned flags = params->flags;
2301
gnutls_digest_algorithm_t hash_alg;
2302
gnutls_sign_algorithm_t sign_alg;
2303
gnutls_datum_t gnutls_hash, gnutls_signature;
2304
gnutls_pk_algorithm_t pk_alg;
2305
NTSTATUS status;
2306
int ret;
2307
2308
switch (key->alg_id)
2309
{
2310
case ALG_ID_ECDSA_P256:
2311
case ALG_ID_ECDSA_P384:
2312
case ALG_ID_ECDSA_P521:
2313
{
2314
if (flags) FIXME( "flags %#x not supported\n", flags );
2315
2316
/* only the hash size must match, not the actual hash function */
2317
switch (params->hash_len)
2318
{
2319
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2320
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2321
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2322
2323
default:
2324
FIXME( "hash size %u not yet supported\n", params->hash_len );
2325
return STATUS_INVALID_SIGNATURE;
2326
}
2327
pk_alg = GNUTLS_PK_ECC;
2328
break;
2329
}
2330
case ALG_ID_RSA:
2331
case ALG_ID_RSA_SIGN:
2332
{
2333
if (flags & BCRYPT_PAD_PKCS1)
2334
{
2335
BCRYPT_PKCS1_PADDING_INFO *info = params->padding;
2336
2337
if (!info) return STATUS_INVALID_PARAMETER;
2338
if (!info->pszAlgId)
2339
{
2340
hash_alg = GNUTLS_DIG_UNKNOWN;
2341
verify_flags |= GNUTLS_VERIFY_USE_TLS1_RSA;
2342
}
2343
else if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2344
{
2345
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2346
return STATUS_NOT_SUPPORTED;
2347
}
2348
pk_alg = GNUTLS_PK_RSA;
2349
}
2350
else if (flags & BCRYPT_PAD_PSS)
2351
{
2352
BCRYPT_PSS_PADDING_INFO *info = params->padding;
2353
2354
if (!info) return STATUS_INVALID_PARAMETER;
2355
if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
2356
if ((hash_alg = get_digest_from_id(info->pszAlgId)) == GNUTLS_DIG_UNKNOWN)
2357
{
2358
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
2359
return STATUS_NOT_SUPPORTED;
2360
}
2361
if ((status = pubkey_set_rsa_pss_params( key_data(key)->a.pubkey, hash_alg, info->cbSalt ))) return status;
2362
pk_alg = GNUTLS_PK_RSA_PSS;
2363
}
2364
else return STATUS_INVALID_PARAMETER;
2365
break;
2366
}
2367
case ALG_ID_DSA:
2368
{
2369
if (flags) FIXME( "flags %#x not supported\n", flags );
2370
if (params->hash_len != 20)
2371
{
2372
FIXME( "hash size %u not supported\n", params->hash_len );
2373
return STATUS_INVALID_PARAMETER;
2374
}
2375
hash_alg = GNUTLS_DIG_SHA1;
2376
pk_alg = GNUTLS_PK_DSA;
2377
break;
2378
}
2379
default:
2380
FIXME( "algorithm %u not yet supported\n", key->alg_id );
2381
return STATUS_NOT_IMPLEMENTED;
2382
}
2383
2384
if ((sign_alg = pgnutls_pk_to_sign( pk_alg, hash_alg )) == GNUTLS_SIGN_UNKNOWN)
2385
{
2386
FIXME("GnuTLS does not support algorithm %u with hash len %u\n", key->alg_id, params->hash_len );
2387
return STATUS_NOT_IMPLEMENTED;
2388
}
2389
2390
if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
2391
return status;
2392
2393
gnutls_hash.data = params->hash;
2394
gnutls_hash.size = params->hash_len;
2395
2396
ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, verify_flags, &gnutls_hash, &gnutls_signature );
2397
if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
2398
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
2399
}
2400
2401
static unsigned int get_signature_length( enum alg_id id )
2402
{
2403
switch (id)
2404
{
2405
case ALG_ID_ECDSA_P256: return 64;
2406
case ALG_ID_ECDSA_P384: return 96;
2407
case ALG_ID_ECDSA_P521: return 132;
2408
case ALG_ID_DSA: return 40;
2409
default:
2410
FIXME( "unhandled algorithm %u\n", id );
2411
return 0;
2412
}
2413
}
2414
2415
static NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature,
2416
UCHAR *output, ULONG output_len, ULONG *ret_len )
2417
{
2418
switch (type)
2419
{
2420
case ALG_ID_RSA:
2421
case ALG_ID_RSA_SIGN:
2422
{
2423
*ret_len = signature.size;
2424
if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
2425
if (output) memcpy( output, signature.data, signature.size );
2426
return STATUS_SUCCESS;
2427
}
2428
case ALG_ID_ECDSA_P256:
2429
case ALG_ID_ECDSA_P384:
2430
case ALG_ID_ECDSA_P521:
2431
case ALG_ID_DSA:
2432
{
2433
int err;
2434
unsigned int sig_len = get_signature_length( type );
2435
gnutls_datum_t r, s; /* format as r||s */
2436
2437
if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
2438
{
2439
pgnutls_perror( err );
2440
return STATUS_INTERNAL_ERROR;
2441
}
2442
2443
*ret_len = sig_len;
2444
if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
2445
2446
if (r.size > sig_len / 2 + 1 || s.size > sig_len / 2 + 1)
2447
{
2448
ERR( "we didn't get a correct signature\n" );
2449
return STATUS_INTERNAL_ERROR;
2450
}
2451
2452
if (output)
2453
{
2454
export_gnutls_datum( output, sig_len / 2, &r, 1 );
2455
export_gnutls_datum( output + sig_len / 2, sig_len / 2, &s, 1 );
2456
}
2457
2458
free( r.data ); free( s.data );
2459
return STATUS_SUCCESS;
2460
}
2461
default:
2462
return STATUS_INTERNAL_ERROR;
2463
}
2464
}
2465
2466
static NTSTATUS privkey_set_rsa_pss_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, unsigned int salt_size )
2467
{
2468
gnutls_x509_spki_t spki;
2469
int ret;
2470
2471
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2472
{
2473
pgnutls_perror( ret );
2474
return STATUS_INTERNAL_ERROR;
2475
}
2476
pgnutls_x509_spki_set_rsa_pss_params( spki, dig, salt_size );
2477
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2478
pgnutls_x509_spki_deinit( spki );
2479
if (ret < 0)
2480
{
2481
pgnutls_perror( ret );
2482
return STATUS_INTERNAL_ERROR;
2483
}
2484
return STATUS_SUCCESS;
2485
}
2486
2487
static NTSTATUS key_asymmetric_sign( void *args )
2488
{
2489
const struct key_asymmetric_sign_params *params = args;
2490
struct key *key = params->key;
2491
unsigned int flags = params->flags, gnutls_flags = 0;
2492
gnutls_datum_t hash, signature;
2493
gnutls_digest_algorithm_t hash_alg;
2494
NTSTATUS status;
2495
int ret;
2496
2497
if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384 || key->alg_id == ALG_ID_ECDSA_P521)
2498
{
2499
/* With ECDSA, we find the digest algorithm from the hash length, and verify it */
2500
switch (params->input_len)
2501
{
2502
case 20: hash_alg = GNUTLS_DIG_SHA1; break;
2503
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
2504
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
2505
case 64: hash_alg = GNUTLS_DIG_SHA512; break;
2506
2507
default:
2508
FIXME( "hash size %u not yet supported\n", params->input_len );
2509
return STATUS_INVALID_PARAMETER;
2510
}
2511
2512
if (flags == BCRYPT_PAD_PKCS1)
2513
{
2514
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2515
if (pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
2516
{
2517
WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
2518
return STATUS_INVALID_PARAMETER;
2519
}
2520
}
2521
}
2522
else if (key->alg_id == ALG_ID_DSA)
2523
{
2524
if (flags) FIXME( "flags %#x not supported\n", flags );
2525
if (params->input_len != 20)
2526
{
2527
FIXME( "hash size %u not supported\n", params->input_len );
2528
return STATUS_INVALID_PARAMETER;
2529
}
2530
hash_alg = GNUTLS_DIG_SHA1;
2531
}
2532
else if (flags == BCRYPT_PAD_PKCS1)
2533
{
2534
BCRYPT_PKCS1_PADDING_INFO *pad = params->padding;
2535
2536
if (!pad)
2537
{
2538
WARN( "padding info not found\n" );
2539
return STATUS_INVALID_PARAMETER;
2540
}
2541
if (!pad->pszAlgId) hash_alg = GNUTLS_DIG_UNKNOWN;
2542
else if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2543
{
2544
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2545
return STATUS_NOT_SUPPORTED;
2546
}
2547
}
2548
else if (flags == BCRYPT_PAD_PSS)
2549
{
2550
BCRYPT_PSS_PADDING_INFO *pad = params->padding;
2551
2552
if (!pad || !pad->pszAlgId)
2553
{
2554
WARN( "padding info not found\n" );
2555
return STATUS_INVALID_PARAMETER;
2556
}
2557
if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
2558
{
2559
FIXME( "BCRYPT_PAD_PSS not supported for key algorithm %u\n", key->alg_id );
2560
return STATUS_NOT_SUPPORTED;
2561
}
2562
if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2563
{
2564
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2565
return STATUS_NOT_SUPPORTED;
2566
}
2567
2568
if ((status = privkey_set_rsa_pss_params( key_data(key)->a.privkey, hash_alg, pad->cbSalt ))) return status;
2569
gnutls_flags = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS;
2570
}
2571
else if (!flags)
2572
{
2573
WARN( "invalid flags %#x\n", flags );
2574
return STATUS_INVALID_PARAMETER;
2575
}
2576
else
2577
{
2578
FIXME( "flags %#x not implemented\n", flags );
2579
return STATUS_NOT_IMPLEMENTED;
2580
}
2581
2582
if (!params->output)
2583
{
2584
*params->ret_len = len_from_bitlen( key->u.a.bitlen );
2585
return STATUS_SUCCESS;
2586
}
2587
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
2588
2589
hash.data = params->input;
2590
hash.size = params->input_len;
2591
2592
signature.data = NULL;
2593
signature.size = 0;
2594
2595
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, gnutls_flags, &hash, &signature )))
2596
{
2597
pgnutls_perror( ret );
2598
return STATUS_INTERNAL_ERROR;
2599
}
2600
2601
status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
2602
free( signature.data );
2603
return status;
2604
}
2605
2606
static NTSTATUS key_asymmetric_destroy( void *args )
2607
{
2608
struct key *key = args;
2609
2610
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
2611
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
2612
if (key_data(key)->a.dh_params) pgnutls_dh_params_deinit( key_data(key)->a.dh_params );
2613
return STATUS_SUCCESS;
2614
}
2615
2616
static NTSTATUS dup_privkey( struct key *key_orig, struct key *key_copy )
2617
{
2618
gnutls_privkey_t privkey;
2619
int ret;
2620
2621
if ((ret = pgnutls_privkey_init( &privkey )))
2622
{
2623
pgnutls_perror( ret );
2624
return STATUS_INTERNAL_ERROR;
2625
}
2626
2627
switch (key_orig->alg_id)
2628
{
2629
case ALG_ID_RSA:
2630
case ALG_ID_RSA_SIGN:
2631
{
2632
gnutls_datum_t m, e, d, p, q, u, e1, e2;
2633
2634
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
2635
break;
2636
ret = pgnutls_privkey_import_rsa_raw( privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
2637
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
2638
free( e1.data ); free( e2.data );
2639
break;
2640
}
2641
case ALG_ID_DSA:
2642
{
2643
gnutls_datum_t p, q, g, y, x;
2644
2645
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x ))) break;
2646
ret = pgnutls_privkey_import_dsa_raw( privkey, &p, &q, &g, &y, &x );
2647
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
2648
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2649
break;
2650
}
2651
case ALG_ID_ECDH:
2652
case ALG_ID_ECDH_P256:
2653
case ALG_ID_ECDH_P384:
2654
case ALG_ID_ECDH_P521:
2655
case ALG_ID_ECDSA:
2656
case ALG_ID_ECDSA_P256:
2657
case ALG_ID_ECDSA_P384:
2658
case ALG_ID_ECDSA_P521:
2659
{
2660
gnutls_ecc_curve_t curve;
2661
gnutls_datum_t x, y, k;
2662
2663
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k ))) break;
2664
ret = pgnutls_privkey_import_ecc_raw( privkey, curve, &x, &y, &k );
2665
free( x.data ); free( y.data ); free( k.data );
2666
break;
2667
}
2668
case ALG_ID_DH:
2669
{
2670
gnutls_dh_params_t params;
2671
gnutls_datum_t y, x;
2672
2673
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2674
if ((ret = pgnutls_privkey_export_dh_raw( key_data(key_orig)->a.privkey, params, &y, &x, 0 )) < 0)
2675
{
2676
pgnutls_dh_params_deinit( params );
2677
break;
2678
}
2679
ret = pgnutls_privkey_import_dh_raw( privkey, params, &y, &x );
2680
pgnutls_dh_params_deinit( params );
2681
free( x.data ); free( y.data );
2682
break;
2683
}
2684
default:
2685
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2686
pgnutls_privkey_deinit( privkey );
2687
return STATUS_INTERNAL_ERROR;
2688
}
2689
2690
if (ret < 0)
2691
{
2692
pgnutls_perror( ret );
2693
pgnutls_privkey_deinit( privkey );
2694
return STATUS_INTERNAL_ERROR;
2695
}
2696
2697
key_data(key_copy)->a.privkey = privkey;
2698
return STATUS_SUCCESS;
2699
}
2700
2701
static NTSTATUS dup_pubkey( struct key *key_orig, struct key *key_copy )
2702
{
2703
gnutls_pubkey_t pubkey;
2704
int ret;
2705
2706
if ((ret = pgnutls_pubkey_init( &pubkey )))
2707
{
2708
pgnutls_perror( ret );
2709
return STATUS_INTERNAL_ERROR;
2710
}
2711
2712
switch (key_orig->alg_id)
2713
{
2714
case ALG_ID_RSA:
2715
case ALG_ID_RSA_SIGN:
2716
{
2717
gnutls_datum_t m, e;
2718
2719
if ((ret = pgnutls_pubkey_export_rsa_raw( key_data(key_orig)->a.pubkey, &m, &e ))) break;
2720
ret = pgnutls_pubkey_import_rsa_raw( pubkey, &m, &e );
2721
free( m.data ); free( e.data );
2722
break;
2723
}
2724
case ALG_ID_DSA:
2725
{
2726
gnutls_datum_t p, q, g, y;
2727
2728
if ((ret = pgnutls_pubkey_export_dsa_raw( key_data(key_orig)->a.pubkey, &p, &q, &g, &y ))) break;
2729
ret = pgnutls_pubkey_import_dsa_raw( pubkey, &p, &q, &g, &y );
2730
free( p.data ); free( q.data ); free( g.data ); free( y.data );
2731
if (!ret) key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
2732
break;
2733
}
2734
case ALG_ID_ECDH:
2735
case ALG_ID_ECDH_P256:
2736
case ALG_ID_ECDH_P384:
2737
case ALG_ID_ECDH_P521:
2738
case ALG_ID_ECDSA:
2739
case ALG_ID_ECDSA_P256:
2740
case ALG_ID_ECDSA_P384:
2741
case ALG_ID_ECDSA_P521:
2742
{
2743
gnutls_ecc_curve_t curve;
2744
gnutls_datum_t x, y;
2745
2746
if ((ret = pgnutls_pubkey_export_ecc_raw( key_data(key_orig)->a.pubkey, &curve, &x, &y ))) break;
2747
ret = pgnutls_pubkey_import_ecc_raw( pubkey, curve, &x, &y );
2748
free( x.data ); free( y.data );
2749
break;
2750
}
2751
case ALG_ID_DH:
2752
{
2753
gnutls_dh_params_t params;
2754
gnutls_datum_t y;
2755
2756
if ((ret = pgnutls_dh_params_init( &params )) < 0) break;
2757
if ((ret = pgnutls_pubkey_export_dh_raw( key_data(key_orig)->a.pubkey, params, &y, 0 )) < 0)
2758
{
2759
pgnutls_dh_params_deinit( params );
2760
break;
2761
}
2762
ret = pgnutls_pubkey_import_dh_raw( pubkey, params, &y );
2763
pgnutls_dh_params_deinit( params );
2764
free( y.data );
2765
break;
2766
}
2767
default:
2768
ERR( "unhandled algorithm %u\n", key_orig->alg_id );
2769
pgnutls_pubkey_deinit( pubkey );
2770
return STATUS_INTERNAL_ERROR;
2771
}
2772
2773
if (ret < 0)
2774
{
2775
pgnutls_perror( ret );
2776
pgnutls_pubkey_deinit( pubkey );
2777
return STATUS_INTERNAL_ERROR;
2778
}
2779
2780
key_data(key_copy)->a.pubkey = pubkey;
2781
return STATUS_SUCCESS;
2782
}
2783
2784
static NTSTATUS key_asymmetric_duplicate( void *args )
2785
{
2786
const struct key_asymmetric_duplicate_params *params = args;
2787
NTSTATUS status;
2788
2789
if (key_data(params->key_orig)->a.privkey && (status = dup_privkey( params->key_orig, params->key_copy )))
2790
return status;
2791
2792
if (key_data(params->key_orig)->a.pubkey && (status = dup_pubkey( params->key_orig, params->key_copy )))
2793
return status;
2794
2795
return STATUS_SUCCESS;
2796
}
2797
2798
static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2799
{
2800
gnutls_x509_spki_t spki;
2801
int ret;
2802
2803
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2804
{
2805
pgnutls_perror( ret );
2806
return STATUS_INTERNAL_ERROR;
2807
}
2808
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2809
ret = pgnutls_privkey_set_spki( key, spki, 0 );
2810
pgnutls_x509_spki_deinit( spki );
2811
if (ret < 0)
2812
{
2813
pgnutls_perror( ret );
2814
return STATUS_INTERNAL_ERROR;
2815
}
2816
return STATUS_SUCCESS;
2817
}
2818
2819
static NTSTATUS key_asymmetric_decrypt( void *args )
2820
{
2821
const struct key_asymmetric_decrypt_params *params = args;
2822
gnutls_datum_t e, d = { 0 };
2823
NTSTATUS status = STATUS_SUCCESS;
2824
int ret;
2825
2826
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2827
{
2828
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2829
gnutls_digest_algorithm_t dig;
2830
gnutls_datum_t label;
2831
2832
if (!pad || !pad->pszAlgId)
2833
{
2834
WARN( "padding info not found\n" );
2835
return STATUS_INVALID_PARAMETER;
2836
}
2837
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2838
{
2839
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2840
return STATUS_NOT_SUPPORTED;
2841
}
2842
2843
label.data = pad->pbLabel;
2844
label.size = pad->cbLabel;
2845
if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
2846
}
2847
2848
e.data = params->input;
2849
e.size = params->input_len;
2850
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
2851
{
2852
pgnutls_perror( ret );
2853
return STATUS_INTERNAL_ERROR;
2854
}
2855
2856
*params->ret_len = d.size;
2857
if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
2858
else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
2859
2860
free( d.data );
2861
return status;
2862
}
2863
2864
static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
2865
{
2866
gnutls_x509_spki_t spki;
2867
int ret;
2868
2869
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
2870
{
2871
pgnutls_perror( ret );
2872
return STATUS_INTERNAL_ERROR;
2873
}
2874
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
2875
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
2876
pgnutls_x509_spki_deinit( spki );
2877
if (ret < 0)
2878
{
2879
pgnutls_perror( ret );
2880
return STATUS_INTERNAL_ERROR;
2881
}
2882
return STATUS_SUCCESS;
2883
}
2884
2885
static NTSTATUS key_asymmetric_encrypt( void *args )
2886
{
2887
const struct key_asymmetric_encrypt_params *params = args;
2888
gnutls_datum_t d, e = { 0 };
2889
NTSTATUS status = STATUS_SUCCESS;
2890
int ret;
2891
2892
if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
2893
2894
if (params->key->alg_id == ALG_ID_RSA
2895
&& (!params->output || len_from_bitlen( params->key->u.a.bitlen ) > params->output_len))
2896
{
2897
*params->ret_len = len_from_bitlen( params->key->u.a.bitlen );
2898
return !params->output ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
2899
}
2900
2901
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
2902
{
2903
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
2904
gnutls_digest_algorithm_t dig;
2905
gnutls_datum_t label;
2906
2907
if (!pad || !pad->pszAlgId || !pad->pbLabel)
2908
{
2909
WARN( "padding info not found\n" );
2910
return STATUS_INVALID_PARAMETER;
2911
}
2912
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
2913
{
2914
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
2915
return STATUS_NOT_SUPPORTED;
2916
}
2917
2918
label.data = pad->pbLabel;
2919
label.size = pad->cbLabel;
2920
if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
2921
}
2922
2923
d.data = params->input;
2924
d.size = params->input_len;
2925
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
2926
{
2927
pgnutls_perror( ret );
2928
return STATUS_INTERNAL_ERROR;
2929
}
2930
2931
*params->ret_len = e.size;
2932
if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len );
2933
else if (params->output_len == 0) status = STATUS_SUCCESS;
2934
else status = STATUS_BUFFER_TOO_SMALL;
2935
2936
free( e.data );
2937
return status;
2938
}
2939
2940
static NTSTATUS key_asymmetric_derive_key( void *args )
2941
{
2942
const struct key_asymmetric_derive_key_params *params = args;
2943
gnutls_datum_t s;
2944
NTSTATUS status = STATUS_SUCCESS;
2945
int ret;
2946
2947
if ((ret = pgnutls_privkey_derive_secret( key_data(params->privkey)->a.privkey,
2948
key_data(params->pubkey)->a.pubkey, NULL, &s, 0 )))
2949
{
2950
pgnutls_perror( ret );
2951
return STATUS_INTERNAL_ERROR;
2952
}
2953
2954
*params->ret_len = EXPORT_SIZE( s, len_from_bitlen( params->privkey->u.a.bitlen ), 1 );
2955
if (params->output)
2956
{
2957
if (params->output_len < *params->ret_len) status = STATUS_BUFFER_TOO_SMALL;
2958
else export_gnutls_datum( params->output, *params->ret_len, &s, 1 );
2959
}
2960
2961
free( s.data );
2962
return status;
2963
}
2964
2965
const unixlib_entry_t __wine_unix_call_funcs[] =
2966
{
2967
gnutls_process_attach,
2968
gnutls_process_detach,
2969
key_symmetric_vector_reset,
2970
key_symmetric_set_auth_data,
2971
key_symmetric_encrypt,
2972
key_symmetric_decrypt,
2973
key_symmetric_get_tag,
2974
key_symmetric_destroy,
2975
key_asymmetric_generate,
2976
key_asymmetric_decrypt,
2977
key_asymmetric_encrypt,
2978
key_asymmetric_duplicate,
2979
key_asymmetric_sign,
2980
key_asymmetric_verify,
2981
key_asymmetric_destroy,
2982
key_asymmetric_export,
2983
key_asymmetric_import,
2984
key_asymmetric_derive_key,
2985
};
2986
2987
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
2988
2989
#ifdef _WIN64
2990
2991
typedef ULONG PTR32;
2992
2993
struct key_symmetric32
2994
{
2995
enum chain_mode mode;
2996
ULONG block_size;
2997
PTR32 vector;
2998
ULONG vector_len;
2999
PTR32 secret;
3000
ULONG secret_len;
3001
ULONG __cs[6];
3002
};
3003
3004
struct key_asymmetric32
3005
{
3006
ULONG bitlen; /* ignored for ECC keys */
3007
enum ecc_curve_id curve_id;
3008
ULONG flags;
3009
DSSSEED dss_seed;
3010
};
3011
3012
struct key32
3013
{
3014
struct object hdr;
3015
enum alg_id alg_id;
3016
UINT64 private[PRIVATE_DATA_SIZE]; /* private data for backend */
3017
union
3018
{
3019
struct key_symmetric32 s;
3020
struct key_asymmetric32 a;
3021
} u;
3022
};
3023
3024
union padding
3025
{
3026
BCRYPT_OAEP_PADDING_INFO oaep;
3027
BCRYPT_PKCS1_PADDING_INFO pkcs1;
3028
BCRYPT_PSS_PADDING_INFO pss;
3029
};
3030
3031
union padding32
3032
{
3033
struct
3034
{
3035
PTR32 pszAlgId;
3036
PTR32 pbLabel;
3037
ULONG cbLabel;
3038
} oaep;
3039
struct
3040
{
3041
PTR32 pszAlgId;
3042
} pkcs1;
3043
struct
3044
{
3045
PTR32 pszAlgId;
3046
ULONG cbSalt;
3047
} pss;
3048
};
3049
3050
static union padding *get_padding( union padding32 *padding32, union padding *padding, ULONG flags)
3051
{
3052
if (!padding32) return NULL;
3053
3054
switch (flags)
3055
{
3056
case BCRYPT_PAD_OAEP:
3057
padding->oaep.pszAlgId = ULongToPtr( padding32->oaep.pszAlgId );
3058
padding->oaep.pbLabel = ULongToPtr( padding32->oaep.pbLabel );
3059
padding->oaep.cbLabel = padding32->oaep.cbLabel;
3060
return padding;
3061
3062
case BCRYPT_PAD_PKCS1:
3063
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
3064
return padding;
3065
3066
case BCRYPT_PAD_PSS:
3067
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
3068
padding->pss.cbSalt = padding32->pss.cbSalt;
3069
return padding;
3070
3071
default:
3072
break;
3073
}
3074
return NULL;
3075
}
3076
3077
static struct key *get_symmetric_key( struct key32 *key32, struct key *key )
3078
{
3079
key->hdr = key32->hdr;
3080
key->alg_id = key32->alg_id;
3081
memcpy( key->private, key32->private, sizeof(key->private) );
3082
key->u.s.mode = key32->u.s.mode;
3083
key->u.s.block_size = key32->u.s.block_size;
3084
key->u.s.vector = ULongToPtr(key32->u.s.vector);
3085
key->u.s.vector_len = key32->u.s.vector_len;
3086
key->u.s.secret = ULongToPtr(key32->u.s.secret);
3087
key->u.s.secret_len = key32->u.s.secret_len;
3088
return key;
3089
}
3090
3091
static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
3092
{
3093
key->hdr = key32->hdr;
3094
key->alg_id = key32->alg_id;
3095
memcpy( key->private, key32->private, sizeof(key->private) );
3096
key->u.a.bitlen = key32->u.a.bitlen;
3097
key->u.a.curve_id = key32->u.a.curve_id;
3098
key->u.a.flags = key32->u.a.flags;
3099
key->u.a.dss_seed = key32->u.a.dss_seed;
3100
return key;
3101
}
3102
3103
static void put_symmetric_key32( struct key *key, struct key32 *key32 )
3104
{
3105
memcpy( key32->private, key->private, sizeof(key32->private) );
3106
}
3107
3108
static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
3109
{
3110
memcpy( key32->private, key->private, sizeof(key32->private) );
3111
key32->u.a.curve_id = key->u.a.curve_id;
3112
key32->u.a.flags = key->u.a.flags;
3113
key32->u.a.dss_seed = key->u.a.dss_seed;
3114
}
3115
3116
static NTSTATUS wow64_key_symmetric_vector_reset( void *args )
3117
{
3118
NTSTATUS ret;
3119
struct key key;
3120
struct key32 *key32 = args;
3121
3122
ret = key_symmetric_vector_reset( get_symmetric_key( key32, &key ));
3123
put_symmetric_key32( &key, key32 );
3124
return ret;
3125
}
3126
3127
static NTSTATUS wow64_key_symmetric_set_auth_data( void *args )
3128
{
3129
struct
3130
{
3131
PTR32 key;
3132
PTR32 auth_data;
3133
ULONG len;
3134
} const *params32 = args;
3135
3136
NTSTATUS ret;
3137
struct key key;
3138
struct key32 *key32 = ULongToPtr( params32->key );
3139
struct key_symmetric_set_auth_data_params params =
3140
{
3141
get_symmetric_key( key32, &key ),
3142
ULongToPtr(params32->auth_data),
3143
params32->len
3144
};
3145
3146
ret = key_symmetric_set_auth_data( &params );
3147
put_symmetric_key32( &key, key32 );
3148
return ret;
3149
}
3150
3151
static NTSTATUS wow64_key_symmetric_encrypt( void *args )
3152
{
3153
struct
3154
{
3155
PTR32 key;
3156
PTR32 input;
3157
ULONG input_len;
3158
PTR32 output;
3159
ULONG output_len;
3160
} const *params32 = args;
3161
3162
NTSTATUS ret;
3163
struct key key;
3164
struct key32 *key32 = ULongToPtr( params32->key );
3165
struct key_symmetric_encrypt_params params =
3166
{
3167
get_symmetric_key( key32, &key ),
3168
ULongToPtr(params32->input),
3169
params32->input_len,
3170
ULongToPtr(params32->output),
3171
params32->output_len
3172
};
3173
3174
ret = key_symmetric_encrypt( &params );
3175
put_symmetric_key32( &key, key32 );
3176
return ret;
3177
}
3178
3179
static NTSTATUS wow64_key_symmetric_decrypt( void *args )
3180
{
3181
struct
3182
{
3183
PTR32 key;
3184
PTR32 input;
3185
ULONG input_len;
3186
PTR32 output;
3187
ULONG output_len;
3188
} const *params32 = args;
3189
3190
NTSTATUS ret;
3191
struct key key;
3192
struct key32 *key32 = ULongToPtr( params32->key );
3193
struct key_symmetric_decrypt_params params =
3194
{
3195
get_symmetric_key( key32, &key ),
3196
ULongToPtr(params32->input),
3197
params32->input_len,
3198
ULongToPtr(params32->output),
3199
params32->output_len
3200
};
3201
3202
ret = key_symmetric_decrypt( &params );
3203
put_symmetric_key32( &key, key32 );
3204
return ret;
3205
}
3206
3207
static NTSTATUS wow64_key_symmetric_get_tag( void *args )
3208
{
3209
struct
3210
{
3211
PTR32 key;
3212
PTR32 tag;
3213
ULONG len;
3214
} const *params32 = args;
3215
3216
NTSTATUS ret;
3217
struct key key;
3218
struct key32 *key32 = ULongToPtr( params32->key );
3219
struct key_symmetric_get_tag_params params =
3220
{
3221
get_symmetric_key( key32, &key ),
3222
ULongToPtr(params32->tag),
3223
params32->len
3224
};
3225
3226
ret = key_symmetric_get_tag( &params );
3227
put_symmetric_key32( &key, key32 );
3228
return ret;
3229
}
3230
3231
static NTSTATUS wow64_key_symmetric_destroy( void *args )
3232
{
3233
struct key32 *key32 = args;
3234
struct key key;
3235
3236
return key_symmetric_destroy( get_symmetric_key( key32, &key ));
3237
}
3238
3239
static NTSTATUS wow64_key_asymmetric_generate( void *args )
3240
{
3241
struct key32 *key32 = args;
3242
struct key key;
3243
NTSTATUS ret;
3244
3245
ret = key_asymmetric_generate( get_asymmetric_key( key32, &key ));
3246
put_asymmetric_key32( &key, key32 );
3247
return ret;
3248
}
3249
3250
static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
3251
{
3252
struct
3253
{
3254
PTR32 key;
3255
PTR32 input;
3256
ULONG input_len;
3257
PTR32 padding;
3258
PTR32 output;
3259
ULONG output_len;
3260
PTR32 ret_len;
3261
ULONG flags;
3262
} const *params32 = args;
3263
3264
NTSTATUS ret;
3265
struct key key;
3266
union padding padding;
3267
struct key32 *key32 = ULongToPtr( params32->key );
3268
struct key_asymmetric_decrypt_params params =
3269
{
3270
get_asymmetric_key( key32, &key ),
3271
ULongToPtr(params32->input),
3272
params32->input_len,
3273
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3274
ULongToPtr(params32->output),
3275
params32->output_len,
3276
ULongToPtr(params32->ret_len),
3277
params32->flags
3278
};
3279
3280
ret = key_asymmetric_decrypt( &params );
3281
put_asymmetric_key32( &key, key32 );
3282
return ret;
3283
}
3284
3285
static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
3286
{
3287
struct
3288
{
3289
PTR32 key;
3290
PTR32 input;
3291
ULONG input_len;
3292
PTR32 padding;
3293
PTR32 output;
3294
ULONG output_len;
3295
PTR32 ret_len;
3296
ULONG flags;
3297
} const *params32 = args;
3298
3299
NTSTATUS ret;
3300
struct key key;
3301
union padding padding;
3302
struct key32 *key32 = ULongToPtr( params32->key );
3303
struct key_asymmetric_encrypt_params params =
3304
{
3305
get_asymmetric_key( key32, &key ),
3306
ULongToPtr(params32->input),
3307
params32->input_len,
3308
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
3309
ULongToPtr(params32->output),
3310
params32->output_len,
3311
ULongToPtr(params32->ret_len),
3312
params32->flags
3313
};
3314
3315
ret = key_asymmetric_encrypt( &params );
3316
put_asymmetric_key32( &key, key32 );
3317
return ret;
3318
}
3319
3320
static NTSTATUS wow64_key_asymmetric_duplicate( void *args )
3321
{
3322
struct
3323
{
3324
PTR32 key_orig;
3325
PTR32 key_copy;
3326
} const *params32 = args;
3327
3328
NTSTATUS ret;
3329
struct key key_orig, key_copy;
3330
struct key32 *key_orig32 = ULongToPtr( params32->key_orig );
3331
struct key32 *key_copy32 = ULongToPtr( params32->key_copy );
3332
struct key_asymmetric_duplicate_params params =
3333
{
3334
get_asymmetric_key( key_orig32, &key_orig ),
3335
get_asymmetric_key( key_copy32, &key_copy )
3336
};
3337
3338
ret = key_asymmetric_duplicate( &params );
3339
put_asymmetric_key32( &key_copy, key_copy32 );
3340
return ret;
3341
}
3342
3343
static NTSTATUS wow64_key_asymmetric_sign( void *args )
3344
{
3345
struct
3346
{
3347
PTR32 key;
3348
PTR32 padding;
3349
PTR32 input;
3350
ULONG input_len;
3351
PTR32 output;
3352
ULONG output_len;
3353
PTR32 ret_len;
3354
ULONG flags;
3355
} const *params32 = args;
3356
3357
NTSTATUS ret;
3358
struct key key;
3359
union padding padding;
3360
struct key32 *key32 = ULongToPtr( params32->key );
3361
struct key_asymmetric_sign_params params =
3362
{
3363
get_asymmetric_key( key32, &key ),
3364
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3365
ULongToPtr(params32->input),
3366
params32->input_len,
3367
ULongToPtr(params32->output),
3368
params32->output_len,
3369
ULongToPtr(params32->ret_len),
3370
params32->flags
3371
};
3372
3373
ret = key_asymmetric_sign( &params );
3374
put_asymmetric_key32( &key, key32 );
3375
return ret;
3376
}
3377
3378
static NTSTATUS wow64_key_asymmetric_verify( void *args )
3379
{
3380
struct
3381
{
3382
PTR32 key;
3383
PTR32 padding;
3384
PTR32 hash;
3385
ULONG hash_len;
3386
PTR32 signature;
3387
ULONG signature_len;
3388
ULONG flags;
3389
} const *params32 = args;
3390
3391
NTSTATUS ret;
3392
struct key key;
3393
union padding padding;
3394
struct key32 *key32 = ULongToPtr( params32->key );
3395
struct key_asymmetric_verify_params params =
3396
{
3397
get_asymmetric_key( key32, &key ),
3398
get_padding(ULongToPtr( params32->padding ), &padding, params32->flags),
3399
ULongToPtr(params32->hash),
3400
params32->hash_len,
3401
ULongToPtr(params32->signature),
3402
params32->signature_len,
3403
params32->flags
3404
};
3405
3406
ret = key_asymmetric_verify( &params );
3407
put_asymmetric_key32( &key, key32 );
3408
return ret;
3409
}
3410
3411
static NTSTATUS wow64_key_asymmetric_destroy( void *args )
3412
{
3413
struct key32 *key32 = args;
3414
struct key key;
3415
3416
return key_asymmetric_destroy( get_asymmetric_key( key32, &key ));
3417
}
3418
3419
static NTSTATUS wow64_key_asymmetric_export( void *args )
3420
{
3421
struct
3422
{
3423
PTR32 key;
3424
ULONG flags;
3425
PTR32 buf;
3426
ULONG len;
3427
PTR32 ret_len;
3428
} const *params32 = args;
3429
3430
NTSTATUS ret;
3431
struct key key;
3432
struct key32 *key32 = ULongToPtr( params32->key );
3433
struct key_asymmetric_export_params params =
3434
{
3435
get_asymmetric_key( key32, &key ),
3436
params32->flags,
3437
ULongToPtr(params32->buf),
3438
params32->len,
3439
ULongToPtr(params32->ret_len),
3440
};
3441
3442
ret = key_asymmetric_export( &params );
3443
put_asymmetric_key32( &key, key32 );
3444
return ret;
3445
}
3446
3447
static NTSTATUS wow64_key_asymmetric_import( void *args )
3448
{
3449
struct
3450
{
3451
PTR32 key;
3452
ULONG flags;
3453
PTR32 buf;
3454
ULONG len;
3455
} const *params32 = args;
3456
3457
NTSTATUS ret;
3458
struct key key;
3459
struct key32 *key32 = ULongToPtr( params32->key );
3460
struct key_asymmetric_import_params params =
3461
{
3462
get_asymmetric_key( key32, &key ),
3463
params32->flags,
3464
ULongToPtr(params32->buf),
3465
params32->len
3466
};
3467
3468
ret = key_asymmetric_import( &params );
3469
put_asymmetric_key32( &key, key32 );
3470
return ret;
3471
}
3472
3473
static NTSTATUS wow64_key_asymmetric_derive_key( void *args )
3474
{
3475
struct
3476
{
3477
PTR32 privkey;
3478
PTR32 pubkey;
3479
PTR32 output;
3480
ULONG output_len;
3481
PTR32 ret_len;
3482
} const *params32 = args;
3483
3484
NTSTATUS ret;
3485
struct key privkey, pubkey;
3486
struct key32 *privkey32 = ULongToPtr( params32->privkey );
3487
struct key32 *pubkey32 = ULongToPtr( params32->pubkey );
3488
struct key_asymmetric_derive_key_params params =
3489
{
3490
get_asymmetric_key( privkey32, &privkey ),
3491
get_asymmetric_key( pubkey32, &pubkey ),
3492
ULongToPtr(params32->output),
3493
params32->output_len,
3494
ULongToPtr(params32->ret_len),
3495
};
3496
3497
ret = key_asymmetric_derive_key( &params );
3498
put_asymmetric_key32( &privkey, privkey32 );
3499
put_asymmetric_key32( &pubkey, pubkey32 );
3500
return ret;
3501
}
3502
3503
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
3504
{
3505
gnutls_process_attach,
3506
gnutls_process_detach,
3507
wow64_key_symmetric_vector_reset,
3508
wow64_key_symmetric_set_auth_data,
3509
wow64_key_symmetric_encrypt,
3510
wow64_key_symmetric_decrypt,
3511
wow64_key_symmetric_get_tag,
3512
wow64_key_symmetric_destroy,
3513
wow64_key_asymmetric_generate,
3514
wow64_key_asymmetric_decrypt,
3515
wow64_key_asymmetric_encrypt,
3516
wow64_key_asymmetric_duplicate,
3517
wow64_key_asymmetric_sign,
3518
wow64_key_asymmetric_verify,
3519
wow64_key_asymmetric_destroy,
3520
wow64_key_asymmetric_export,
3521
wow64_key_asymmetric_import,
3522
wow64_key_asymmetric_derive_key,
3523
};
3524
3525
C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
3526
3527
#endif /* _WIN64 */
3528
3529
#endif /* HAVE_GNUTLS_CIPHER_INIT */
3530
3531