Path: blob/main/crypto/libecc/src/wycheproof_tests/libecc_wycheproof.c
34889 views
/*1* Copyright (C) 2021 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6*7* This software is licensed under a dual BSD and GPL v2 license.8* See LICENSE file at the root folder of the project.9*/1011/*12* Source code for handling tests imported from the wycheproof project:13* https://github.com/google/wycheproof14*15* As this project primarily targets java cryptographic libraries, the16* json test files have been parsed to generate libecc friendly test cases.17*18* NOTE: we skip here all the tests related to ASN.1 format errors as libecc19* does not handle ASN.1 parsing at all. This explains the "skipped" tests from20* the wycheproof project.21*22*/23#include "libecc_wycheproof.h"2425/* Parallelize self tests? */26#ifdef WITH_OPENMP_SELF_TESTS27/* No openmp without stdlib ... */28#ifndef WITH_STDLIB29#error "Sorry: no possible self tests parallelization (OpenMP) without stdlib! Please use WITH_STDLIB"30#endif31#include <omp.h>32#include <stdlib.h>33static omp_lock_t global_lock;34static volatile u8 global_lock_initialized = 0;35#define OPENMP_LOCK() do { \36if(!global_lock_initialized){ \37omp_init_lock(&global_lock); \38global_lock_initialized = 1; \39} \40omp_set_lock(&global_lock); \41} while(0)42#define OPENMP_EG(ret, err) do { \43if(ret){ \44ext_printf("OpenMP abort following error ... %s:%d\n", __FILE__, __LINE__); \45exit(-1); \46} \47} while(0)48#define OPENMP_MUST_HAVE(cnd, ret, err) do { \49ret = !!(cnd); \50ret = -((~ret) & 1); \51OPENMP_EG(ret, err); \52} while(0)53#define OPENMP_UNLOCK() do { \54omp_unset_lock(&global_lock); \55} while(0)56#else57#define OPENMP_LOCK()58#define OPENMP_UNLOCK()59#define OPENMP_EG(ret, err) do { \60EG(ret, err); \61} while(0)62#define OPENMP_MUST_HAVE(cnd, ret, err) do { \63MUST_HAVE(cnd, ret, err); \64} while(0)65#endif6667#include "libecc_wycheproof_tests.h"6869/* Check all ECDSA test vectors */70static unsigned int ecdsa_acceptable_invalid = 0;71static unsigned int ecdsa_acceptable_valid = 0;72static unsigned int ecdsa_all_performed = 0;73static int check_wycheproof_ecdsa(void)74{75#if defined(WITH_SIG_ECDSA)76int ret;77unsigned int i;7879#ifdef WITH_OPENMP_SELF_TESTS80#pragma omp parallel81#pragma omp for schedule(static, 1) nowait82#endif83for(i = 0; i < NUM_WYCHEPROOF_ECDSA_TESTS; i++){84const wycheproof_ecdsa_test *t = wycheproof_ecdsa_all_tests[i];85ec_pub_key pub_key;86ec_params params;8788if (t == NULL){89continue;90}9192ecdsa_all_performed++;93ret = local_memset(&pub_key, 0, sizeof(pub_key)); OPENMP_EG(ret, err);94ret = local_memset(¶ms, 0, sizeof(params)); OPENMP_EG(ret, err);9596/* Import EC params from test case */97ret = import_params(¶ms, t->curve);98if (ret) {99ext_printf("Error: ECDSA tests error importing params\n");100ret = -1;101OPENMP_EG(ret, err);102}103104/* Import the public key */105ret = ec_pub_key_import_from_aff_buf(&pub_key, ¶ms, t->pubkey, (u8)(t->pubkeylen), t->sig_alg);106if (ret) {107ext_printf("Error: ECDSA tests error importing public key\n");108ret = -1;109OPENMP_EG(ret, err);110}111112113ret = ec_verify(t->sig, (u8)(t->siglen), &pub_key, t->msg, t->msglen, t->sig_alg, t->hash, NULL, 0);114/* Valid result */115if ((t->result == 1) && ret) {116ext_printf("[-] Error when verifying ECDSA test %d / %s (verification NOK while must be valid)\n", i, t->name);117ext_printf(" (comment = %s)\n", t->comment);118ret = -1;119OPENMP_EG(ret, err);120}121/* Invalid result */122if ((t->result == -1) && !ret) {123ext_printf("[-] Error when verifying ECDSA test %d / %s (verification OK while must be invalid)\n", i, t->name);124ext_printf(" (comment = %s)\n", t->comment);125ret = -1;126OPENMP_EG(ret, err);127}128/* Acceptable result: only trigger an informational warning */129if (t->result == 0) {130if(ret){131ecdsa_acceptable_valid++;132}133else{134ecdsa_acceptable_invalid++;135}136#ifdef VERBOSE_ACCEPTABLE137ext_printf("\t[~] ECDSA test %d / %s (verification %d while acceptable)\n", i, t->name, ret);138ext_printf("\t (comment = %s)\n", t->comment);139#endif140}141}142143ret = 0;144#ifndef WITH_OPENMP_SELF_TESTS145err:146#endif147return ret;148#else149return 0;150#endif151}152153/* Check all EDDSA test vectors */154static unsigned int eddsa_acceptable_invalid = 0;155static unsigned int eddsa_acceptable_valid = 0;156static unsigned int eddsa_all_performed = 0;157static int check_wycheproof_eddsa(void)158{159#if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)160int ret;161unsigned int i;162163#ifdef WITH_OPENMP_SELF_TESTS164#pragma omp parallel165#pragma omp for schedule(static, 1) nowait166#endif167for(i = 0; i < NUM_WYCHEPROOF_EDDSA_TESTS; i++){168const wycheproof_eddsa_test *t = wycheproof_eddsa_all_tests[i];169ec_pub_key pub_key;170ec_pub_key pub_key_check;171ec_priv_key priv_key;172ec_params params;173int check;174u8 exported_pub_key[EDDSA_MAX_PUB_KEY_ENCODED_LEN];175176if (t == NULL){177continue;178}179180OPENMP_LOCK();181eddsa_all_performed++;182OPENMP_UNLOCK();183ret = local_memset(&pub_key, 0, sizeof(pub_key)); OPENMP_EG(ret, err);184ret = local_memset(&priv_key, 0, sizeof(priv_key)); OPENMP_EG(ret, err);185ret = local_memset(¶ms, 0, sizeof(params)); OPENMP_EG(ret, err);186187/* Import EC params from test case */188ret = import_params(¶ms, t->curve);189if (ret) {190ext_printf("Error: EDDSA tests error importing params\n");191ret = -1;192OPENMP_EG(ret, err);193}194195/* Import the public key */196ret = eddsa_import_pub_key(&pub_key, t->pubkey, (u8)(t->pubkeylen), ¶ms, t->sig_alg);197if (ret) {198ext_printf("Error: EDDSA tests error importing public key\n");199ret = -1;200OPENMP_EG(ret, err);201}202/* Import the private key */203ret = eddsa_import_priv_key(&priv_key, t->privkey, (u8)(t->privkeylen), ¶ms, t->sig_alg);204if (ret) {205ext_printf("Error: EDDSA tests error importing private key\n");206ret = -1;207OPENMP_EG(ret, err);208}209/* Derive private to public */210ret = eddsa_init_pub_key(&pub_key_check, &priv_key);211if (ret) {212ext_printf("Error: EDDSA tests error deriving private to public key\n");213ret = -1;214OPENMP_EG(ret, err);215}216/* Check */217ret = eddsa_export_pub_key(&pub_key, exported_pub_key, (u8)(t->pubkeylen));218if(ret){219ext_printf("Error: EDDSA tests error when exporting public key\n");220ret = -1;221OPENMP_EG(ret, err);222}223/* */224ret = are_equal(t->pubkey, &exported_pub_key, (u8)(t->pubkeylen), &check); OPENMP_EG(ret, err);225if(!check){226ext_printf("Error: EDDSA tests error when checking public key from private\n");227ret = -1;228OPENMP_EG(ret, err);229}230231ret = ec_verify(t->sig, (u8)(t->siglen), &pub_key, t->msg, t->msglen, t->sig_alg, t->hash, NULL, 0);232/* Valid result */233if ((t->result == 1) && ret) {234ext_printf("[-] Error when verifying EDDSA test %d / %s (verification NOK while must be valid)\n", i, t->name);235ext_printf(" (comment = %s)\n", t->comment);236ret = -1;237OPENMP_EG(ret, err);238}239/* Invalid result */240if ((t->result == -1) && !ret) {241ext_printf("[-] Error when verifying EDDSA test %d / %s (verification OK while must be invalid)\n", i, t->name);242ext_printf(" (comment = %s)\n", t->comment);243ret = -1;244OPENMP_EG(ret, err);245}246/* Acceptable result: only trigger an informational warning */247if (t->result == 0) {248OPENMP_LOCK();249if(ret){250eddsa_acceptable_valid++;251}252else{253eddsa_acceptable_invalid++;254}255#ifdef VERBOSE_ACCEPTABLE256ext_printf("\t[~] EDDSA test %d / %s (verification %d while acceptable)\n", i, t->name, ret);257ext_printf("\t (comment = %s)\n", t->comment);258#endif259OPENMP_UNLOCK();260}261}262263ret = 0;264#ifndef WITH_OPENMP_SELF_TESTS265err:266#endif267return ret;268#else269return 0;270#endif271}272273/* Check all XDH test vectors */274static unsigned int xdh_acceptable_invalid = 0;275static unsigned int xdh_acceptable_valid = 0;276static unsigned int xdh_all_performed = 0;277static int check_wycheproof_xdh(void)278{279#if defined(WITH_X25519) || defined(WITH_X448)280int ret;281unsigned int i;282283#ifdef WITH_OPENMP_SELF_TESTS284#pragma omp parallel285#pragma omp for schedule(static, 1) nowait286#endif287for(i = 0; i < NUM_WYCHEPROOF_XDH_TESTS; i++){288int check;289const wycheproof_xdh_test *t = wycheproof_xdh_all_tests[i];290unsigned int alglen = 0;291/* Max size buffer */292u8 pubkey_check[X448_SIZE];293u8 sharedsecret_check[X448_SIZE];294295if (t == NULL){296continue;297}298299OPENMP_LOCK();300xdh_all_performed++;301OPENMP_UNLOCK();302303#if defined(WITH_X25519)304if(t->xdh_alg == X25519){305OPENMP_MUST_HAVE(((t->curve) == &wei25519_str_params), ret, err);306alglen = X25519_SIZE;307}308#endif309#if defined(WITH_X448)310if(t->xdh_alg == X448){311OPENMP_MUST_HAVE(((t->curve) == &wei448_str_params), ret, err);312alglen = X448_SIZE;313}314#endif315if(alglen == 0){316ext_printf("Error: XDH tests error, unkown algorithm\n");317ret = -1;318OPENMP_EG(ret, err);319}320/* Reject bad lengths */321if(t->privkeylen != alglen){322if(t->result != -1){323ext_printf("[-] Error: XDH tests error, unkown private key length %d with valid result\n", t->privkeylen);324ext_printf(" (comment = %s)\n", t->comment);325ret = -1;326OPENMP_EG(ret, err);327}328else{329continue;330}331}332if(t->peerpubkeylen != alglen){333if(t->result != -1){334ext_printf("[-] Error: XDH tests error, unkown peer public key length %d with valid result\n", t->peerpubkeylen);335ext_printf(" (comment = %s)\n", t->comment);336ret = -1;337OPENMP_EG(ret, err);338}339else{340continue;341}342}343if(t->sharedsecretlen != alglen){344if(t->result != -1){345ext_printf("[-] Error: XDH tests error, unkown shared secret length %d with valid result\n", t->sharedsecretlen);346ext_printf(" (comment = %s)\n", t->comment);347ret = -1;348OPENMP_EG(ret, err);349}350else{351continue;352}353}354if((t->ourpubkeylen != 0) && (t->ourpubkeylen != alglen)){355if(t->result != -1){356ext_printf("[-] Error: XDH tests error, unkown our public key length %d with valid result\n", t->ourpubkeylen);357ext_printf(" (comment = %s)\n", t->comment);358ret = -1;359OPENMP_EG(ret, err);360}361else{362continue;363}364}365#if defined(WITH_X25519)366if(t->xdh_alg == X25519){367/* Derive our public key */368ret = x25519_init_pub_key(t->privkey, pubkey_check);369if(ret){370ext_printf("[-] Error: XDH tests error when deriving private key to public\n");371ext_printf(" (comment = %s)\n", t->comment);372ret = -1;373OPENMP_EG(ret, err);374}375if(t->ourpubkeylen != 0){376/* Check public key against the test one */377ret = are_equal(t->ourpubkey, pubkey_check, alglen, &check); OPENMP_EG(ret, err);378if(!check){379ext_printf("[-] Error: XDH tests error when checking our public key\n");380ext_printf(" (comment = %s)\n", t->comment);381ret = -1;382OPENMP_EG(ret, err);383}384}385/* Derive the shared secret */386ret = x25519_derive_secret(t->privkey, t->peerpubkey, sharedsecret_check);387if(ret){388/* Handle "acceptable" results here (e.g. public key on twist) */389if(t->result == 0){390OPENMP_LOCK();391xdh_acceptable_invalid++;392#ifdef VERBOSE_ACCEPTABLE393ext_printf("\t[~] XDH test %d / %s (shared secret derivation NOK while acceptable)\n", i, t->name);394ext_printf("\t (comment = %s)\n", t->comment);395#endif396OPENMP_UNLOCK();397continue;398}399ext_printf("[-] Error: XDH tests error when deriving shared secret\n");400ext_printf(" (comment = %s)\n", t->comment);401ret = -1;402OPENMP_EG(ret, err);403}404if(t->result == -1){405ext_printf("[-] Error: XDH tests is OK while invalid\n");406ext_printf(" (comment = %s)\n", t->comment);407ret = -1;408OPENMP_EG(ret, err);409}410/* Check the shared secret */411ret = are_equal(t->sharedsecret, sharedsecret_check, alglen, &check); OPENMP_EG(ret, err);412if(!check){413ext_printf("[-] Error: XDH tests error when checking shared secret\n");414ext_printf(" (comment = %s)\n", t->comment);415ret = -1;416OPENMP_EG(ret, err);417}418}419#endif420#if defined(WITH_X448)421if(t->xdh_alg == X448){422/* Derive our public key */423ret = x448_init_pub_key(t->privkey, pubkey_check);424if(ret){425ext_printf("[-] Error: XDH tests error when deriving private key to public\n");426ext_printf(" (comment = %s)\n", t->comment);427ret = -1;428OPENMP_EG(ret, err);429}430if(t->ourpubkeylen != 0){431/* Check public key against the test one */432ret = are_equal(t->ourpubkey, pubkey_check, alglen, &check); OPENMP_EG(ret, err);433if(!check){434ext_printf("[-] Error: XDH tests error when checking our public key\n");435ext_printf(" (comment = %s)\n", t->comment);436ret = -1;437OPENMP_EG(ret, err);438}439}440/* Derive the shared secret */441ret = x448_derive_secret(t->privkey, t->peerpubkey, sharedsecret_check);442if(ret){443/* Handle "acceptable" results here (e.g. public key on twist) */444if(t->result == 0){445OPENMP_LOCK();446xdh_acceptable_invalid++;447#ifdef VERBOSE_ACCEPTABLE448ext_printf("\t[~] XDH test %d / %s (shared secret derivation NOK while acceptable)\n", i, t->name);449ext_printf("\t (comment = %s)\n", t->comment);450#endif451OPENMP_UNLOCK();452continue;453}454ext_printf("[-] Error: XDH tests error when deriving shared secret\n");455ext_printf(" (comment = %s)\n", t->comment);456OPENMP_EG(ret, err);457}458if(t->result == -1){459ext_printf("[-] Error: XDH tests is OK while invalid\n");460ext_printf(" (comment = %s)\n", t->comment);461ret = -1;462OPENMP_EG(ret, err);463}464/* Check the shared secret */465ret = are_equal(t->sharedsecret, sharedsecret_check, alglen, &check); OPENMP_EG(ret, err);466if(!check){467ext_printf("[-] Error: XDH tests error when checking shared secret\n");468ext_printf(" (comment = %s)\n", t->comment);469ret = -1;470OPENMP_EG(ret, err);471}472473}474#endif475/* Log the acceptable results */476if (t->result == 0) {477OPENMP_LOCK();478xdh_acceptable_valid++;479#ifdef VERBOSE_ACCEPTABLE480ext_printf("\t[~] XDH test %d / %s (shared secret OK while acceptable)\n", i, t->name);481ext_printf("\t (comment = %s)\n", t->comment);482#endif483OPENMP_UNLOCK();484}485}486ret = 0;487#ifndef WITH_OPENMP_SELF_TESTS488err:489#endif490return ret;491#else492return 0;493#endif494}495496/* Point decompression routine */497static int uncompress_ecc_point(const ec_params *params, const u8 *peerpubkey, u8 peerpubkeylen, u8 *serialized_pub_key, u8 serialized_pub_key_size, int compression)498{499int ret, sign, check;500fp x, tmp;501fp_t y;502x.magic = tmp.magic = 0;503504MUST_HAVE((params != NULL) && (peerpubkey != NULL) && (serialized_pub_key != NULL), ret, err);505506/* Uncompressed point size should be twice the x coordinate */507MUST_HAVE((serialized_pub_key_size == (2 * peerpubkeylen)), ret, err);508509/* Compression is either 02 or 03 */510MUST_HAVE(((compression == 0x02) || (compression == 0x03)), ret, err);511512/* Import our x coordinate */513ret = fp_init_from_buf(&x, &(params->ec_fp), peerpubkey, peerpubkeylen); EG(ret, err);514ret = fp_init(&tmp, &(params->ec_fp)); EG(ret, err);515/* Compute the Weierstrass equation y^2 = x^3 + ax + b solutions */516ret = aff_pt_y_from_x(&tmp, &x, &x, &(params->ec_curve)); EG(ret, err);517518/* Choose the square root depending on the compression information */519sign = (compression - 2);520521ret = fp_cmp(&x, &tmp, &check); EG(ret, err);522523y = ((check > 0) == sign) ? &x : &tmp;524525/* Export the point to our buffer */526ret = local_memcpy(&serialized_pub_key[0], &peerpubkey[0], (serialized_pub_key_size / 2)); EG(ret, err);527ret = fp_export_to_buf(&serialized_pub_key[(serialized_pub_key_size / 2)], (serialized_pub_key_size / 2), y);528529err:530fp_uninit(&x);531fp_uninit(&tmp);532PTR_NULLIFY(y);533534return ret;535}536537/* Check all ECDH test vectors */538static unsigned int ecdh_acceptable_invalid = 0;539static unsigned int ecdh_acceptable_valid = 0;540static unsigned int ecdh_all_performed = 0;541static int check_wycheproof_ecdh(void)542{543#if defined(WITH_ECCCDH)544int ret;545unsigned int i;546547#ifdef WITH_OPENMP_SELF_TESTS548#pragma omp parallel549#pragma omp for schedule(static, 1) nowait550#endif551for(i = 0; i < NUM_WYCHEPROOF_ECDH_TESTS; i++){552int check;553const wycheproof_ecdh_test *t = wycheproof_ecdh_all_tests[i];554ec_pub_key peerpub_key;555ec_pub_key ourpub_key;556ec_pub_key ourpub_key_check;557ec_priv_key priv_key;558ec_params params;559u8 sharedsecret_check[EC_PRIV_KEY_MAX_SIZE];560u8 sharedsecretsize;561u8 serialized_pub_key[EC_PUB_KEY_MAX_SIZE];562u8 serialized_pub_key_check[EC_PUB_KEY_MAX_SIZE];563u8 serialized_pub_key_size;564565if (t == NULL){566continue;567}568569OPENMP_LOCK();570ecdh_all_performed++;571OPENMP_UNLOCK();572573ret = local_memset(&peerpub_key, 0, sizeof(peerpub_key)); OPENMP_EG(ret, err);574ret = local_memset(&ourpub_key, 0, sizeof(ourpub_key)); OPENMP_EG(ret, err);575ret = local_memset(&ourpub_key_check, 0, sizeof(ourpub_key_check)); OPENMP_EG(ret, err);576ret = local_memset(&priv_key, 0, sizeof(priv_key)); OPENMP_EG(ret, err);577ret = local_memset(¶ms, 0, sizeof(params)); OPENMP_EG(ret, err);578ret = local_memset(sharedsecret_check, 0, sizeof(sharedsecret_check)); OPENMP_EG(ret, err);579ret = local_memset(serialized_pub_key, 0, sizeof(serialized_pub_key)); OPENMP_EG(ret, err);580581/* Import EC params from test case */582ret = import_params(¶ms, t->curve);583if (ret) {584ext_printf("Error: ECDH tests error importing params\n");585ret = -1;586OPENMP_EG(ret, err);587}588589/* Get the sizes */590ret = ecccdh_shared_secret_size(¶ms, &sharedsecretsize);591if (ret) {592ext_printf("Error: ECDH tests error getting shared secret size\n");593ret = -1;594OPENMP_EG(ret, err);595}596OPENMP_MUST_HAVE((sharedsecretsize <= sizeof(sharedsecret_check)), ret, err);597ret = ecccdh_serialized_pub_key_size(¶ms, &serialized_pub_key_size);598if (ret) {599ext_printf("Error: ECDH tests error getting serialized public key size\n");600ret = -1;601OPENMP_EG(ret, err);602}603OPENMP_MUST_HAVE((serialized_pub_key_size <= sizeof(serialized_pub_key)), ret, err);604OPENMP_MUST_HAVE((serialized_pub_key_size <= sizeof(serialized_pub_key_check)), ret, err);605606/* Import the private key */607ret = ec_priv_key_import_from_buf(&priv_key, ¶ms, t->privkey, (u8)(t->privkeylen), t->ecdh_alg);608if (ret) {609ext_printf("Error: ECDH tests error importing private key\n");610ret = -1;611OPENMP_EG(ret, err);612}613614if(t->ourpubkeylen != 0){615/* Import our public key if it exists */616ret = ec_pub_key_import_from_aff_buf(&ourpub_key, ¶ms, t->ourpubkey, (u8)(t->ourpubkeylen), t->ecdh_alg);617if (ret && (t->result >= 0)) {618ext_printf("[-] Error: ECDH tests error when importing our public key\n");619ext_printf(" (comment = %s)\n", t->comment);620ret = -1;621OPENMP_EG(ret, err);622}623/* Derive our private key to public */624ret = ecccdh_init_pub_key(&ourpub_key_check, &priv_key);625if (ret) {626ext_printf("Error: ECDH tests error deriving our private key to public\n");627ret = -1;628OPENMP_EG(ret, err);629}630/* Check if we get the same public key by serializing them */631ret = ecccdh_serialize_pub_key(&ourpub_key, serialized_pub_key, serialized_pub_key_size);632if (ret){633ext_printf("Error: ECDH tests error serializing public key\n");634ret = -1;635OPENMP_EG(ret, err);636}637ret = ecccdh_serialize_pub_key(&ourpub_key_check, serialized_pub_key_check, serialized_pub_key_size);638if (ret){639ext_printf("Error: ECDH tests error serializing public key\n");640ret = -1;641OPENMP_EG(ret, err);642}643ret = are_equal(serialized_pub_key, serialized_pub_key_check, serialized_pub_key_size, &check); OPENMP_EG(ret, err);644if(!check){645ext_printf("[-] Error: ECDH tests error when checking our public key\n");646ext_printf(" (comment = %s)\n", t->comment);647ret = -1;648OPENMP_EG(ret, err);649}650}651652/* Do we have to uncompress our point? */653if(t->compressed > 0){654/* Uncompress the point */655ret = uncompress_ecc_point(¶ms, t->peerpubkey, (u8)(t->peerpubkeylen), serialized_pub_key, serialized_pub_key_size, t->compressed);656if ((ret) && (t->result >= 0)) {657ext_printf("[-] Error: ECDH tests error when uncompressing public key\n");658ext_printf(" (comment = %s)\n", t->comment);659ret = -1;660OPENMP_EG(ret, err);661}662}663else{664/* No point compression is used, copy our raw buffer as public key */665if((t->peerpubkeylen != serialized_pub_key_size) && (t->result >= 0)){666ext_printf("[-] Error: ECDH tests error when checking our public key size, got %d instead of %d\n", t->peerpubkeylen, serialized_pub_key_size);667ext_printf(" (comment = %s)\n", t->comment);668ret = -1;669OPENMP_EG(ret, err);670}671ret = local_memcpy(serialized_pub_key, t->peerpubkey, serialized_pub_key_size); OPENMP_EG(ret, err);672}673/* Now derive the shared secret */674ret = ecccdh_derive_secret(&priv_key, serialized_pub_key, serialized_pub_key_size, sharedsecret_check, sharedsecretsize);675if ((ret) && (t->result >= 0)) {676ext_printf("[-] Error: ECDH tests error when deriving secret while acceptable or valid\n");677ext_printf(" (comment = %s)\n", t->comment);678ret = -1;679OPENMP_EG(ret, err);680}681if((!ret) && (t->result == -1)){682ext_printf("Error: ECDH tests error, secret derived OK while invalid\n");683ext_printf(" (comment = %s)\n", t->comment);684ret = -1;685OPENMP_EG(ret, err);686}687if(t->result == -1){688continue;689}690if(sharedsecretsize != t->sharedsecretlen){691ext_printf("Error: ECDH tests error, bad shared secret size %d instead of %d\n", sharedsecretsize, t->sharedsecretlen);692ext_printf(" (comment = %s)\n", t->comment);693ret = -1;694OPENMP_EG(ret, err);695}696/* Compare */697ret = are_equal(sharedsecret_check, t->sharedsecret, sharedsecretsize, &check); OPENMP_EG(ret, err);698if(!check){699ext_printf("[-] Error: ECDH tests error when checking the computed shared secret, they differ\n");700ext_printf(" (comment = %s)\n", t->comment);701ret = -1;702OPENMP_EG(ret, err);703}704/* Log the acceptable results */705if (t->result == 0) {706OPENMP_LOCK();707ecdh_acceptable_valid++;708#ifdef VERBOSE_ACCEPTABLE709ext_printf("\t[~] ECDH test %d / %s (shared secret OK while acceptable)\n", i, t->name);710ext_printf("\t (comment = %s)\n", t->comment);711#endif712OPENMP_UNLOCK();713}714715}716ret = 0;717#ifndef WITH_OPENMP_SELF_TESTS718err:719#endif720return ret;721#else722return 0;723#endif724}725726/* Check all HMAC test vectors */727static unsigned int hmac_acceptable_invalid = 0;728static unsigned int hmac_acceptable_valid = 0;729static unsigned int hmac_all_performed = 0;730static int check_wycheproof_hmac(void)731{732#if defined(WITH_HMAC)733int ret;734unsigned int i;735736#ifdef WITH_OPENMP_SELF_TESTS737#pragma omp parallel738#pragma omp for schedule(static, 1) nowait739#endif740for(i = 0; i < NUM_WYCHEPROOF_HMAC_TESTS; i++){741int check;742const wycheproof_hmac_test *t = wycheproof_hmac_all_tests[i];743u8 hmac_res[MAX_DIGEST_SIZE];744u8 hlen;745746if (t == NULL){747continue;748}749750OPENMP_LOCK();751hmac_all_performed++;752OPENMP_UNLOCK();753754ret = local_memset(&hmac_res, 0, sizeof(hmac_res)); OPENMP_EG(ret, err);755756hlen = sizeof(hmac_res);757ret = hmac(t->key, t->keylen, t->hash, t->msg, t->msglen, hmac_res, &hlen);758if (ret) {759ext_printf("[-] Error: HMAC tests error when performin HMAC\n");760ext_printf(" (comment = %s)\n", t->comment);761ret = -1;762OPENMP_EG(ret, err);763}764if((hlen < t->taglen) && (t->result >= 0)){765ext_printf("[-] Error: HMAC tests error: size error %d < %d\n", hlen, t->taglen);766ext_printf(" (comment = %s)\n", t->comment);767ret = -1;768OPENMP_EG(ret, err);769}770/* Compare */771ret = are_equal(hmac_res, t->tag, t->taglen, &check); OPENMP_EG(ret, err);772if((!check) && (t->result >= 0)){773ext_printf("[-] Error: HMAC tests error when checking the computed tag, they differ\n");774ext_printf(" (comment = %s)\n", t->comment);775ret = -1;776OPENMP_EG(ret, err);777}778/* Log the acceptable results */779if (t->result == 0) {780OPENMP_LOCK();781hmac_acceptable_valid++;782#ifdef VERBOSE_ACCEPTABLE783ext_printf("\t[~] HMAC test %d / %s (shared secret OK while acceptable)\n", i, t->name);784ext_printf("\t (comment = %s)\n", t->comment);785#endif786OPENMP_UNLOCK();787}788}789ret = 0;790#ifndef WITH_OPENMP_SELF_TESTS791err:792#endif793return ret;794#else795return 0;796#endif797}798799int main(int argc, char *argv[])800{801FORCE_USED_VAR(argc);802FORCE_USED_VAR(argv);803804/**********************/805ext_printf("==== Checking ECDH =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_ECDH_TESTS_IMPORTED, NUM_WYCHEPROOF_ECDH_TESTS_SKIPPED, NUM_WYCHEPROOF_ECDH_TESTS_VALID, NUM_WYCHEPROOF_ECDH_TESTS_INVALID, NUM_WYCHEPROOF_ECDH_TESTS_ACCEPTABLE);806if(check_wycheproof_ecdh()){807goto err;808}809ext_printf("[+][%d] All ECDH tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", ecdh_all_performed, ecdh_acceptable_valid, ecdh_acceptable_invalid);810/**********************/811ext_printf("==== Checking XDH =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_XDH_TESTS_IMPORTED, NUM_WYCHEPROOF_XDH_TESTS_SKIPPED, NUM_WYCHEPROOF_XDH_TESTS_VALID, NUM_WYCHEPROOF_XDH_TESTS_INVALID, NUM_WYCHEPROOF_XDH_TESTS_ACCEPTABLE);812if(check_wycheproof_xdh()){813goto err;814}815ext_printf("[+][%d] All XDH tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", xdh_all_performed, xdh_acceptable_valid, xdh_acceptable_invalid);816/**********************/817ext_printf("==== Checking ECDSA =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_ECDSA_TESTS_IMPORTED, NUM_WYCHEPROOF_ECDSA_TESTS_SKIPPED, NUM_WYCHEPROOF_ECDSA_TESTS_VALID, NUM_WYCHEPROOF_ECDSA_TESTS_INVALID, NUM_WYCHEPROOF_ECDSA_TESTS_ACCEPTABLE);818if(check_wycheproof_ecdsa()){819goto err;820}821ext_printf("[+][%d] All ECDSA tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", ecdsa_all_performed, ecdsa_acceptable_valid, ecdsa_acceptable_invalid);822/**********************/823ext_printf("==== Checking EDDSA =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_EDDSA_TESTS_IMPORTED, NUM_WYCHEPROOF_EDDSA_TESTS_SKIPPED, NUM_WYCHEPROOF_EDDSA_TESTS_VALID, NUM_WYCHEPROOF_EDDSA_TESTS_INVALID, NUM_WYCHEPROOF_EDDSA_TESTS_ACCEPTABLE);824if(check_wycheproof_eddsa()){825goto err;826}827ext_printf("[+][%d] All EDDSA tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", eddsa_all_performed, eddsa_acceptable_valid, eddsa_acceptable_invalid);828/**********************/829ext_printf("==== Checking HMAC =========== Imported = %d, Skipped = %d (valid = %d, invalid = %d, acceptable = %d)\n", NUM_WYCHEPROOF_HMAC_TESTS_IMPORTED, NUM_WYCHEPROOF_HMAC_TESTS_SKIPPED, NUM_WYCHEPROOF_HMAC_TESTS_VALID, NUM_WYCHEPROOF_HMAC_TESTS_INVALID, NUM_WYCHEPROOF_HMAC_TESTS_ACCEPTABLE);830if(check_wycheproof_hmac()){831goto err;832}833ext_printf("[+][%d] All HMAC tests went OK! (%d acceptable/valid, %d acceptable/invalid)\n", hmac_all_performed, hmac_acceptable_valid, hmac_acceptable_invalid);834835err:836return 0;837}838839840