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