From 565ebb8b9bf2d017b68cce0129728c079f6b7c00 Mon Sep 17 00:00:00 2001 From: Vitaly Chikunov Date: Sun, 22 Jul 2018 08:59:53 +0300 Subject: [PATCH] test_grasshopper: Test for OMAC (cherry picked from commit 370c40dfa4e9a372da03b68453a4af0c10d30a90) --- test_grasshopper.c | 152 +++++++++++++++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 47 deletions(-) diff --git a/test_grasshopper.c b/test_grasshopper.c index 772afa9..e5a0988 100644 --- a/test_grasshopper.c +++ b/test_grasshopper.c @@ -10,53 +10,72 @@ #include "gost_grasshopper_math.h" #include "gost_grasshopper_core.h" #include "e_gost_err.h" +#include "gost_lcl.h" #include #include #include #include #include +#define T(e) if (!(e)) {\ + ERR_print_errors_fp(stderr);\ + OpenSSLDie(__FILE__, __LINE__, #e);\ + } + +#define cRED "\033[1;31m" +#define cGREEN "\033[1;32m" +#define cNORM "\033[m" +#define TEST_ASSERT(e) {if ((test = (e))) \ + printf(cRED "Test FAILED\n" cNORM); \ + else \ + printf(cGREEN "Test passed\n" cNORM);} + enum e_mode { E_ECB = 0, E_CTR }; -static void hexdump(void *ptr, size_t len) +/* Test key from both GOST R 34.12-2015 and GOST R 34.13-2015. */ +static const unsigned char K[] = { + 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, +}; + +/* Plaintext from GOST R 34.13-2015 A.1. + * First 16 bytes is vector (a) from GOST R 34.12-2015 A.1. */ +static const unsigned char P[] = { + 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0xff,0xee,0xdd,0xcc,0xbb,0xaa,0x99,0x88, + 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a, + 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a,0x00, + 0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a,0x00,0x11, +}; + +static void hexdump(const void *ptr, size_t len) { - unsigned char *p = ptr; - size_t i; + const unsigned char *p = ptr; + size_t i, j; - for (i = 0; i < len; i++) - printf(" %02x", p[i]); - printf("\n"); + for (i = 0; i < len; i += j) { + for (j = 0; j < 16 && i + j < len; j++) + printf("%s%02x", j? " " : "\t", p[i + j]); + printf("\n"); + } } /* Test vectors from GOST R 34.13-2015 A.1 which* includes vectors - * from GOST R 34.12-2015 A.1 as first block of ecb mode */ + * from GOST R 34.12-2015 A.1 as first block of ecb mode. */ static int test_modes(const EVP_CIPHER *type, const char *mode, enum e_mode t) { EVP_CIPHER_CTX ctx; - unsigned char k[] = { - 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, - 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, - }; - unsigned char p[] = { - /* plaintext from GOST R 34.13-2015 A.1 */ - /* first 16 bytes is vector (a) from GOST R 34.12-2015 A.1 */ - 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0xff,0xee,0xdd,0xcc,0xbb,0xaa,0x99,0x88, - 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a, - 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a,0x00, - 0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xee,0xff,0x0a,0x00,0x11, - }; - unsigned char e[4][sizeof(p)] = { - { /* ecb test vectors from GOST R 34.13-2015 A.1.1 */ + unsigned char e[4][sizeof(P)] = { + { /* ECB test vectors from GOST R 34.13-2015 A.1.1 */ /* first 16 bytes is vector (b) from GOST R 34.12-2015 A.1 */ 0x7f,0x67,0x9d,0x90,0xbe,0xbc,0x24,0x30,0x5a,0x46,0x8d,0x42,0xb9,0xd4,0xed,0xcd, 0xb4,0x29,0x91,0x2c,0x6e,0x00,0x32,0xf9,0x28,0x54,0x52,0xd7,0x67,0x18,0xd0,0x8b, 0xf0,0xca,0x33,0x54,0x9d,0x24,0x7c,0xee,0xf3,0xf5,0xa5,0x31,0x3b,0xd4,0xb1,0x57, 0xd0,0xb0,0x9c,0xcd,0xe8,0x30,0xb9,0xeb,0x3a,0x02,0xc4,0xc5,0xaa,0x8a,0xda,0x98, }, - { /* ctr test vectors from GOST R 34.13-2015 A.1.2 */ + { /* CTR test vectors from GOST R 34.13-2015 A.1.2 */ 0xf1,0x95,0xd8,0xbe,0xc1,0x0e,0xd1,0xdb,0xd5,0x7b,0x5f,0xa2,0x40,0xbd,0xa1,0xb8, 0x85,0xee,0xe7,0x33,0xf6,0xa1,0x3e,0x5d,0xf3,0x3c,0xe4,0xb3,0x3c,0x45,0xde,0xe4, 0xa5,0xea,0xe8,0x8b,0xe6,0x35,0x6e,0xd3,0xd5,0xe8,0x77,0xf1,0x35,0x64,0xa3,0xa5, @@ -65,23 +84,27 @@ static int test_modes(const EVP_CIPHER *type, const char *mode, enum e_mode t) }; unsigned char iv_ctr[] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xce,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; unsigned char *iv[4] = { NULL, iv_ctr, }; - unsigned char c[sizeof(p)]; + unsigned char c[sizeof(P)]; int outlen, tmplen; int ret = 0, test; printf("Encryption test from GOST R 34.13-2015 [%s] \n", mode); + if (!t) { + printf(" p[%zu] =\n", sizeof(P)); + hexdump(P, sizeof(P)); + } EVP_CIPHER_CTX_init(&ctx); - EVP_CipherInit_ex(&ctx, type, NULL, k, iv[t], 1); - EVP_CIPHER_CTX_set_padding(&ctx, 0); - EVP_CipherUpdate(&ctx, c, &outlen, p, sizeof(p)); - EVP_CipherFinal_ex(&ctx, c + outlen, &tmplen); + T(EVP_CipherInit_ex(&ctx, type, NULL, K, iv[t], 1)); + T(EVP_CIPHER_CTX_set_padding(&ctx, 0)); + memset(c, 0, sizeof(c)); + T(EVP_CipherUpdate(&ctx, c, &outlen, P, sizeof(P))); + T(EVP_CipherFinal_ex(&ctx, c + outlen, &tmplen)); EVP_CIPHER_CTX_cleanup(&ctx); - // hexdump(c, outlen); + printf(" c[%d] =\n", outlen); + hexdump(c, outlen); - test = outlen != sizeof(p) || - memcmp(c, e[t], sizeof(p)); - - printf("Test %s\n", test? "FAILED" : "passed"); + TEST_ASSERT(outlen != sizeof(P) || + memcmp(c, e[t], sizeof(P))); ret |= test; if (t == E_CTR) { @@ -89,20 +112,21 @@ static int test_modes(const EVP_CIPHER *type, const char *mode, enum e_mode t) printf("Stream encryption test from GOST R 34.13-2015 [%s] \n", mode); EVP_CIPHER_CTX_init(&ctx); - EVP_CipherInit_ex(&ctx, type, NULL, k, iv[t], 1); + EVP_CipherInit_ex(&ctx, type, NULL, K, iv[t], 1); EVP_CIPHER_CTX_set_padding(&ctx, 0); - for (i = 0; i < sizeof(p); i++) { - EVP_CipherUpdate(&ctx, c + i, &outlen, p + i, 1); + memset(c, 0, sizeof(c)); + for (i = 0; i < sizeof(P); i++) { + EVP_CipherUpdate(&ctx, c + i, &outlen, P + i, 1); OPENSSL_assert(outlen == 1); } outlen = i; EVP_CipherFinal_ex(&ctx, c + outlen, &tmplen); EVP_CIPHER_CTX_cleanup(&ctx); + printf(" c[%d] =\n", outlen); + hexdump(c, outlen); - test = outlen != sizeof(p) || - memcmp(c, e[t], sizeof(p)); - - printf("Test %s\n", test? "FAILED" : "passed"); + TEST_ASSERT(outlen != sizeof(P) || + memcmp(c, e[t], sizeof(P))); #if 0 ret |= test; #endif @@ -110,21 +134,53 @@ static int test_modes(const EVP_CIPHER *type, const char *mode, enum e_mode t) printf("Decryption test from GOST R 34.13-2015 [%s] \n", mode); EVP_CIPHER_CTX_init(&ctx); - EVP_CipherInit_ex(&ctx, type, NULL, k, iv[t], 0); - EVP_CIPHER_CTX_set_padding(&ctx, 0); - EVP_CipherUpdate(&ctx, c, &outlen, e[t], sizeof(p)); - EVP_CipherFinal_ex(&ctx, c + outlen, &tmplen); + T(EVP_CipherInit_ex(&ctx, type, NULL, K, iv[t], 0)); + T(EVP_CIPHER_CTX_set_padding(&ctx, 0)); + memset(c, 0, sizeof(c)); + T(EVP_CipherUpdate(&ctx, c, &outlen, e[t], sizeof(P))); + T(EVP_CipherFinal_ex(&ctx, c + outlen, &tmplen)); EVP_CIPHER_CTX_cleanup(&ctx); + printf(" d[%d] =\n", outlen); + hexdump(c, outlen); - test = outlen != sizeof(p) || - memcmp(c, p, sizeof(p)); - - printf("Test %s\n", test? "FAILED" : "passed"); + TEST_ASSERT(outlen != sizeof(P) || + memcmp(c, P, sizeof(P))); ret |= test; return ret; } +static int test_omac() +{ + EVP_MD_CTX ctx; + unsigned char e[] = { 0x33,0x6f,0x4d,0x29,0x60,0x59,0xfb,0xe3 }; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len; + int test; + + printf("OMAC test from GOST R 34.13-2015\n"); + EVP_MD_CTX_init(&ctx); + /* preload cbc cipher for omac set key */ + EVP_add_cipher(cipher_gost_grasshopper_cbc()); + T(EVP_DigestInit_ex(&ctx, grasshopper_omac(), NULL)); + if (EVP_MD_CTX_size(&ctx) != 8) { + /* strip const out of EVP_MD_CTX_md() to + * overwrite output size, as test vector is 8 bytes */ + T(EVP_MD_meth_set_result_size((EVP_MD *)EVP_MD_CTX_md(&ctx), 8)); + } + T(EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(&ctx))(&ctx, EVP_MD_CTRL_SET_KEY, sizeof(K), (void *)K)); + T(EVP_DigestUpdate(&ctx, P, sizeof(P))); + T(EVP_DigestFinal_ex(&ctx, md_value, &md_len)); + EVP_MD_CTX_cleanup(&ctx); + printf(" MAC[%u] =\n", md_len); + hexdump(md_value, md_len); + + TEST_ASSERT(md_len != sizeof(e) || + memcmp(e, md_value, md_len)); + + return test; +} + int main(int argc, char **argv) { int ret = 0; @@ -139,5 +195,7 @@ int main(int argc, char **argv) * Also, current grasshopper code having fixed IV length of 128 bits. */ + ret |= test_omac(); + return ret; } -- 2.39.5