1*f0865ec9SKyle Evans /*
2*f0865ec9SKyle Evans * Copyright (C) 2017 - 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 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8*f0865ec9SKyle Evans *
9*f0865ec9SKyle Evans * Contributors:
10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12*f0865ec9SKyle Evans *
13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license.
14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project.
15*f0865ec9SKyle Evans */
16*f0865ec9SKyle Evans #include <libecc/external_deps/print.h>
17*f0865ec9SKyle Evans #include <libecc/utils/utils.h>
18*f0865ec9SKyle Evans #include <libecc/libsig.h>
19*f0865ec9SKyle Evans
20*f0865ec9SKyle Evans /*
21*f0865ec9SKyle Evans * Use extern declarations to avoid including
22*f0865ec9SKyle Evans * ec_self_tests_core.h, which has all fixed
23*f0865ec9SKyle Evans * test vectors definitions. We only need the
24*f0865ec9SKyle Evans * three functions below.
25*f0865ec9SKyle Evans */
26*f0865ec9SKyle Evans extern ATTRIBUTE_WARN_UNUSED_RET int perform_known_test_vectors_test(const char *sig, const char *hash, const char *curve);
27*f0865ec9SKyle Evans extern ATTRIBUTE_WARN_UNUSED_RET int perform_random_sig_verif_test(const char *sig, const char *hash, const char *curve);
28*f0865ec9SKyle Evans extern ATTRIBUTE_WARN_UNUSED_RET int perform_performance_test(const char *sig, const char *hash, const char *curve);
29*f0865ec9SKyle Evans
30*f0865ec9SKyle Evans /* Tests kinds */
31*f0865ec9SKyle Evans #define KNOWN_TEST_VECTORS (1)
32*f0865ec9SKyle Evans #define RANDOM_SIG_VERIF (1 << 2)
33*f0865ec9SKyle Evans #define PERFORMANCE (1 << 3)
34*f0865ec9SKyle Evans
35*f0865ec9SKyle Evans typedef struct {
36*f0865ec9SKyle Evans const char *type_name;
37*f0865ec9SKyle Evans const char *type_help;
38*f0865ec9SKyle Evans unsigned int type_mask;
39*f0865ec9SKyle Evans } test_type;
40*f0865ec9SKyle Evans
41*f0865ec9SKyle Evans static const test_type test_types[] = {
42*f0865ec9SKyle Evans {
43*f0865ec9SKyle Evans .type_name = "vectors",
44*f0865ec9SKyle Evans .type_help = "Perform known test vectors",
45*f0865ec9SKyle Evans .type_mask = KNOWN_TEST_VECTORS,
46*f0865ec9SKyle Evans },
47*f0865ec9SKyle Evans {
48*f0865ec9SKyle Evans .type_name = "rand",
49*f0865ec9SKyle Evans .type_help = "Perform random sign/verify tests",
50*f0865ec9SKyle Evans .type_mask = RANDOM_SIG_VERIF,
51*f0865ec9SKyle Evans },
52*f0865ec9SKyle Evans {
53*f0865ec9SKyle Evans .type_name = "perf",
54*f0865ec9SKyle Evans .type_help = "Performance tests",
55*f0865ec9SKyle Evans .type_mask = PERFORMANCE,
56*f0865ec9SKyle Evans },
57*f0865ec9SKyle Evans };
58*f0865ec9SKyle Evans
perform_tests(unsigned int tests,const char * sig,const char * hash,const char * curve)59*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int perform_tests(unsigned int tests, const char *sig, const char *hash, const char *curve)
60*f0865ec9SKyle Evans {
61*f0865ec9SKyle Evans /* KNOWN_TEST_VECTORS tests */
62*f0865ec9SKyle Evans if (tests & KNOWN_TEST_VECTORS) {
63*f0865ec9SKyle Evans if (perform_known_test_vectors_test(sig, hash, curve)) {
64*f0865ec9SKyle Evans goto err;
65*f0865ec9SKyle Evans }
66*f0865ec9SKyle Evans }
67*f0865ec9SKyle Evans /* RANDOM_SIG_VERIF tests */
68*f0865ec9SKyle Evans if (tests & RANDOM_SIG_VERIF) {
69*f0865ec9SKyle Evans if (perform_random_sig_verif_test(sig, hash, curve)) {
70*f0865ec9SKyle Evans goto err;
71*f0865ec9SKyle Evans }
72*f0865ec9SKyle Evans }
73*f0865ec9SKyle Evans /* PERFORMANCE tests */
74*f0865ec9SKyle Evans if (tests & PERFORMANCE) {
75*f0865ec9SKyle Evans if (perform_performance_test(sig, hash, curve)) {
76*f0865ec9SKyle Evans goto err;
77*f0865ec9SKyle Evans }
78*f0865ec9SKyle Evans }
79*f0865ec9SKyle Evans
80*f0865ec9SKyle Evans return 0;
81*f0865ec9SKyle Evans
82*f0865ec9SKyle Evans err:
83*f0865ec9SKyle Evans return -1;
84*f0865ec9SKyle Evans }
85*f0865ec9SKyle Evans
print_curves(void)86*f0865ec9SKyle Evans static void print_curves(void)
87*f0865ec9SKyle Evans {
88*f0865ec9SKyle Evans u8 i;
89*f0865ec9SKyle Evans
90*f0865ec9SKyle Evans /* Print all the available curves */
91*f0865ec9SKyle Evans for (i = 0; i < EC_CURVES_NUM; i++) {
92*f0865ec9SKyle Evans ext_printf("%s ", (const char *)(ec_maps[i].params->name->buf));
93*f0865ec9SKyle Evans }
94*f0865ec9SKyle Evans
95*f0865ec9SKyle Evans return;
96*f0865ec9SKyle Evans }
97*f0865ec9SKyle Evans
print_hash_algs(void)98*f0865ec9SKyle Evans static void print_hash_algs(void)
99*f0865ec9SKyle Evans {
100*f0865ec9SKyle Evans int i;
101*f0865ec9SKyle Evans
102*f0865ec9SKyle Evans /* Print all the available hash functions */
103*f0865ec9SKyle Evans for (i = 0; hash_maps[i].type != UNKNOWN_HASH_ALG; i++) {
104*f0865ec9SKyle Evans ext_printf("%s ", hash_maps[i].name);
105*f0865ec9SKyle Evans }
106*f0865ec9SKyle Evans
107*f0865ec9SKyle Evans return;
108*f0865ec9SKyle Evans }
109*f0865ec9SKyle Evans
print_sig_algs(void)110*f0865ec9SKyle Evans static void print_sig_algs(void)
111*f0865ec9SKyle Evans {
112*f0865ec9SKyle Evans int i;
113*f0865ec9SKyle Evans
114*f0865ec9SKyle Evans /* Print all the available signature schemes */
115*f0865ec9SKyle Evans for (i = 0; ec_sig_maps[i].type != UNKNOWN_ALG; i++) {
116*f0865ec9SKyle Evans ext_printf("%s ", ec_sig_maps[i].name);
117*f0865ec9SKyle Evans }
118*f0865ec9SKyle Evans
119*f0865ec9SKyle Evans return;
120*f0865ec9SKyle Evans }
121*f0865ec9SKyle Evans
print_help(const char * bad_arg)122*f0865ec9SKyle Evans static void print_help(const char *bad_arg)
123*f0865ec9SKyle Evans {
124*f0865ec9SKyle Evans int j;
125*f0865ec9SKyle Evans if(bad_arg != NULL){
126*f0865ec9SKyle Evans ext_printf("Argument %s is unknown. Possible args are:\n", bad_arg);
127*f0865ec9SKyle Evans }
128*f0865ec9SKyle Evans for (j = 0; j < (int)(sizeof(test_types) / sizeof(test_type)); j++) {
129*f0865ec9SKyle Evans ext_printf("\t%20s:\t%s\n", test_types[j].type_name,
130*f0865ec9SKyle Evans test_types[j].type_help);
131*f0865ec9SKyle Evans }
132*f0865ec9SKyle Evans ext_printf("-------------------\n");
133*f0865ec9SKyle Evans ext_printf("NOTE: you can filter signatures with 'sign=', hash algorithms with 'hash=', curves with 'curve='\n");
134*f0865ec9SKyle Evans ext_printf("\tExample: sign=ECDSA hash=SHA256 hash=SHA512 curve=FRP256V1\n");
135*f0865ec9SKyle Evans ext_printf("\tPossible signatures: ");
136*f0865ec9SKyle Evans print_sig_algs();
137*f0865ec9SKyle Evans ext_printf("\n\tPossible hash algorithms: ");
138*f0865ec9SKyle Evans print_hash_algs();
139*f0865ec9SKyle Evans ext_printf("\n\tPossible curves: ");
140*f0865ec9SKyle Evans print_curves();
141*f0865ec9SKyle Evans ext_printf("\n");
142*f0865ec9SKyle Evans }
143*f0865ec9SKyle Evans
144*f0865ec9SKyle Evans #if defined(USE_SMALL_STACK)
145*f0865ec9SKyle Evans #define MAX_FILTERS 1
146*f0865ec9SKyle Evans #else
147*f0865ec9SKyle Evans #define MAX_FILTERS 100
148*f0865ec9SKyle Evans #endif
149*f0865ec9SKyle Evans
150*f0865ec9SKyle Evans #ifdef __cplusplus
151*f0865ec9SKyle Evans /* In case of a C++ compiler, preserve our "main"
152*f0865ec9SKyle Evans * linkage.
153*f0865ec9SKyle Evans */
154*f0865ec9SKyle Evans extern "C" {
155*f0865ec9SKyle Evans int main(int argc, char *argv[]);
156*f0865ec9SKyle Evans }
157*f0865ec9SKyle Evans #endif
158*f0865ec9SKyle Evans
main(int argc,char * argv[])159*f0865ec9SKyle Evans int main(int argc, char *argv[])
160*f0865ec9SKyle Evans {
161*f0865ec9SKyle Evans int ret;
162*f0865ec9SKyle Evans unsigned int tests_to_do;
163*f0865ec9SKyle Evans const char *sign_filters[MAX_FILTERS] = { NULL };
164*f0865ec9SKyle Evans const char *hash_filters[MAX_FILTERS] = { NULL };
165*f0865ec9SKyle Evans const char *curve_filters[MAX_FILTERS] = { NULL };
166*f0865ec9SKyle Evans int sign_filters_num = 0, hash_filters_num = 0, curve_filters_num = 0;
167*f0865ec9SKyle Evans int i, j, k;
168*f0865ec9SKyle Evans
169*f0865ec9SKyle Evans /* By default, perform all tests */
170*f0865ec9SKyle Evans tests_to_do = KNOWN_TEST_VECTORS | RANDOM_SIG_VERIF | PERFORMANCE;
171*f0865ec9SKyle Evans
172*f0865ec9SKyle Evans /* Sanity check */
173*f0865ec9SKyle Evans if(MAX_FILTERS < 1){
174*f0865ec9SKyle Evans ext_printf("Error: MAX_FILTERS too small\n");
175*f0865ec9SKyle Evans ret = -1;
176*f0865ec9SKyle Evans goto err;
177*f0865ec9SKyle Evans }
178*f0865ec9SKyle Evans
179*f0865ec9SKyle Evans /* If we have one or more arguments, only perform specific test */
180*f0865ec9SKyle Evans if (argc > 1) {
181*f0865ec9SKyle Evans unsigned char found = 0, found_filter = 0;
182*f0865ec9SKyle Evans unsigned int found_ops = 0;
183*f0865ec9SKyle Evans int check;
184*f0865ec9SKyle Evans u32 len;
185*f0865ec9SKyle Evans /* Check of the args */
186*f0865ec9SKyle Evans for (i = 1; i < argc; i++) {
187*f0865ec9SKyle Evans found = found_filter = 0;
188*f0865ec9SKyle Evans for (j = 0;
189*f0865ec9SKyle Evans j < (int)(sizeof(test_types) / sizeof(test_type));
190*f0865ec9SKyle Evans j++) {
191*f0865ec9SKyle Evans ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);
192*f0865ec9SKyle Evans ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);
193*f0865ec9SKyle Evans if (check) {
194*f0865ec9SKyle Evans found_ops++;
195*f0865ec9SKyle Evans found = 1;
196*f0865ec9SKyle Evans break;
197*f0865ec9SKyle Evans }
198*f0865ec9SKyle Evans ret = are_equal(argv[i], "sign=", sizeof("sign=")-1, &check); EG(ret, err);
199*f0865ec9SKyle Evans if(check){
200*f0865ec9SKyle Evans if(sign_filters_num >= MAX_FILTERS){
201*f0865ec9SKyle Evans ext_printf("Maximum number of sign filters %d exceeded!\n", sign_filters_num);
202*f0865ec9SKyle Evans ret = -1;
203*f0865ec9SKyle Evans goto err;
204*f0865ec9SKyle Evans }
205*f0865ec9SKyle Evans sign_filters[sign_filters_num++] = argv[i]+sizeof("sign=")-1;
206*f0865ec9SKyle Evans found_filter = 1;
207*f0865ec9SKyle Evans break;
208*f0865ec9SKyle Evans }
209*f0865ec9SKyle Evans ret = are_equal(argv[i], "hash=", sizeof("hash=")-1, &check); EG(ret, err);
210*f0865ec9SKyle Evans if(check){
211*f0865ec9SKyle Evans if(hash_filters_num >= MAX_FILTERS){
212*f0865ec9SKyle Evans ext_printf("Maximum number of hash filters %d exceeded!\n", hash_filters_num);
213*f0865ec9SKyle Evans ret = -1;
214*f0865ec9SKyle Evans goto err;
215*f0865ec9SKyle Evans }
216*f0865ec9SKyle Evans hash_filters[hash_filters_num++] = argv[i]+sizeof("hash=")-1;
217*f0865ec9SKyle Evans found_filter = 1;
218*f0865ec9SKyle Evans break;
219*f0865ec9SKyle Evans }
220*f0865ec9SKyle Evans ret = are_equal(argv[i], "curve=", sizeof("curve=")-1, &check); EG(ret, err);
221*f0865ec9SKyle Evans if(check){
222*f0865ec9SKyle Evans if(curve_filters_num >= MAX_FILTERS){
223*f0865ec9SKyle Evans ext_printf("Maximum number of curve filters %d exceeded!\n", curve_filters_num);
224*f0865ec9SKyle Evans return -1;
225*f0865ec9SKyle Evans }
226*f0865ec9SKyle Evans curve_filters[curve_filters_num++] = argv[i]+sizeof("curve=")-1;
227*f0865ec9SKyle Evans found_filter = 1;
228*f0865ec9SKyle Evans break;
229*f0865ec9SKyle Evans }
230*f0865ec9SKyle Evans }
231*f0865ec9SKyle Evans if ((found == 0) && (found_filter == 0)) {
232*f0865ec9SKyle Evans print_help(argv[i]);
233*f0865ec9SKyle Evans ret = -1;
234*f0865ec9SKyle Evans goto err;
235*f0865ec9SKyle Evans }
236*f0865ec9SKyle Evans }
237*f0865ec9SKyle Evans if (found_ops == 0) {
238*f0865ec9SKyle Evans if(found_filter == 0){
239*f0865ec9SKyle Evans ext_printf("Error: no operation asked ...\n");
240*f0865ec9SKyle Evans print_help(NULL);
241*f0865ec9SKyle Evans ret = -1;
242*f0865ec9SKyle Evans goto err;
243*f0865ec9SKyle Evans }
244*f0865ec9SKyle Evans }
245*f0865ec9SKyle Evans else{
246*f0865ec9SKyle Evans tests_to_do = 0;
247*f0865ec9SKyle Evans for (i = 1; i < argc; i++) {
248*f0865ec9SKyle Evans for (j = 0;
249*f0865ec9SKyle Evans j < (int)(sizeof(test_types) / sizeof(test_type));
250*f0865ec9SKyle Evans j++) {
251*f0865ec9SKyle Evans ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);
252*f0865ec9SKyle Evans ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);
253*f0865ec9SKyle Evans if (check){
254*f0865ec9SKyle Evans tests_to_do |= test_types[j].type_mask;
255*f0865ec9SKyle Evans }
256*f0865ec9SKyle Evans }
257*f0865ec9SKyle Evans }
258*f0865ec9SKyle Evans }
259*f0865ec9SKyle Evans }
260*f0865ec9SKyle Evans /* If we do not have filters, we put NULL to tell that we do not filter */
261*f0865ec9SKyle Evans if(sign_filters_num == 0){
262*f0865ec9SKyle Evans sign_filters_num = 1;
263*f0865ec9SKyle Evans sign_filters[0] = NULL;
264*f0865ec9SKyle Evans }
265*f0865ec9SKyle Evans if(hash_filters_num == 0){
266*f0865ec9SKyle Evans hash_filters_num = 1;
267*f0865ec9SKyle Evans hash_filters[0] = NULL;
268*f0865ec9SKyle Evans }
269*f0865ec9SKyle Evans if(curve_filters_num == 0){
270*f0865ec9SKyle Evans curve_filters_num = 1;
271*f0865ec9SKyle Evans curve_filters[0] = NULL;
272*f0865ec9SKyle Evans }
273*f0865ec9SKyle Evans for(i = 0; i < sign_filters_num; i++){
274*f0865ec9SKyle Evans for(j = 0; j < hash_filters_num; j++){
275*f0865ec9SKyle Evans for(k = 0; k < curve_filters_num; k++){
276*f0865ec9SKyle Evans if(perform_tests(tests_to_do, sign_filters[i], hash_filters[j], curve_filters[k])){
277*f0865ec9SKyle Evans const char *curr_sign_filters = sign_filters[i];
278*f0865ec9SKyle Evans const char *curr_hash_filters = hash_filters[j];
279*f0865ec9SKyle Evans const char *curr_curve_filters = curve_filters[k];
280*f0865ec9SKyle Evans const char *all = "all";
281*f0865ec9SKyle Evans if(curr_sign_filters == NULL){
282*f0865ec9SKyle Evans curr_sign_filters = all;
283*f0865ec9SKyle Evans }
284*f0865ec9SKyle Evans if(curr_hash_filters == NULL){
285*f0865ec9SKyle Evans curr_hash_filters = all;
286*f0865ec9SKyle Evans }
287*f0865ec9SKyle Evans if(curr_curve_filters == NULL){
288*f0865ec9SKyle Evans curr_curve_filters = all;
289*f0865ec9SKyle Evans }
290*f0865ec9SKyle Evans ext_printf("Test for sign=%s/hash=%s/curve=%s failed!\n", curr_sign_filters, curr_hash_filters, curr_curve_filters);
291*f0865ec9SKyle Evans ret = -1;
292*f0865ec9SKyle Evans goto err;
293*f0865ec9SKyle Evans }
294*f0865ec9SKyle Evans }
295*f0865ec9SKyle Evans }
296*f0865ec9SKyle Evans }
297*f0865ec9SKyle Evans
298*f0865ec9SKyle Evans ret = 0;
299*f0865ec9SKyle Evans
300*f0865ec9SKyle Evans err:
301*f0865ec9SKyle Evans return ret;
302*f0865ec9SKyle Evans }
303