#include <libecc/external_deps/print.h>
#include <libecc/utils/utils.h>
#include <libecc/libsig.h>
extern ATTRIBUTE_WARN_UNUSED_RET int perform_known_test_vectors_test(const char *sig, const char *hash, const char *curve);
extern ATTRIBUTE_WARN_UNUSED_RET int perform_random_sig_verif_test(const char *sig, const char *hash, const char *curve);
extern ATTRIBUTE_WARN_UNUSED_RET int perform_performance_test(const char *sig, const char *hash, const char *curve);
#define KNOWN_TEST_VECTORS (1)
#define RANDOM_SIG_VERIF (1 << 2)
#define PERFORMANCE (1 << 3)
typedef struct {
const char *type_name;
const char *type_help;
unsigned int type_mask;
} test_type;
static const test_type test_types[] = {
{
.type_name = "vectors",
.type_help = "Perform known test vectors",
.type_mask = KNOWN_TEST_VECTORS,
},
{
.type_name = "rand",
.type_help = "Perform random sign/verify tests",
.type_mask = RANDOM_SIG_VERIF,
},
{
.type_name = "perf",
.type_help = "Performance tests",
.type_mask = PERFORMANCE,
},
};
ATTRIBUTE_WARN_UNUSED_RET static int perform_tests(unsigned int tests, const char *sig, const char *hash, const char *curve)
{
if (tests & KNOWN_TEST_VECTORS) {
if (perform_known_test_vectors_test(sig, hash, curve)) {
goto err;
}
}
if (tests & RANDOM_SIG_VERIF) {
if (perform_random_sig_verif_test(sig, hash, curve)) {
goto err;
}
}
if (tests & PERFORMANCE) {
if (perform_performance_test(sig, hash, curve)) {
goto err;
}
}
return 0;
err:
return -1;
}
static void print_curves(void)
{
u8 i;
for (i = 0; i < EC_CURVES_NUM; i++) {
ext_printf("%s ", (const char *)(ec_maps[i].params->name->buf));
}
return;
}
static void print_hash_algs(void)
{
int i;
for (i = 0; hash_maps[i].type != UNKNOWN_HASH_ALG; i++) {
ext_printf("%s ", hash_maps[i].name);
}
return;
}
static void print_sig_algs(void)
{
int i;
for (i = 0; ec_sig_maps[i].type != UNKNOWN_ALG; i++) {
ext_printf("%s ", ec_sig_maps[i].name);
}
return;
}
static void print_help(const char *bad_arg)
{
int j;
if(bad_arg != NULL){
ext_printf("Argument %s is unknown. Possible args are:\n", bad_arg);
}
for (j = 0; j < (int)(sizeof(test_types) / sizeof(test_type)); j++) {
ext_printf("\t%20s:\t%s\n", test_types[j].type_name,
test_types[j].type_help);
}
ext_printf("-------------------\n");
ext_printf("NOTE: you can filter signatures with 'sign=', hash algorithms with 'hash=', curves with 'curve='\n");
ext_printf("\tExample: sign=ECDSA hash=SHA256 hash=SHA512 curve=FRP256V1\n");
ext_printf("\tPossible signatures: ");
print_sig_algs();
ext_printf("\n\tPossible hash algorithms: ");
print_hash_algs();
ext_printf("\n\tPossible curves: ");
print_curves();
ext_printf("\n");
}
#if defined(USE_SMALL_STACK)
#define MAX_FILTERS 1
#else
#define MAX_FILTERS 100
#endif
#ifdef __cplusplus
extern "C" {
int main(int argc, char *argv[]);
}
#endif
int main(int argc, char *argv[])
{
int ret;
unsigned int tests_to_do;
const char *sign_filters[MAX_FILTERS] = { NULL };
const char *hash_filters[MAX_FILTERS] = { NULL };
const char *curve_filters[MAX_FILTERS] = { NULL };
int sign_filters_num = 0, hash_filters_num = 0, curve_filters_num = 0;
int i, j, k;
tests_to_do = KNOWN_TEST_VECTORS | RANDOM_SIG_VERIF | PERFORMANCE;
if(MAX_FILTERS < 1){
ext_printf("Error: MAX_FILTERS too small\n");
ret = -1;
goto err;
}
if (argc > 1) {
unsigned char found = 0, found_filter = 0;
unsigned int found_ops = 0;
int check;
u32 len;
for (i = 1; i < argc; i++) {
found = found_filter = 0;
for (j = 0;
j < (int)(sizeof(test_types) / sizeof(test_type));
j++) {
ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);
ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);
if (check) {
found_ops++;
found = 1;
break;
}
ret = are_equal(argv[i], "sign=", sizeof("sign=")-1, &check); EG(ret, err);
if(check){
if(sign_filters_num >= MAX_FILTERS){
ext_printf("Maximum number of sign filters %d exceeded!\n", sign_filters_num);
ret = -1;
goto err;
}
sign_filters[sign_filters_num++] = argv[i]+sizeof("sign=")-1;
found_filter = 1;
break;
}
ret = are_equal(argv[i], "hash=", sizeof("hash=")-1, &check); EG(ret, err);
if(check){
if(hash_filters_num >= MAX_FILTERS){
ext_printf("Maximum number of hash filters %d exceeded!\n", hash_filters_num);
ret = -1;
goto err;
}
hash_filters[hash_filters_num++] = argv[i]+sizeof("hash=")-1;
found_filter = 1;
break;
}
ret = are_equal(argv[i], "curve=", sizeof("curve=")-1, &check); EG(ret, err);
if(check){
if(curve_filters_num >= MAX_FILTERS){
ext_printf("Maximum number of curve filters %d exceeded!\n", curve_filters_num);
return -1;
}
curve_filters[curve_filters_num++] = argv[i]+sizeof("curve=")-1;
found_filter = 1;
break;
}
}
if ((found == 0) && (found_filter == 0)) {
print_help(argv[i]);
ret = -1;
goto err;
}
}
if (found_ops == 0) {
if(found_filter == 0){
ext_printf("Error: no operation asked ...\n");
print_help(NULL);
ret = -1;
goto err;
}
}
else{
tests_to_do = 0;
for (i = 1; i < argc; i++) {
for (j = 0;
j < (int)(sizeof(test_types) / sizeof(test_type));
j++) {
ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);
ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);
if (check){
tests_to_do |= test_types[j].type_mask;
}
}
}
}
}
if(sign_filters_num == 0){
sign_filters_num = 1;
sign_filters[0] = NULL;
}
if(hash_filters_num == 0){
hash_filters_num = 1;
hash_filters[0] = NULL;
}
if(curve_filters_num == 0){
curve_filters_num = 1;
curve_filters[0] = NULL;
}
for(i = 0; i < sign_filters_num; i++){
for(j = 0; j < hash_filters_num; j++){
for(k = 0; k < curve_filters_num; k++){
if(perform_tests(tests_to_do, sign_filters[i], hash_filters[j], curve_filters[k])){
const char *curr_sign_filters = sign_filters[i];
const char *curr_hash_filters = hash_filters[j];
const char *curr_curve_filters = curve_filters[k];
const char *all = "all";
if(curr_sign_filters == NULL){
curr_sign_filters = all;
}
if(curr_hash_filters == NULL){
curr_hash_filters = all;
}
if(curr_curve_filters == NULL){
curr_curve_filters = all;
}
ext_printf("Test for sign=%s/hash=%s/curve=%s failed!\n", curr_sign_filters, curr_hash_filters, curr_curve_filters);
ret = -1;
goto err;
}
}
}
}
ret = 0;
err:
return ret;
}