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