2 * Copyright (C) 2018 vt@altlinux.org. All Rights Reserved.
4 * Contents licensed under the terms of the OpenSSL license
5 * See https://www.openssl.org/source/license.html for details
8 #include <openssl/engine.h>
9 #include <openssl/evp.h>
10 #include <openssl/rand.h>
11 #include <openssl/err.h>
12 #include <openssl/asn1.h>
15 #define T(e) if (!(e)) {\
16 ERR_print_errors_fp(stderr);\
17 OpenSSLDie(__FILE__, __LINE__, #e);\
20 #define cRED "\033[1;31m"
21 #define cDRED "\033[0;31m"
22 #define cGREEN "\033[1;32m"
23 #define cDGREEN "\033[0;32m"
24 #define cBLUE "\033[1;34m"
25 #define cDBLUE "\033[0;34m"
26 #define cNORM "\033[m"
27 #define TEST_ASSERT(e) {if ((test = (e))) \
28 printf(cRED " Test FAILED\n" cNORM); \
30 printf(cGREEN " Test passed\n" cNORM);}
32 static void hexdump(const void *ptr, size_t len)
34 const unsigned char *p = ptr;
37 for (i = 0; i < len; i += j) {
38 for (j = 0; j < 16 && i + j < len; j++)
39 printf("%s%02x", j? "" : " ", p[i + j]);
47 static int test_contexts(int nid, const int enc, int acpkm)
49 EVP_CIPHER_CTX *ctx, *save;
50 unsigned char pt[TEST_SIZE] = {1};
51 unsigned char b[TEST_SIZE]; /* base output */
52 unsigned char c[TEST_SIZE]; /* cloned output */
53 unsigned char K[32] = {1};
54 unsigned char iv[16] = {1};
56 int ret = 0, test = 0;
58 const EVP_CIPHER *type = EVP_get_cipherbynid(nid);
59 const char *name = EVP_CIPHER_name(type);
61 printf(cBLUE "%s test for %s (nid %d)\n" cNORM,
62 enc ? "Encryption" : "Decryption", name, nid);
64 /* produce base encryption */
65 ctx = EVP_CIPHER_CTX_new();
67 T(EVP_CipherInit_ex(ctx, type, NULL, K, iv, enc));
69 T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL));
70 T(EVP_CIPHER_CTX_set_padding(ctx, 0));
71 T(EVP_CipherUpdate(ctx, b, &outlen, pt, sizeof(b)));
72 T(EVP_CipherFinal_ex(ctx, b + outlen, &tmplen));
75 EVP_CIPHER_CTX_reset(ctx);
76 EVP_CIPHER_CTX_reset(ctx); /* double call is intentional */
77 T(EVP_CipherInit_ex(ctx, type, NULL, K, iv, enc));
78 T(EVP_CIPHER_CTX_set_padding(ctx, 0));
80 T(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_KEY_MESH, acpkm, NULL));
83 printf(" cloned contexts: ");
85 memset(c, 0, sizeof(c));
86 for (i = 0; i < TEST_SIZE / STEP_SIZE; i++) {
87 EVP_CIPHER_CTX *copy = EVP_CIPHER_CTX_new();
89 T(EVP_CIPHER_CTX_copy(copy, ctx));
90 if (save != ctx) /* else original context */
91 EVP_CIPHER_CTX_free(ctx);
94 T(EVP_CipherUpdate(ctx, c + STEP_SIZE * i, &outlen,
95 pt + STEP_SIZE * i, STEP_SIZE));
98 outlen = i * STEP_SIZE;
99 T(EVP_CipherFinal_ex(ctx, c + outlen, &tmplen));
100 TEST_ASSERT(outlen != TEST_SIZE || memcmp(c, b, TEST_SIZE));
101 EVP_CIPHER_CTX_free(ctx);
103 printf(" b[%d] = ", outlen);
105 printf(" c[%d] = ", outlen);
110 /* resume original context */
111 printf(" base context: ");
112 memset(c, 0, sizeof(c));
113 T(EVP_CipherUpdate(save, c, &outlen, pt, sizeof(c)));
114 T(EVP_CipherFinal_ex(save, c + outlen, &tmplen));
115 TEST_ASSERT(outlen != TEST_SIZE || memcmp(c, b, TEST_SIZE));
116 EVP_CIPHER_CTX_cleanup(save); /* multiple calls are intentional */
117 EVP_CIPHER_CTX_cleanup(save);
118 EVP_CIPHER_CTX_free(save);
120 printf(" b[%d] = ", outlen);
122 printf(" c[%d] = ", outlen);
130 static struct testcase {
134 { NID_id_Gost28147_89, },
136 { NID_gost89_cnt_12, },
138 { NID_grasshopper_ecb, },
139 { NID_grasshopper_cbc, },
140 { NID_grasshopper_cfb, },
141 { NID_grasshopper_ofb, },
142 { NID_grasshopper_ctr, },
145 { NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, 256 / 8 },
149 int main(int argc, char **argv)
153 setenv("OPENSSL_ENGINES", ENGINE_DIR, 0);
154 OPENSSL_add_all_algorithms_conf();
155 ERR_load_crypto_strings();
157 T(eng = ENGINE_by_id("gost"));
159 T(ENGINE_set_default(eng, ENGINE_METHOD_ALL));
161 const struct testcase *t;
162 for (t = testcases; t->nid; t++) {
163 ret |= test_contexts(t->nid, 1, t->acpkm);
164 ret |= test_contexts(t->nid, 0, t->acpkm);
171 printf(cDRED "= Some tests FAILED!\n" cNORM);
173 printf(cDGREEN "= All tests passed!\n" cNORM);