Path: blob/main/crypto/libecc/src/tests/ec_self_tests.c
34869 views
/*1* Copyright (C) 2017 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6* Jean-Pierre FLORI <[email protected]>7*8* Contributors:9* Nicolas VIVET <[email protected]>10* Karim KHALFALLAH <[email protected]>11*12* This software is licensed under a dual BSD and GPL v2 license.13* See LICENSE file at the root folder of the project.14*/15#include <libecc/external_deps/print.h>16#include <libecc/utils/utils.h>17#include <libecc/libsig.h>1819/*20* Use extern declarations to avoid including21* ec_self_tests_core.h, which has all fixed22* test vectors definitions. We only need the23* three functions below.24*/25extern ATTRIBUTE_WARN_UNUSED_RET int perform_known_test_vectors_test(const char *sig, const char *hash, const char *curve);26extern ATTRIBUTE_WARN_UNUSED_RET int perform_random_sig_verif_test(const char *sig, const char *hash, const char *curve);27extern ATTRIBUTE_WARN_UNUSED_RET int perform_performance_test(const char *sig, const char *hash, const char *curve);2829/* Tests kinds */30#define KNOWN_TEST_VECTORS (1)31#define RANDOM_SIG_VERIF (1 << 2)32#define PERFORMANCE (1 << 3)3334typedef struct {35const char *type_name;36const char *type_help;37unsigned int type_mask;38} test_type;3940static const test_type test_types[] = {41{42.type_name = "vectors",43.type_help = "Perform known test vectors",44.type_mask = KNOWN_TEST_VECTORS,45},46{47.type_name = "rand",48.type_help = "Perform random sign/verify tests",49.type_mask = RANDOM_SIG_VERIF,50},51{52.type_name = "perf",53.type_help = "Performance tests",54.type_mask = PERFORMANCE,55},56};5758ATTRIBUTE_WARN_UNUSED_RET static int perform_tests(unsigned int tests, const char *sig, const char *hash, const char *curve)59{60/* KNOWN_TEST_VECTORS tests */61if (tests & KNOWN_TEST_VECTORS) {62if (perform_known_test_vectors_test(sig, hash, curve)) {63goto err;64}65}66/* RANDOM_SIG_VERIF tests */67if (tests & RANDOM_SIG_VERIF) {68if (perform_random_sig_verif_test(sig, hash, curve)) {69goto err;70}71}72/* PERFORMANCE tests */73if (tests & PERFORMANCE) {74if (perform_performance_test(sig, hash, curve)) {75goto err;76}77}7879return 0;8081err:82return -1;83}8485static void print_curves(void)86{87u8 i;8889/* Print all the available curves */90for (i = 0; i < EC_CURVES_NUM; i++) {91ext_printf("%s ", (const char *)(ec_maps[i].params->name->buf));92}9394return;95}9697static void print_hash_algs(void)98{99int i;100101/* Print all the available hash functions */102for (i = 0; hash_maps[i].type != UNKNOWN_HASH_ALG; i++) {103ext_printf("%s ", hash_maps[i].name);104}105106return;107}108109static void print_sig_algs(void)110{111int i;112113/* Print all the available signature schemes */114for (i = 0; ec_sig_maps[i].type != UNKNOWN_ALG; i++) {115ext_printf("%s ", ec_sig_maps[i].name);116}117118return;119}120121static void print_help(const char *bad_arg)122{123int j;124if(bad_arg != NULL){125ext_printf("Argument %s is unknown. Possible args are:\n", bad_arg);126}127for (j = 0; j < (int)(sizeof(test_types) / sizeof(test_type)); j++) {128ext_printf("\t%20s:\t%s\n", test_types[j].type_name,129test_types[j].type_help);130}131ext_printf("-------------------\n");132ext_printf("NOTE: you can filter signatures with 'sign=', hash algorithms with 'hash=', curves with 'curve='\n");133ext_printf("\tExample: sign=ECDSA hash=SHA256 hash=SHA512 curve=FRP256V1\n");134ext_printf("\tPossible signatures: ");135print_sig_algs();136ext_printf("\n\tPossible hash algorithms: ");137print_hash_algs();138ext_printf("\n\tPossible curves: ");139print_curves();140ext_printf("\n");141}142143#if defined(USE_SMALL_STACK)144#define MAX_FILTERS 1145#else146#define MAX_FILTERS 100147#endif148149#ifdef __cplusplus150/* In case of a C++ compiler, preserve our "main"151* linkage.152*/153extern "C" {154int main(int argc, char *argv[]);155}156#endif157158int main(int argc, char *argv[])159{160int ret;161unsigned int tests_to_do;162const char *sign_filters[MAX_FILTERS] = { NULL };163const char *hash_filters[MAX_FILTERS] = { NULL };164const char *curve_filters[MAX_FILTERS] = { NULL };165int sign_filters_num = 0, hash_filters_num = 0, curve_filters_num = 0;166int i, j, k;167168/* By default, perform all tests */169tests_to_do = KNOWN_TEST_VECTORS | RANDOM_SIG_VERIF | PERFORMANCE;170171/* Sanity check */172if(MAX_FILTERS < 1){173ext_printf("Error: MAX_FILTERS too small\n");174ret = -1;175goto err;176}177178/* If we have one or more arguments, only perform specific test */179if (argc > 1) {180unsigned char found = 0, found_filter = 0;181unsigned int found_ops = 0;182int check;183u32 len;184/* Check of the args */185for (i = 1; i < argc; i++) {186found = found_filter = 0;187for (j = 0;188j < (int)(sizeof(test_types) / sizeof(test_type));189j++) {190ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);191ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);192if (check) {193found_ops++;194found = 1;195break;196}197ret = are_equal(argv[i], "sign=", sizeof("sign=")-1, &check); EG(ret, err);198if(check){199if(sign_filters_num >= MAX_FILTERS){200ext_printf("Maximum number of sign filters %d exceeded!\n", sign_filters_num);201ret = -1;202goto err;203}204sign_filters[sign_filters_num++] = argv[i]+sizeof("sign=")-1;205found_filter = 1;206break;207}208ret = are_equal(argv[i], "hash=", sizeof("hash=")-1, &check); EG(ret, err);209if(check){210if(hash_filters_num >= MAX_FILTERS){211ext_printf("Maximum number of hash filters %d exceeded!\n", hash_filters_num);212ret = -1;213goto err;214}215hash_filters[hash_filters_num++] = argv[i]+sizeof("hash=")-1;216found_filter = 1;217break;218}219ret = are_equal(argv[i], "curve=", sizeof("curve=")-1, &check); EG(ret, err);220if(check){221if(curve_filters_num >= MAX_FILTERS){222ext_printf("Maximum number of curve filters %d exceeded!\n", curve_filters_num);223return -1;224}225curve_filters[curve_filters_num++] = argv[i]+sizeof("curve=")-1;226found_filter = 1;227break;228}229}230if ((found == 0) && (found_filter == 0)) {231print_help(argv[i]);232ret = -1;233goto err;234}235}236if (found_ops == 0) {237if(found_filter == 0){238ext_printf("Error: no operation asked ...\n");239print_help(NULL);240ret = -1;241goto err;242}243}244else{245tests_to_do = 0;246for (i = 1; i < argc; i++) {247for (j = 0;248j < (int)(sizeof(test_types) / sizeof(test_type));249j++) {250ret = local_strlen(test_types[j].type_name, &len); EG(ret, err);251ret = are_equal(argv[i], test_types[j].type_name, len + 1, &check); EG(ret, err);252if (check){253tests_to_do |= test_types[j].type_mask;254}255}256}257}258}259/* If we do not have filters, we put NULL to tell that we do not filter */260if(sign_filters_num == 0){261sign_filters_num = 1;262sign_filters[0] = NULL;263}264if(hash_filters_num == 0){265hash_filters_num = 1;266hash_filters[0] = NULL;267}268if(curve_filters_num == 0){269curve_filters_num = 1;270curve_filters[0] = NULL;271}272for(i = 0; i < sign_filters_num; i++){273for(j = 0; j < hash_filters_num; j++){274for(k = 0; k < curve_filters_num; k++){275if(perform_tests(tests_to_do, sign_filters[i], hash_filters[j], curve_filters[k])){276const char *curr_sign_filters = sign_filters[i];277const char *curr_hash_filters = hash_filters[j];278const char *curr_curve_filters = curve_filters[k];279const char *all = "all";280if(curr_sign_filters == NULL){281curr_sign_filters = all;282}283if(curr_hash_filters == NULL){284curr_hash_filters = all;285}286if(curr_curve_filters == NULL){287curr_curve_filters = all;288}289ext_printf("Test for sign=%s/hash=%s/curve=%s failed!\n", curr_sign_filters, curr_hash_filters, curr_curve_filters);290ret = -1;291goto err;292}293}294}295}296297ret = 0;298299err:300return ret;301}302303304