X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=test_ciphers.c;h=60384988e40f43a012ea93768ae5fbf887af18b6;hb=c6655a0b620a3e31f085cc906f8073fe81b2fad3;hp=95e3e993afba9a3af19f582bac90a2f4277820a6;hpb=541bf464a0b5849e0823d075a2403eeb37f90ea9;p=openssl-gost%2Fengine.git diff --git a/test_ciphers.c b/test_ciphers.c index 95e3e99..6038498 100644 --- a/test_ciphers.c +++ b/test_ciphers.c @@ -5,34 +5,50 @@ * See https://www.openssl.org/source/license.html for details */ +#ifdef _MSC_VER +# pragma warning(push, 3) +# include +# pragma warning(pop) +#endif #include +#include #include #include #include #include #include -#define T(e) ({ \ - if (!(e)) {\ - ERR_print_errors_fp(stderr);\ - OpenSSLDie(__FILE__, __LINE__, #e);\ - } \ -}) +#if defined _MSC_VER +# include +# define alloca _alloca +#elif defined __linux__ +# include +#endif +#include + +#define T(e) \ + if (!(e)) { \ + ERR_print_errors_fp(stderr); \ + OpenSSLDie(__FILE__, __LINE__, #e); \ + } #define cRED "\033[1;31m" #define cDRED "\033[0;31m" #define cGREEN "\033[1;32m" #define cDGREEN "\033[0;32m" #define cBLUE "\033[1;34m" +#define cMAGENT "\033[1;35m" #define cDBLUE "\033[0;34m" #define cNORM "\033[m" #define TEST_ASSERT(e) {if ((test = (e))) \ - printf(cRED "Test FAILED\n" cNORM); \ + printf(cRED "Test FAILED" cNORM "\n"); \ else \ - printf(cGREEN "Test passed\n" cNORM);} + printf(cGREEN "Test passed" cNORM "\n");} +#ifdef __GNUC__ /* Pragma to allow commenting out some tests. */ -#pragma GCC diagnostic ignored "-Wunused-const-variable" +# pragma GCC diagnostic ignored "-Wunused-const-variable" +#endif /* * Test keys from both GOST R 34.12-2015 and GOST R 34.13-2015, @@ -169,7 +185,7 @@ static const unsigned char iv_128bit[] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xce,0x static const unsigned char iv_acpkm_m[] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; static struct testcase { - int nid; + const char *algname; int block; /* Actual underlying block size (bytes). */ int stream; /* Stream cipher. */ const unsigned char *plaintext; @@ -181,7 +197,7 @@ static struct testcase { int acpkm; } testcases[] = { { - .nid = NID_grasshopper_ecb, + .algname = SN_grasshopper_ecb, .block = 16, .plaintext = P, .key = K, @@ -189,7 +205,7 @@ static struct testcase { .size = sizeof(P), }, { - .nid = NID_grasshopper_ctr, + .algname = SN_grasshopper_ctr, .block = 16, .stream = 1, .plaintext = P, @@ -200,7 +216,7 @@ static struct testcase { .iv_size = sizeof(iv_ctr), }, { - .nid = NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, + .algname = SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, .block = 16, .stream = 1, .plaintext = P, @@ -212,7 +228,7 @@ static struct testcase { /* no acpkm works same as ctr */ }, { - .nid = NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, + .algname = SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, .block = 16, .stream = 1, .plaintext = P_acpkm, @@ -224,7 +240,7 @@ static struct testcase { .acpkm = 256 / 8, }, { - .nid = NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, + .algname = SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, .block = 16, .plaintext = P_acpkm_master, .key = K, @@ -235,7 +251,7 @@ static struct testcase { .acpkm = 768 / 8 }, { - .nid = NID_grasshopper_ofb, + .algname = SN_grasshopper_ofb, .block = 16, .stream = 1, .plaintext = P, @@ -246,7 +262,7 @@ static struct testcase { .iv_size = sizeof(iv_128bit), }, { - .nid = NID_grasshopper_cbc, + .algname = SN_grasshopper_cbc, .block = 16, .plaintext = P, .key = K, @@ -256,7 +272,7 @@ static struct testcase { .iv_size = sizeof(iv_128bit), }, { - .nid = NID_grasshopper_cfb, + .algname = SN_grasshopper_cfb, .block = 16, .plaintext = P, .key = K, @@ -266,7 +282,7 @@ static struct testcase { .iv_size = sizeof(iv_128bit), }, { - .nid = NID_magma_ctr, + .algname = SN_magma_ctr, .block = 8, .plaintext = Pm, .key = Km, @@ -275,9 +291,8 @@ static struct testcase { .iv = iv_ctr, .iv_size = sizeof(iv_ctr) / 2, }, -#if 0 { - .nid = NID_magma_cbc, + .algname = SN_magma_cbc, .block = 8, .plaintext = Pm, .key = Km, @@ -286,7 +301,6 @@ static struct testcase { .iv = iv_cbc, .iv_size = sizeof(iv_cbc), }, -#endif { 0 } }; @@ -304,12 +318,12 @@ static void hexdump(const void *ptr, size_t len) static int test_block(const EVP_CIPHER *type, const char *name, int block_size, const unsigned char *pt, const unsigned char *key, const unsigned char *exp, - size_t size, const unsigned char *iv, size_t iv_size, int acpkm, + const size_t size, const unsigned char *iv, size_t iv_size, int acpkm, int inplace) { EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); const char *standard = acpkm? "R 23565.1.017-2018" : "GOST R 34.13-2015"; - unsigned char c[size]; + unsigned char *c = alloca(size); int outlen, tmplen; int ret = 0, test; @@ -332,9 +346,18 @@ static int test_block(const EVP_CIPHER *type, const char *name, int block_size, if (inplace) memcpy(c, pt, size); else - memset(c, 0, sizeof(c)); - if (acpkm) - T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + memset(c, 0, size); + if (acpkm) { + if (EVP_CIPHER_get0_provider(type) != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t v = (size_t)acpkm; + + params[0] = OSSL_PARAM_construct_size_t("key-mesh", &v); + T(EVP_CIPHER_CTX_set_params(ctx, params)); + } else { + T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + } + } T(EVP_CipherUpdate(ctx, c, &outlen, inplace? c : pt, size)); T(EVP_CipherFinal_ex(ctx, c + outlen, &tmplen)); EVP_CIPHER_CTX_cleanup(ctx); @@ -357,9 +380,18 @@ static int test_block(const EVP_CIPHER *type, const char *name, int block_size, if (inplace) memcpy(c, pt, size); else - memset(c, 0, sizeof(c)); - if (acpkm) - T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + memset(c, 0, size); + if (acpkm) { + if (EVP_CIPHER_get0_provider(type) != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t v = (size_t)acpkm; + + params[0] = OSSL_PARAM_construct_size_t("key-mesh", &v); + T(EVP_CIPHER_CTX_set_params(ctx, params)); + } else { + T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + } + } for (z = 0; z < blocks; z++) { int offset = z * block_size; int sz = block_size; @@ -386,9 +418,18 @@ static int test_block(const EVP_CIPHER *type, const char *name, int block_size, if (inplace) memcpy(c, exp, size); else - memset(c, 0, sizeof(c)); - if (acpkm) - T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + memset(c, 0, size); + if (acpkm) { + if (EVP_CIPHER_get0_provider(type) != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t v = (size_t)acpkm; + + params[0] = OSSL_PARAM_construct_size_t("key-mesh", &v); + T(EVP_CIPHER_CTX_set_params(ctx, params)); + } else { + T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + } + } T(EVP_CipherUpdate(ctx, c, &outlen, inplace ? c : exp, size)); T(EVP_CipherFinal_ex(ctx, c + outlen, &tmplen)); EVP_CIPHER_CTX_cleanup(ctx); @@ -406,10 +447,11 @@ static int test_block(const EVP_CIPHER *type, const char *name, int block_size, static int test_stream(const EVP_CIPHER *type, const char *name, const unsigned char *pt, const unsigned char *key, const unsigned char *exp, - size_t size, const unsigned char *iv, size_t iv_size, int acpkm) + const size_t size, const unsigned char *iv, size_t iv_size, int acpkm) { EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); const char *standard = acpkm? "R 23565.1.017-2018" : "GOST R 34.13-2015"; + unsigned char *c = alloca(size); int ret = 0, test; int z; @@ -421,7 +463,6 @@ static int test_stream(const EVP_CIPHER *type, const char *name, T(EVP_CIPHER_block_size(type) == 1); for (z = 1; z <= size; z++) { - unsigned char c[size]; int outlen, tmplen; int sz = 0; int i; @@ -429,9 +470,18 @@ static int test_stream(const EVP_CIPHER *type, const char *name, EVP_CIPHER_CTX_init(ctx); T(EVP_CipherInit_ex(ctx, type, NULL, key, iv, 1)); T(EVP_CIPHER_CTX_set_padding(ctx, 0)); - memset(c, 0xff, sizeof(c)); - if (acpkm) - T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + memset(c, 0xff, size); + if (acpkm) { + if (EVP_CIPHER_get0_provider(type) != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t v = (size_t)acpkm; + + params[0] = OSSL_PARAM_construct_size_t("key-mesh", &v); + T(EVP_CIPHER_CTX_set_params(ctx, params)); + } else { + T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL)); + } + } for (i = 0; i < size; i += z) { if (i + z > size) sz = size - i; @@ -455,6 +505,64 @@ static int test_stream(const EVP_CIPHER *type, const char *name, return ret; } +int engine_is_available(const char *name) +{ + ENGINE *e = ENGINE_get_first(); + + while (e != NULL) { + if (strcmp(ENGINE_get_id(e), name) == 0) + break; + e = ENGINE_get_next(e); + } + ENGINE_free(e); + return 0; +} + +void warn_if_untested(const EVP_CIPHER *ciph, void *provider) +{ + const struct testcase *t; + + /* ENGINE provided EVP_MDs have a NULL provider */ + if (provider != EVP_CIPHER_get0_provider(ciph)) + return; + + for (t = testcases; t->algname; t++) + if (EVP_CIPHER_is_a(ciph, t->algname)) + break; + if (!t->algname) + printf(cMAGENT "Cipher %s is untested!" cNORM "\n", EVP_CIPHER_name(ciph)); +} + +void warn_all_untested(void) +{ + if (engine_is_available("gost")) { + ENGINE *eng; + + T(eng = ENGINE_by_id("gost")); + T(ENGINE_init(eng)); + + ENGINE_CIPHERS_PTR fn_c; + T(fn_c = ENGINE_get_ciphers(eng)); + const int *nids; + int n, k; + n = fn_c(eng, NULL, &nids, 0); + for (k = 0; k < n; ++k) + warn_if_untested(ENGINE_get_cipher(eng, nids[k]), NULL); + ENGINE_finish(eng); + ENGINE_free(eng); + } + if (OSSL_PROVIDER_available(NULL, "gostprov")) { + OSSL_PROVIDER *prov; + + T(prov = OSSL_PROVIDER_load(NULL, "gostprov")); + EVP_CIPHER_do_all_provided(NULL, + (void (*)(EVP_CIPHER *, void *))warn_if_untested, + prov); + + OSSL_PROVIDER_unload(prov); + } +} + int main(int argc, char **argv) { int ret = 0; @@ -464,38 +572,37 @@ int main(int argc, char **argv) /* Trigger SIGBUS for unaligned access. */ sysmips(MIPS_FIXADE, 0); #endif - setenv("OPENSSL_ENGINES", ENGINE_DIR, 0); OPENSSL_add_all_algorithms_conf(); - ERR_load_crypto_strings(); - ENGINE *eng; - T(eng = ENGINE_by_id("gost")); - T(ENGINE_init(eng)); - T(ENGINE_set_default(eng, ENGINE_METHOD_ALL)); - for (t = testcases; t->nid; t++) { + for (t = testcases; t->algname; t++) { int inplace; const char *standard = t->acpkm? "R 23565.1.017-2018" : "GOST R 34.13-2015"; - const EVP_CIPHER *type = EVP_get_cipherbynid(t->nid); - const char *name = EVP_CIPHER_name(type); + EVP_CIPHER *ciph; - printf(cBLUE "# Tests for %s [%s]\n" cNORM, name, standard); + ERR_set_mark(); + T((ciph = (EVP_CIPHER *)EVP_get_cipherbyname(t->algname)) + || (ciph = EVP_CIPHER_fetch(NULL, t->algname, NULL))); + ERR_pop_to_mark(); + + printf(cBLUE "# Tests for %s [%s]" cNORM "\n", t->algname, standard); for (inplace = 0; inplace <= 1; inplace++) - ret |= test_block(type, name, t->block, + ret |= test_block(ciph, t->algname, t->block, t->plaintext, t->key, t->expected, t->size, t->iv, t->iv_size, t->acpkm, inplace); if (t->stream) - ret |= test_stream(type, name, + ret |= test_stream(ciph, t->algname, t->plaintext, t->key, t->expected, t->size, t->iv, t->iv_size, t->acpkm); + + EVP_CIPHER_free(ciph); } - ENGINE_finish(eng); - ENGINE_free(eng); + warn_all_untested(); if (ret) - printf(cDRED "= Some tests FAILED!\n" cNORM); + printf(cDRED "= Some tests FAILED!" cNORM "\n"); else - printf(cDGREEN "= All tests passed!\n" cNORM); + printf(cDGREEN "= All tests passed!" cNORM "\n"); return ret; }