Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/libecc/src/tests/ec_self_tests.c
34869 views
1
/*
2
* Copyright (C) 2017 - This file is part of libecc project
3
*
4
* Authors:
5
* Ryad BENADJILA <[email protected]>
6
* Arnaud EBALARD <[email protected]>
7
* Jean-Pierre FLORI <[email protected]>
8
*
9
* Contributors:
10
* Nicolas VIVET <[email protected]>
11
* Karim KHALFALLAH <[email protected]>
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
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
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
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
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
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
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
304