2 * Copyright (c) 2019-2020 Dmitry Belyavskiy <beldmit@gmail.com>
4 * Contents licensed under the terms of the OpenSSL license
5 * See https://www.openssl.org/source/license.html for details
8 # pragma warning(push, 3)
9 # include <openssl/applink.c>
11 # include <Winsock2.h>
14 # include <arpa/inet.h>
19 #include <openssl/evp.h>
20 #include <openssl/hmac.h>
21 #include <openssl/obj_mac.h>
23 #include "e_gost_err.h"
24 #include "gost_grasshopper_cipher.h"
28 ERR_print_errors_fp(stderr); \
29 OpenSSLDie(__FILE__, __LINE__, #e); \
32 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
36 fprintf(f, "%s", title);
39 fprintf(f, "\n%04x", n);
40 fprintf(f, " %02x", s[n]);
47 const unsigned char shared_key[] = {
48 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
49 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
50 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
51 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
54 const unsigned char magma_key[] = {
55 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
56 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
57 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
58 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
61 unsigned char mac_magma_key[] = {
62 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
63 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
64 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
65 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
68 const unsigned char magma_iv[] = { 0x67, 0xBE, 0xD6, 0x54 };
70 const unsigned char magma_export[] = {
71 0xCF, 0xD5, 0xA1, 0x2D, 0x5B, 0x81, 0xB6, 0xE1,
72 0xE9, 0x9C, 0x91, 0x6D, 0x07, 0x90, 0x0C, 0x6A,
73 0xC1, 0x27, 0x03, 0xFB, 0x3A, 0xBD, 0xED, 0x55,
74 0x56, 0x7B, 0xF3, 0x74, 0x2C, 0x89, 0x9C, 0x75,
75 0x5D, 0xAF, 0xE7, 0xB4, 0x2E, 0x3A, 0x8B, 0xD9
78 unsigned char kdftree_key[] = {
79 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
80 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
81 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
82 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
85 unsigned char kdf_label[] = { 0x26, 0xBD, 0xB8, 0x78 };
86 unsigned char kdf_seed[] =
87 { 0xAF, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78 };
88 const unsigned char kdf_etalon[] = {
89 0x22, 0xB6, 0x83, 0x78, 0x45, 0xC6, 0xBE, 0xF6,
90 0x5E, 0xA7, 0x16, 0x72, 0xB2, 0x65, 0x83, 0x10,
91 0x86, 0xD3, 0xC7, 0x6A, 0xEB, 0xE6, 0xDA, 0xE9,
92 0x1C, 0xAD, 0x51, 0xD8, 0x3F, 0x79, 0xD1, 0x6B,
93 0x07, 0x4C, 0x93, 0x30, 0x59, 0x9D, 0x7F, 0x8D,
94 0x71, 0x2F, 0xCA, 0x54, 0x39, 0x2F, 0x4D, 0xDD,
95 0xE9, 0x37, 0x51, 0x20, 0x6B, 0x35, 0x84, 0xC8,
96 0xF4, 0x3F, 0x9E, 0x6D, 0xC5, 0x15, 0x31, 0xF9
99 const unsigned char tlstree_gh_etalon[] = {
100 0x50, 0x76, 0x42, 0xd9, 0x58, 0xc5, 0x20, 0xc6,
101 0xd7, 0xee, 0xf5, 0xca, 0x8a, 0x53, 0x16, 0xd4,
102 0xf3, 0x4b, 0x85, 0x5d, 0x2d, 0xd4, 0xbc, 0xbf,
103 0x4e, 0x5b, 0xf0, 0xff, 0x64, 0x1a, 0x19, 0xff,
106 unsigned char buf[32 + 16];
107 int ret = 0, err = 0;
109 unsigned char kdf_result[64];
111 unsigned char kroot[32];
112 unsigned char tlsseq[8];
113 unsigned char out[32];
116 _putenv_s("OPENSSL_ENGINES", ENGINE_DIR);
118 setenv("OPENSSL_ENGINES", ENGINE_DIR, 0);
120 OPENSSL_add_all_algorithms_conf();
121 ERR_load_crypto_strings();
123 T(eng = ENGINE_by_id("gost"));
125 T(ENGINE_set_default(eng, ENGINE_METHOD_ALL));
127 memset(buf, 0, sizeof(buf));
129 memset(kroot, 0xFF, 32);
130 memset(tlsseq, 0, 8);
134 ret = gost_kexp15(shared_key, 32,
135 NID_magma_ctr, magma_key,
136 NID_magma_mac, mac_magma_key, magma_iv, 4, buf, &outlen);
139 ERR_print_errors_fp(stderr);
142 hexdump(stdout, "Magma key export", buf, 40);
143 if (memcmp(buf, magma_export, 40) != 0) {
144 fprintf(stdout, "ERROR! test failed\n");
149 ret = gost_kimp15(magma_export, 40,
150 NID_magma_ctr, magma_key,
151 NID_magma_mac, mac_magma_key, magma_iv, 4, buf);
154 ERR_print_errors_fp(stderr);
157 hexdump(stdout, "Magma key import", buf, 32);
158 if (memcmp(buf, shared_key, 32) != 0) {
159 fprintf(stdout, "ERROR! test failed\n");
164 ret = gost_kdftree2012_256(kdf_result, 64, kdftree_key, 32, kdf_label, 4,
167 ERR_print_errors_fp(stderr);
170 hexdump(stdout, "KDF TREE", kdf_result, 64);
171 if (memcmp(kdf_result, kdf_etalon, 64) != 0) {
172 fprintf(stdout, "ERROR! test failed\n");
177 ret = gost_tlstree(NID_grasshopper_cbc, kroot, out, tlsseq);
179 ERR_print_errors_fp(stderr);
182 hexdump(stdout, "Gost TLSTREE - grasshopper", out, 32);
183 if (memcmp(out, tlstree_gh_etalon, 32) != 0) {
184 fprintf(stdout, "ERROR! test failed\n");