Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/libecc/src/wycheproof_tests/libecc_wycheproof.c
34889 views
1
/*
2
* Copyright (C) 2021 - This file is part of libecc project
3
*
4
* Authors:
5
* Ryad BENADJILA <[email protected]>
6
* Arnaud EBALARD <[email protected]>
7
*
8
* This software is licensed under a dual BSD and GPL v2 license.
9
* See LICENSE file at the root folder of the project.
10
*/
11
12
/*
13
* Source code for handling tests imported from the wycheproof project:
14
* https://github.com/google/wycheproof
15
*
16
* As this project primarily targets java cryptographic libraries, the
17
* json test files have been parsed to generate libecc friendly test cases.
18
*
19
* NOTE: we skip here all the tests related to ASN.1 format errors as libecc
20
* does not handle ASN.1 parsing at all. This explains the "skipped" tests from
21
* the wycheproof project.
22
*
23
*/
24
#include "libecc_wycheproof.h"
25
26
/* Parallelize self tests? */
27
#ifdef WITH_OPENMP_SELF_TESTS
28
/* No openmp without stdlib ... */
29
#ifndef WITH_STDLIB
30
#error "Sorry: no possible self tests parallelization (OpenMP) without stdlib! Please use WITH_STDLIB"
31
#endif
32
#include <omp.h>
33
#include <stdlib.h>
34
static omp_lock_t global_lock;
35
static volatile u8 global_lock_initialized = 0;
36
#define OPENMP_LOCK() do { \
37
if(!global_lock_initialized){ \
38
omp_init_lock(&global_lock); \
39
global_lock_initialized = 1; \
40
} \
41
omp_set_lock(&global_lock); \
42
} while(0)
43
#define OPENMP_EG(ret, err) do { \
44
if(ret){ \
45
ext_printf("OpenMP abort following error ... %s:%d\n", __FILE__, __LINE__); \
46
exit(-1); \
47
} \
48
} while(0)
49
#define OPENMP_MUST_HAVE(cnd, ret, err) do { \
50
ret = !!(cnd); \
51
ret = -((~ret) & 1); \
52
OPENMP_EG(ret, err); \
53
} while(0)
54
#define OPENMP_UNLOCK() do { \
55
omp_unset_lock(&global_lock); \
56
} while(0)
57
#else
58
#define OPENMP_LOCK()
59
#define OPENMP_UNLOCK()
60
#define OPENMP_EG(ret, err) do { \
61
EG(ret, err); \
62
} while(0)
63
#define OPENMP_MUST_HAVE(cnd, ret, err) do { \
64
MUST_HAVE(cnd, ret, err); \
65
} while(0)
66
#endif
67
68
#include "libecc_wycheproof_tests.h"
69
70
/* Check all ECDSA test vectors */
71
static unsigned int ecdsa_acceptable_invalid = 0;
72
static unsigned int ecdsa_acceptable_valid = 0;
73
static unsigned int ecdsa_all_performed = 0;
74
static int check_wycheproof_ecdsa(void)
75
{
76
#if defined(WITH_SIG_ECDSA)
77
int ret;
78
unsigned int i;
79
80
#ifdef WITH_OPENMP_SELF_TESTS
81
#pragma omp parallel
82
#pragma omp for schedule(static, 1) nowait
83
#endif
84
for(i = 0; i < NUM_WYCHEPROOF_ECDSA_TESTS; i++){
85
const wycheproof_ecdsa_test *t = wycheproof_ecdsa_all_tests[i];
86
ec_pub_key pub_key;
87
ec_params params;
88
89
if (t == NULL){
90
continue;
91
}
92
93
ecdsa_all_performed++;
94
ret = local_memset(&pub_key, 0, sizeof(pub_key)); OPENMP_EG(ret, err);
95
ret = local_memset(&params, 0, sizeof(params)); OPENMP_EG(ret, err);
96
97
/* Import EC params from test case */
98
ret = import_params(&params, t->curve);
99
if (ret) {
100
ext_printf("Error: ECDSA tests error importing params\n");
101
ret = -1;
102
OPENMP_EG(ret, err);
103
}
104
105
/* Import the public key */
106
ret = ec_pub_key_import_from_aff_buf(&pub_key, &params, t->pubkey, (u8)(t->pubkeylen), t->sig_alg);
107
if (ret) {
108
ext_printf("Error: ECDSA tests error importing public key\n");
109
ret = -1;
110
OPENMP_EG(ret, err);
111
}
112
113
114
ret = ec_verify(t->sig, (u8)(t->siglen), &pub_key, t->msg, t->msglen, t->sig_alg, t->hash, NULL, 0);
115
/* Valid result */
116
if ((t->result == 1) && ret) {
117
ext_printf("[-] Error when verifying ECDSA test %d / %s (verification NOK while must be valid)\n", i, t->name);
118
ext_printf(" (comment = %s)\n", t->comment);
119
ret = -1;
120
OPENMP_EG(ret, err);
121
}
122
/* Invalid result */
123
if ((t->result == -1) && !ret) {
124
ext_printf("[-] Error when verifying ECDSA test %d / %s (verification OK while must be invalid)\n", i, t->name);
125
ext_printf(" (comment = %s)\n", t->comment);
126
ret = -1;
127
OPENMP_EG(ret, err);
128
}
129
/* Acceptable result: only trigger an informational warning */
130
if (t->result == 0) {
131
if(ret){
132
ecdsa_acceptable_valid++;
133
}
134
else{
135
ecdsa_acceptable_invalid++;
136
}
137
#ifdef VERBOSE_ACCEPTABLE
138
ext_printf("\t[~] ECDSA test %d / %s (verification %d while acceptable)\n", i, t->name, ret);
139
ext_printf("\t (comment = %s)\n", t->comment);
140
#endif
141
}
142
}
143
144
ret = 0;
145
#ifndef WITH_OPENMP_SELF_TESTS
146
err:
147
#endif
148
return ret;
149
#else
150
return 0;
151
#endif
152
}
153
154
/* Check all EDDSA test vectors */
155
static unsigned int eddsa_acceptable_invalid = 0;
156
static unsigned int eddsa_acceptable_valid = 0;
157
static unsigned int eddsa_all_performed = 0;
158
static int check_wycheproof_eddsa(void)
159
{
160
#if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)
161
int ret;
162
unsigned int i;
163
164
#ifdef WITH_OPENMP_SELF_TESTS
165
#pragma omp parallel
166
#pragma omp for schedule(static, 1) nowait
167
#endif
168
for(i = 0; i < NUM_WYCHEPROOF_EDDSA_TESTS; i++){
169
const wycheproof_eddsa_test *t = wycheproof_eddsa_all_tests[i];
170
ec_pub_key pub_key;
171
ec_pub_key pub_key_check;
172
ec_priv_key priv_key;
173
ec_params params;
174
int check;
175
u8 exported_pub_key[EDDSA_MAX_PUB_KEY_ENCODED_LEN];
176
177
if (t == NULL){
178
continue;
179
}
180
181
OPENMP_LOCK();
182
eddsa_all_performed++;
183
OPENMP_UNLOCK();
184
ret = local_memset(&pub_key, 0, sizeof(pub_key)); OPENMP_EG(ret, err);
185
ret = local_memset(&priv_key, 0, sizeof(priv_key)); OPENMP_EG(ret, err);
186
ret = local_memset(&params, 0, sizeof(params)); OPENMP_EG(ret, err);
187
188
/* Import EC params from test case */
189
ret = import_params(&params, t->curve);
190
if (ret) {
191
ext_printf("Error: EDDSA tests error importing params\n");
192
ret = -1;
193
OPENMP_EG(ret, err);
194
}
195
196
/* Import the public key */
197
ret = eddsa_import_pub_key(&pub_key, t->pubkey, (u8)(t->pubkeylen), &params, t->sig_alg);
198
if (ret) {
199
ext_printf("Error: EDDSA tests error importing public key\n");
200
ret = -1;
201
OPENMP_EG(ret, err);
202
}
203
/* Import the private key */
204
ret = eddsa_import_priv_key(&priv_key, t->privkey, (u8)(t->privkeylen), &params, t->sig_alg);
205
if (ret) {
206
ext_printf("Error: EDDSA tests error importing private key\n");
207
ret = -1;
208
OPENMP_EG(ret, err);
209
}
210
/* Derive private to public */
211
ret = eddsa_init_pub_key(&pub_key_check, &priv_key);
212
if (ret) {
213
ext_printf("Error: EDDSA tests error deriving private to public key\n");
214
ret = -1;
215
OPENMP_EG(ret, err);
216
}
217
/* Check */
218
ret = eddsa_export_pub_key(&pub_key, exported_pub_key, (u8)(t->pubkeylen));
219
if(ret){
220
ext_printf("Error: EDDSA tests error when exporting public key\n");
221
ret = -1;
222
OPENMP_EG(ret, err);
223
}
224
/* */
225
ret = are_equal(t->pubkey, &exported_pub_key, (u8)(t->pubkeylen), &check); OPENMP_EG(ret, err);
226
if(!check){
227
ext_printf("Error: EDDSA tests error when checking public key from private\n");
228
ret = -1;
229
OPENMP_EG(ret, err);
230
}
231
232
ret = ec_verify(t->sig, (u8)(t->siglen), &pub_key, t->msg, t->msglen, t->sig_alg, t->hash, NULL, 0);
233
/* Valid result */
234
if ((t->result == 1) && ret) {
235
ext_printf("[-] Error when verifying EDDSA test %d / %s (verification NOK while must be valid)\n", i, t->name);
236
ext_printf(" (comment = %s)\n", t->comment);
237
ret = -1;
238
OPENMP_EG(ret, err);
239
}
240
/* Invalid result */
241
if ((t->result == -1) && !ret) {
242
ext_printf("[-] Error when verifying EDDSA test %d / %s (verification OK while must be invalid)\n", i, t->name);
243
ext_printf(" (comment = %s)\n", t->comment);
244
ret = -1;
245
OPENMP_EG(ret, err);
246
}
247
/* Acceptable result: only trigger an informational warning */
248
if (t->result == 0) {
249
OPENMP_LOCK();
250
if(ret){
251
eddsa_acceptable_valid++;
252
}
253
else{
254
eddsa_acceptable_invalid++;
255
}
256
#ifdef VERBOSE_ACCEPTABLE
257
ext_printf("\t[~] EDDSA test %d / %s (verification %d while acceptable)\n", i, t->name, ret);
258
ext_printf("\t (comment = %s)\n", t->comment);
259
#endif
260
OPENMP_UNLOCK();
261
}
262
}
263
264
ret = 0;
265
#ifndef WITH_OPENMP_SELF_TESTS
266
err:
267
#endif
268
return ret;
269
#else
270
return 0;
271
#endif
272
}
273
274
/* Check all XDH test vectors */
275
static unsigned int xdh_acceptable_invalid = 0;
276
static unsigned int xdh_acceptable_valid = 0;
277
static unsigned int xdh_all_performed = 0;
278
static int check_wycheproof_xdh(void)
279
{
280
#if defined(WITH_X25519) || defined(WITH_X448)
281
int ret;
282
unsigned int i;
283
284
#ifdef WITH_OPENMP_SELF_TESTS
285
#pragma omp parallel
286
#pragma omp for schedule(static, 1) nowait
287
#endif
288
for(i = 0; i < NUM_WYCHEPROOF_XDH_TESTS; i++){
289
int check;
290
const wycheproof_xdh_test *t = wycheproof_xdh_all_tests[i];
291
unsigned int alglen = 0;
292
/* Max size buffer */
293
u8 pubkey_check[X448_SIZE];
294
u8 sharedsecret_check[X448_SIZE];
295
296
if (t == NULL){
297
continue;
298
}
299
300
OPENMP_LOCK();
301
xdh_all_performed++;
302
OPENMP_UNLOCK();
303
304
#if defined(WITH_X25519)
305
if(t->xdh_alg == X25519){
306
OPENMP_MUST_HAVE(((t->curve) == &wei25519_str_params), ret, err);
307
alglen = X25519_SIZE;
308
}
309
#endif
310
#if defined(WITH_X448)
311
if(t->xdh_alg == X448){
312
OPENMP_MUST_HAVE(((t->curve) == &wei448_str_params), ret, err);
313
alglen = X448_SIZE;
314
}
315
#endif
316
if(alglen == 0){
317
ext_printf("Error: XDH tests error, unkown algorithm\n");
318
ret = -1;
319
OPENMP_EG(ret, err);
320
}
321
/* Reject bad lengths */
322
if(t->privkeylen != alglen){
323
if(t->result != -1){
324
ext_printf("[-] Error: XDH tests error, unkown private key length %d with valid result\n", t->privkeylen);
325
ext_printf(" (comment = %s)\n", t->comment);
326
ret = -1;
327
OPENMP_EG(ret, err);
328
}
329
else{
330
continue;
331
}
332
}
333
if(t->peerpubkeylen != alglen){
334
if(t->result != -1){
335
ext_printf("[-] Error: XDH tests error, unkown peer public key length %d with valid result\n", t->peerpubkeylen);
336
ext_printf(" (comment = %s)\n", t->comment);
337
ret = -1;
338
OPENMP_EG(ret, err);
339
}
340
else{
341
continue;
342
}
343
}
344
if(t->sharedsecretlen != alglen){
345
if(t->result != -1){
346
ext_printf("[-] Error: XDH tests error, unkown shared secret length %d with valid result\n", t->sharedsecretlen);
347
ext_printf(" (comment = %s)\n", t->comment);
348
ret = -1;
349
OPENMP_EG(ret, err);
350
}
351
else{
352
continue;
353
}
354
}
355
if((t->ourpubkeylen != 0) && (t->ourpubkeylen != alglen)){
356
if(t->result != -1){
357
ext_printf("[-] Error: XDH tests error, unkown our public key length %d with valid result\n", t->ourpubkeylen);
358
ext_printf(" (comment = %s)\n", t->comment);
359
ret = -1;
360
OPENMP_EG(ret, err);
361
}
362
else{
363
continue;
364
}
365
}
366
#if defined(WITH_X25519)
367
if(t->xdh_alg == X25519){
368
/* Derive our public key */
369
ret = x25519_init_pub_key(t->privkey, pubkey_check);
370
if(ret){
371
ext_printf("[-] Error: XDH tests error when deriving private key to public\n");
372
ext_printf(" (comment = %s)\n", t->comment);
373
ret = -1;
374
OPENMP_EG(ret, err);
375
}
376
if(t->ourpubkeylen != 0){
377
/* Check public key against the test one */
378
ret = are_equal(t->ourpubkey, pubkey_check, alglen, &check); OPENMP_EG(ret, err);
379
if(!check){
380
ext_printf("[-] Error: XDH tests error when checking our public key\n");
381
ext_printf(" (comment = %s)\n", t->comment);
382
ret = -1;
383
OPENMP_EG(ret, err);
384
}
385
}
386
/* Derive the shared secret */
387
ret = x25519_derive_secret(t->privkey, t->peerpubkey, sharedsecret_check);
388
if(ret){
389
/* Handle "acceptable" results here (e.g. public key on twist) */
390
if(t->result == 0){
391
OPENMP_LOCK();
392
xdh_acceptable_invalid++;
393
#ifdef VERBOSE_ACCEPTABLE
394
ext_printf("\t[~] XDH test %d / %s (shared secret derivation NOK while acceptable)\n", i, t->name);
395
ext_printf("\t (comment = %s)\n", t->comment);
396
#endif
397
OPENMP_UNLOCK();
398
continue;
399
}
400
ext_printf("[-] Error: XDH tests error when deriving shared secret\n");
401
ext_printf(" (comment = %s)\n", t->comment);
402
ret = -1;
403
OPENMP_EG(ret, err);
404
}
405
if(t->result == -1){
406
ext_printf("[-] Error: XDH tests is OK while invalid\n");
407
ext_printf(" (comment = %s)\n", t->comment);
408
ret = -1;
409
OPENMP_EG(ret, err);
410
}
411
/* Check the shared secret */
412
ret = are_equal(t->sharedsecret, sharedsecret_check, alglen, &check); OPENMP_EG(ret, err);
413
if(!check){
414
ext_printf("[-] Error: XDH tests error when checking shared secret\n");
415
ext_printf(" (comment = %s)\n", t->comment);
416
ret = -1;
417
OPENMP_EG(ret, err);
418
}
419
}
420
#endif
421
#if defined(WITH_X448)
422
if(t->xdh_alg == X448){
423
/* Derive our public key */
424
ret = x448_init_pub_key(t->privkey, pubkey_check);
425
if(ret){
426
ext_printf("[-] Error: XDH tests error when deriving private key to public\n");
427
ext_printf(" (comment = %s)\n", t->comment);
428
ret = -1;
429
OPENMP_EG(ret, err);
430
}
431
if(t->ourpubkeylen != 0){
432
/* Check public key against the test one */
433
ret = are_equal(t->ourpubkey, pubkey_check, alglen, &check); OPENMP_EG(ret, err);
434
if(!check){
435
ext_printf("[-] Error: XDH tests error when checking our public key\n");
436
ext_printf(" (comment = %s)\n", t->comment);
437
ret = -1;
438
OPENMP_EG(ret, err);
439
}
440
}
441
/* Derive the shared secret */
442
ret = x448_derive_secret(t->privkey, t->peerpubkey, sharedsecret_check);
443
if(ret){
444
/* Handle "acceptable" results here (e.g. public key on twist) */
445
if(t->result == 0){
446
OPENMP_LOCK();
447
xdh_acceptable_invalid++;
448
#ifdef VERBOSE_ACCEPTABLE
449
ext_printf("\t[~] XDH test %d / %s (shared secret derivation NOK while acceptable)\n", i, t->name);
450
ext_printf("\t (comment = %s)\n", t->comment);
451
#endif
452
OPENMP_UNLOCK();
453
continue;
454
}
455
ext_printf("[-] Error: XDH tests error when deriving shared secret\n");
456
ext_printf(" (comment = %s)\n", t->comment);
457
OPENMP_EG(ret, err);
458
}
459
if(t->result == -1){
460
ext_printf("[-] Error: XDH tests is OK while invalid\n");
461
ext_printf(" (comment = %s)\n", t->comment);
462
ret = -1;
463
OPENMP_EG(ret, err);
464
}
465
/* Check the shared secret */
466
ret = are_equal(t->sharedsecret, sharedsecret_check, alglen, &check); OPENMP_EG(ret, err);
467
if(!check){
468
ext_printf("[-] Error: XDH tests error when checking shared secret\n");
469
ext_printf(" (comment = %s)\n", t->comment);
470
ret = -1;
471
OPENMP_EG(ret, err);
472
}
473
474
}
475
#endif
476
/* Log the acceptable results */
477
if (t->result == 0) {
478
OPENMP_LOCK();
479
xdh_acceptable_valid++;
480
#ifdef VERBOSE_ACCEPTABLE
481
ext_printf("\t[~] XDH test %d / %s (shared secret OK while acceptable)\n", i, t->name);
482
ext_printf("\t (comment = %s)\n", t->comment);
483
#endif
484
OPENMP_UNLOCK();
485
}
486
}
487
ret = 0;
488
#ifndef WITH_OPENMP_SELF_TESTS
489
err:
490
#endif
491
return ret;
492
#else
493
return 0;
494
#endif
495
}
496
497
/* Point decompression routine */
498
static int uncompress_ecc_point(const ec_params *params, const u8 *peerpubkey, u8 peerpubkeylen, u8 *serialized_pub_key, u8 serialized_pub_key_size, int compression)
499
{
500
int ret, sign, check;
501
fp x, tmp;
502
fp_t y;
503
x.magic = tmp.magic = 0;
504
505
MUST_HAVE((params != NULL) && (peerpubkey != NULL) && (serialized_pub_key != NULL), ret, err);
506
507
/* Uncompressed point size should be twice the x coordinate */
508
MUST_HAVE((serialized_pub_key_size == (2 * peerpubkeylen)), ret, err);
509
510
/* Compression is either 02 or 03 */
511
MUST_HAVE(((compression == 0x02) || (compression == 0x03)), ret, err);
512
513
/* Import our x coordinate */
514
ret = fp_init_from_buf(&x, &(params->ec_fp), peerpubkey, peerpubkeylen); EG(ret, err);
515
ret = fp_init(&tmp, &(params->ec_fp)); EG(ret, err);
516
/* Compute the Weierstrass equation y^2 = x^3 + ax + b solutions */
517
ret = aff_pt_y_from_x(&tmp, &x, &x, &(params->ec_curve)); EG(ret, err);
518
519
/* Choose the square root depending on the compression information */
520
sign = (compression - 2);
521
522
ret = fp_cmp(&x, &tmp, &check); EG(ret, err);
523
524
y = ((check > 0) == sign) ? &x : &tmp;
525
526
/* Export the point to our buffer */
527
ret = local_memcpy(&serialized_pub_key[0], &peerpubkey[0], (serialized_pub_key_size / 2)); EG(ret, err);
528
ret = fp_export_to_buf(&serialized_pub_key[(serialized_pub_key_size / 2)], (serialized_pub_key_size / 2), y);
529
530
err:
531
fp_uninit(&x);
532
fp_uninit(&tmp);
533
PTR_NULLIFY(y);
534
535
return ret;
536
}
537
538
/* Check all ECDH test vectors */
539
static unsigned int ecdh_acceptable_invalid = 0;
540
static unsigned int ecdh_acceptable_valid = 0;
541
static unsigned int ecdh_all_performed = 0;
542
static int check_wycheproof_ecdh(void)
543
{
544
#if defined(WITH_ECCCDH)
545
int ret;
546
unsigned int i;
547
548
#ifdef WITH_OPENMP_SELF_TESTS
549
#pragma omp parallel
550
#pragma omp for schedule(static, 1) nowait
551
#endif
552
for(i = 0; i < NUM_WYCHEPROOF_ECDH_TESTS; i++){
553
int check;
554
const wycheproof_ecdh_test *t = wycheproof_ecdh_all_tests[i];
555
ec_pub_key peerpub_key;
556
ec_pub_key ourpub_key;
557
ec_pub_key ourpub_key_check;
558
ec_priv_key priv_key;
559
ec_params params;
560
u8 sharedsecret_check[EC_PRIV_KEY_MAX_SIZE];
561
u8 sharedsecretsize;
562
u8 serialized_pub_key[EC_PUB_KEY_MAX_SIZE];
563
u8 serialized_pub_key_check[EC_PUB_KEY_MAX_SIZE];
564
u8 serialized_pub_key_size;
565
566
if (t == NULL){
567
continue;
568
}
569
570
OPENMP_LOCK();
571
ecdh_all_performed++;
572
OPENMP_UNLOCK();
573
574
ret = local_memset(&peerpub_key, 0, sizeof(peerpub_key)); OPENMP_EG(ret, err);
575
ret = local_memset(&ourpub_key, 0, sizeof(ourpub_key)); OPENMP_EG(ret, err);
576
ret = local_memset(&ourpub_key_check, 0, sizeof(ourpub_key_check)); OPENMP_EG(ret, err);
577
ret = local_memset(&priv_key, 0, sizeof(priv_key)); OPENMP_EG(ret, err);
578
ret = local_memset(&params, 0, sizeof(params)); OPENMP_EG(ret, err);
579
ret = local_memset(sharedsecret_check, 0, sizeof(sharedsecret_check)); OPENMP_EG(ret, err);
580
ret = local_memset(serialized_pub_key, 0, sizeof(serialized_pub_key)); OPENMP_EG(ret, err);
581
582
/* Import EC params from test case */
583
ret = import_params(&params, t->curve);
584
if (ret) {
585
ext_printf("Error: ECDH tests error importing params\n");
586
ret = -1;
587
OPENMP_EG(ret, err);
588
}
589
590
/* Get the sizes */
591
ret = ecccdh_shared_secret_size(&params, &sharedsecretsize);
592
if (ret) {
593
ext_printf("Error: ECDH tests error getting shared secret size\n");
594
ret = -1;
595
OPENMP_EG(ret, err);
596
}
597
OPENMP_MUST_HAVE((sharedsecretsize <= sizeof(sharedsecret_check)), ret, err);
598
ret = ecccdh_serialized_pub_key_size(&params, &serialized_pub_key_size);
599
if (ret) {
600
ext_printf("Error: ECDH tests error getting serialized public key size\n");
601
ret = -1;
602
OPENMP_EG(ret, err);
603
}
604
OPENMP_MUST_HAVE((serialized_pub_key_size <= sizeof(serialized_pub_key)), ret, err);
605
OPENMP_MUST_HAVE((serialized_pub_key_size <= sizeof(serialized_pub_key_check)), ret, err);
606
607
/* Import the private key */
608
ret = ec_priv_key_import_from_buf(&priv_key, &params, t->privkey, (u8)(t->privkeylen), t->ecdh_alg);
609
if (ret) {
610
ext_printf("Error: ECDH tests error importing private key\n");
611
ret = -1;
612
OPENMP_EG(ret, err);
613
}
614
615
if(t->ourpubkeylen != 0){
616
/* Import our public key if it exists */
617
ret = ec_pub_key_import_from_aff_buf(&ourpub_key, &params, t->ourpubkey, (u8)(t->ourpubkeylen), t->ecdh_alg);
618
if (ret && (t->result >= 0)) {
619
ext_printf("[-] Error: ECDH tests error when importing our public key\n");
620
ext_printf(" (comment = %s)\n", t->comment);
621
ret = -1;
622
OPENMP_EG(ret, err);
623
}
624
/* Derive our private key to public */
625
ret = ecccdh_init_pub_key(&ourpub_key_check, &priv_key);
626
if (ret) {
627
ext_printf("Error: ECDH tests error deriving our private key to public\n");
628
ret = -1;
629
OPENMP_EG(ret, err);
630
}
631
/* Check if we get the same public key by serializing them */
632
ret = ecccdh_serialize_pub_key(&ourpub_key, serialized_pub_key, serialized_pub_key_size);
633
if (ret){
634
ext_printf("Error: ECDH tests error serializing public key\n");
635
ret = -1;
636
OPENMP_EG(ret, err);
637
}
638
ret = ecccdh_serialize_pub_key(&ourpub_key_check, serialized_pub_key_check, serialized_pub_key_size);
639
if (ret){
640
ext_printf("Error: ECDH tests error serializing public key\n");
641
ret = -1;
642
OPENMP_EG(ret, err);
643
}
644
ret = are_equal(serialized_pub_key, serialized_pub_key_check, serialized_pub_key_size, &check); OPENMP_EG(ret, err);
645
if(!check){
646
ext_printf("[-] Error: ECDH tests error when checking our public key\n");
647
ext_printf(" (comment = %s)\n", t->comment);
648
ret = -1;
649
OPENMP_EG(ret, err);
650
}
651
}
652
653
/* Do we have to uncompress our point? */
654
if(t->compressed > 0){
655
/* Uncompress the point */
656
ret = uncompress_ecc_point(&params, t->peerpubkey, (u8)(t->peerpubkeylen), serialized_pub_key, serialized_pub_key_size, t->compressed);
657
if ((ret) && (t->result >= 0)) {
658
ext_printf("[-] Error: ECDH tests error when uncompressing public key\n");
659
ext_printf(" (comment = %s)\n", t->comment);
660
ret = -1;
661
OPENMP_EG(ret, err);
662
}
663
}
664
else{
665
/* No point compression is used, copy our raw buffer as public key */
666
if((t->peerpubkeylen != serialized_pub_key_size) && (t->result >= 0)){
667
ext_printf("[-] Error: ECDH tests error when checking our public key size, got %d instead of %d\n", t->peerpubkeylen, serialized_pub_key_size);
668
ext_printf(" (comment = %s)\n", t->comment);
669
ret = -1;
670
OPENMP_EG(ret, err);
671
}
672
ret = local_memcpy(serialized_pub_key, t->peerpubkey, serialized_pub_key_size); OPENMP_EG(ret, err);
673
}
674
/* Now derive the shared secret */
675
ret = ecccdh_derive_secret(&priv_key, serialized_pub_key, serialized_pub_key_size, sharedsecret_check, sharedsecretsize);
676
if ((ret) && (t->result >= 0)) {
677
ext_printf("[-] Error: ECDH tests error when deriving secret while acceptable or valid\n");
678
ext_printf(" (comment = %s)\n", t->comment);
679
ret = -1;
680
OPENMP_EG(ret, err);
681
}
682
if((!ret) && (t->result == -1)){
683
ext_printf("Error: ECDH tests error, secret derived OK while invalid\n");
684
ext_printf(" (comment = %s)\n", t->comment);
685
ret = -1;
686
OPENMP_EG(ret, err);
687
}
688
if(t->result == -1){
689
continue;
690
}
691
if(sharedsecretsize != t->sharedsecretlen){
692
ext_printf("Error: ECDH tests error, bad shared secret size %d instead of %d\n", sharedsecretsize, t->sharedsecretlen);
693
ext_printf(" (comment = %s)\n", t->comment);
694
ret = -1;
695
OPENMP_EG(ret, err);
696
}
697
/* Compare */
698
ret = are_equal(sharedsecret_check, t->sharedsecret, sharedsecretsize, &check); OPENMP_EG(ret, err);
699
if(!check){
700
ext_printf("[-] Error: ECDH tests error when checking the computed shared secret, they differ\n");
701
ext_printf(" (comment = %s)\n", t->comment);
702
ret = -1;
703
OPENMP_EG(ret, err);
704
}
705
/* Log the acceptable results */
706
if (t->result == 0) {
707
OPENMP_LOCK();
708
ecdh_acceptable_valid++;
709
#ifdef VERBOSE_ACCEPTABLE
710
ext_printf("\t[~] ECDH test %d / %s (shared secret OK while acceptable)\n", i, t->name);
711
ext_printf("\t (comment = %s)\n", t->comment);
712
#endif
713
OPENMP_UNLOCK();
714
}
715
716
}
717
ret = 0;
718
#ifndef WITH_OPENMP_SELF_TESTS
719
err:
720
#endif
721
return ret;
722
#else
723
return 0;
724
#endif
725
}
726
727
/* Check all HMAC test vectors */
728
static unsigned int hmac_acceptable_invalid = 0;
729
static unsigned int hmac_acceptable_valid = 0;
730
static unsigned int hmac_all_performed = 0;
731
static int check_wycheproof_hmac(void)
732
{
733
#if defined(WITH_HMAC)
734
int ret;
735
unsigned int i;
736
737
#ifdef WITH_OPENMP_SELF_TESTS
738
#pragma omp parallel
739
#pragma omp for schedule(static, 1) nowait
740
#endif
741
for(i = 0; i < NUM_WYCHEPROOF_HMAC_TESTS; i++){
742
int check;
743
const wycheproof_hmac_test *t = wycheproof_hmac_all_tests[i];
744
u8 hmac_res[MAX_DIGEST_SIZE];
745
u8 hlen;
746
747
if (t == NULL){
748
continue;
749
}
750
751
OPENMP_LOCK();
752
hmac_all_performed++;
753
OPENMP_UNLOCK();
754
755
ret = local_memset(&hmac_res, 0, sizeof(hmac_res)); OPENMP_EG(ret, err);
756
757
hlen = sizeof(hmac_res);
758
ret = hmac(t->key, t->keylen, t->hash, t->msg, t->msglen, hmac_res, &hlen);
759
if (ret) {
760
ext_printf("[-] Error: HMAC tests error when performin HMAC\n");
761
ext_printf(" (comment = %s)\n", t->comment);
762
ret = -1;
763
OPENMP_EG(ret, err);
764
}
765
if((hlen < t->taglen) && (t->result >= 0)){
766
ext_printf("[-] Error: HMAC tests error: size error %d < %d\n", hlen, t->taglen);
767
ext_printf(" (comment = %s)\n", t->comment);
768
ret = -1;
769
OPENMP_EG(ret, err);
770
}
771
/* Compare */
772
ret = are_equal(hmac_res, t->tag, t->taglen, &check); OPENMP_EG(ret, err);
773
if((!check) && (t->result >= 0)){
774
ext_printf("[-] Error: HMAC tests error when checking the computed tag, they differ\n");
775
ext_printf(" (comment = %s)\n", t->comment);
776
ret = -1;
777
OPENMP_EG(ret, err);
778
}
779
/* Log the acceptable results */
780
if (t->result == 0) {
781
OPENMP_LOCK();
782
hmac_acceptable_valid++;
783
#ifdef VERBOSE_ACCEPTABLE
784
ext_printf("\t[~] HMAC test %d / %s (shared secret OK while acceptable)\n", i, t->name);
785
ext_printf("\t (comment = %s)\n", t->comment);
786
#endif
787
OPENMP_UNLOCK();
788
}
789
}
790
ret = 0;
791
#ifndef WITH_OPENMP_SELF_TESTS
792
err:
793
#endif
794
return ret;
795
#else
796
return 0;
797
#endif
798
}
799
800
int main(int argc, char *argv[])
801
{
802
FORCE_USED_VAR(argc);
803
FORCE_USED_VAR(argv);
804
805
/**********************/
806
ext_printf("==== Checking ECDH =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_ECDH_TESTS_IMPORTED, NUM_WYCHEPROOF_ECDH_TESTS_SKIPPED, NUM_WYCHEPROOF_ECDH_TESTS_VALID, NUM_WYCHEPROOF_ECDH_TESTS_INVALID, NUM_WYCHEPROOF_ECDH_TESTS_ACCEPTABLE);
807
if(check_wycheproof_ecdh()){
808
goto err;
809
}
810
ext_printf("[+][%d] All ECDH tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", ecdh_all_performed, ecdh_acceptable_valid, ecdh_acceptable_invalid);
811
/**********************/
812
ext_printf("==== Checking XDH =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_XDH_TESTS_IMPORTED, NUM_WYCHEPROOF_XDH_TESTS_SKIPPED, NUM_WYCHEPROOF_XDH_TESTS_VALID, NUM_WYCHEPROOF_XDH_TESTS_INVALID, NUM_WYCHEPROOF_XDH_TESTS_ACCEPTABLE);
813
if(check_wycheproof_xdh()){
814
goto err;
815
}
816
ext_printf("[+][%d] All XDH tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", xdh_all_performed, xdh_acceptable_valid, xdh_acceptable_invalid);
817
/**********************/
818
ext_printf("==== Checking ECDSA =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_ECDSA_TESTS_IMPORTED, NUM_WYCHEPROOF_ECDSA_TESTS_SKIPPED, NUM_WYCHEPROOF_ECDSA_TESTS_VALID, NUM_WYCHEPROOF_ECDSA_TESTS_INVALID, NUM_WYCHEPROOF_ECDSA_TESTS_ACCEPTABLE);
819
if(check_wycheproof_ecdsa()){
820
goto err;
821
}
822
ext_printf("[+][%d] All ECDSA tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", ecdsa_all_performed, ecdsa_acceptable_valid, ecdsa_acceptable_invalid);
823
/**********************/
824
ext_printf("==== Checking EDDSA =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_EDDSA_TESTS_IMPORTED, NUM_WYCHEPROOF_EDDSA_TESTS_SKIPPED, NUM_WYCHEPROOF_EDDSA_TESTS_VALID, NUM_WYCHEPROOF_EDDSA_TESTS_INVALID, NUM_WYCHEPROOF_EDDSA_TESTS_ACCEPTABLE);
825
if(check_wycheproof_eddsa()){
826
goto err;
827
}
828
ext_printf("[+][%d] All EDDSA tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", eddsa_all_performed, eddsa_acceptable_valid, eddsa_acceptable_invalid);
829
/**********************/
830
ext_printf("==== Checking HMAC =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_HMAC_TESTS_IMPORTED, NUM_WYCHEPROOF_HMAC_TESTS_SKIPPED, NUM_WYCHEPROOF_HMAC_TESTS_VALID, NUM_WYCHEPROOF_HMAC_TESTS_INVALID, NUM_WYCHEPROOF_HMAC_TESTS_ACCEPTABLE);
831
if(check_wycheproof_hmac()){
832
goto err;
833
}
834
ext_printf("[+][%d] All HMAC tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", hmac_all_performed, hmac_acceptable_valid, hmac_acceptable_invalid);
835
836
err:
837
return 0;
838
}
839
840