]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost89.c
tcl_tests: ca.try: Ignore openssl crl exit status for 'corrupted CRL' test
[openssl-gost/engine.git] / gost89.c
1 /**********************************************************************
2  *                        gost89.c                                    *
3  *             Copyright (c) 2005-2006 Cryptocom LTD                  *
4  *         This file is distributed under the same license as OpenSSL *
5  *                                                                    *
6  *          Implementation of GOST 28147-89 encryption algorithm      *
7  *            No OpenSSL libraries required to compile and use        *
8  *                              this code                             *
9  **********************************************************************/
10 #include <string.h>
11 #include <openssl/crypto.h>
12 #include <openssl/rand.h>
13 #include "gost89.h"
14 /*-
15    Substitution blocks from RFC 4357
16
17    Note: our implementation of gost 28147-89 algorithm
18    uses S-box matrix rotated 90 degrees counterclockwise, relative to
19    examples given in RFC.
20
21
22 */
23
24 /* Substitution blocks from test examples for GOST R 34.11-94*/
25 gost_subst_block GostR3411_94_TestParamSet = {
26     {0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB,
27      0X8, 0XC}
28     ,
29     {0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8,
30      0X2, 0XC}
31     ,
32     {0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC,
33      0XF, 0XE}
34     ,
35     {0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3,
36      0XB, 0X2}
37     ,
38     {0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2,
39      0X5, 0X3}
40     ,
41     {0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0,
42      0X9, 0XB}
43     ,
44     {0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7,
45      0X5, 0X9}
46     ,
47     {0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF,
48      0X5, 0X3}
49 };
50
51 /* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
52 gost_subst_block GostR3411_94_CryptoProParamSet = {
53     {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0,
54      0x2, 0xC}
55     ,
56     {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2,
57      0x9, 0xB}
58     ,
59     {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE,
60      0xC, 0x3}
61     ,
62     {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD,
63      0x3, 0x5}
64     ,
65     {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB,
66      0x9, 0x3}
67     ,
68     {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA,
69      0x8, 0xD}
70     ,
71     {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE,
72      0xA, 0x8}
73     ,
74     {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2,
75      0xB, 0xF}
76 };
77
78 /* Test paramset from GOST 28147 */
79 gost_subst_block Gost28147_TestParamSet = {
80     {0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4,
81      0x1, 0x8}
82     ,
83     {0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA,
84      0x2, 0xD}
85     ,
86     {0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE,
87      0x2, 0x4}
88     ,
89     {0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1,
90      0xF, 0x4}
91     ,
92     {0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4,
93      0x3, 0x8}
94     ,
95     {0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF,
96      0x0, 0xB}
97     ,
98     {0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0,
99      0xB, 0x5}
100     ,
101     {0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7,
102      0xA, 0x6}
103 };
104
105 /* 1.2.643.2.2.31.1 */
106 gost_subst_block Gost28147_CryptoProParamSetA = {
107     {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7,
108      0xD, 0x4}
109     ,
110     {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3,
111      0xB, 0xE}
112     ,
113     {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF,
114      0xE, 0x6}
115     ,
116     {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7,
117      0xA, 0x6}
118     ,
119     {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8,
120      0x5, 0x6}
121     ,
122     {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7,
123      0x1, 0x9}
124     ,
125     {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4,
126      0xD, 0x1}
127     ,
128     {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0,
129      0xD, 0x5}
130 };
131
132 /* 1.2.643.2.2.31.2 */
133 gost_subst_block Gost28147_CryptoProParamSetB = {
134     {0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD,
135      0x5, 0xC}
136     ,
137     {0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF,
138      0x8, 0xE}
139     ,
140     {0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0,
141      0x9, 0x5}
142     ,
143     {0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8,
144      0xE, 0x3}
145     ,
146     {0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE,
147      0x9, 0x8}
148     ,
149     {0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6,
150      0x1, 0x4}
151     ,
152     {0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8,
153      0x6, 0xE}
154     ,
155     {0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6,
156      0x7, 0xF}
157 };
158
159 /* 1.2.643.2.2.31.3 */
160 gost_subst_block Gost28147_CryptoProParamSetC = {
161     {0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9,
162      0x3, 0x8}
163     ,
164     {0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1,
165      0xC, 0x7}
166     ,
167     {0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0,
168      0xF, 0xD}
169     ,
170     {0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF,
171      0xA, 0x7}
172     ,
173     {0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF,
174      0xC, 0x4}
175     ,
176     {0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE,
177      0x1, 0xB}
178     ,
179     {0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA,
180      0x6, 0x3}
181     ,
182     {0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7,
183      0x6, 0x3}
184 };
185
186 /* 1.2.643.2.2.31.4 */
187 gost_subst_block Gost28147_CryptoProParamSetD = {
188     {0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD,
189      0x2, 0xE}
190     ,
191     {0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA,
192      0x5, 0x7}
193     ,
194     {0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9,
195      0xD, 0x6}
196     ,
197     {0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE,
198      0xF, 0x1}
199     ,
200     {0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3,
201      0xF, 0x8}
202     ,
203     {0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3,
204      0x7, 0x2}
205     ,
206     {0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA,
207      0x9, 0x1}
208     ,
209     {0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB,
210      0x8, 0x3}
211 };
212
213 /* 1.2.643.7.1.2.5.1.1 */
214 gost_subst_block Gost28147_TC26ParamSetZ = {
215     {0x1, 0x7, 0xe, 0xd, 0x0, 0x5, 0x8, 0x3, 0x4, 0xf, 0xa, 0x6, 0x9, 0xc,
216      0xb, 0x2}
217     ,
218     {0x8, 0xe, 0x2, 0x5, 0x6, 0x9, 0x1, 0xc, 0xf, 0x4, 0xb, 0x0, 0xd, 0xa,
219      0x3, 0x7}
220     ,
221     {0x5, 0xd, 0xf, 0x6, 0x9, 0x2, 0xc, 0xa, 0xb, 0x7, 0x8, 0x1, 0x4, 0x3,
222      0xe, 0x0}
223     ,
224     {0x7, 0xf, 0x5, 0xa, 0x8, 0x1, 0x6, 0xd, 0x0, 0x9, 0x3, 0xe, 0xb, 0x4,
225      0x2, 0xc}
226     ,
227     {0xc, 0x8, 0x2, 0x1, 0xd, 0x4, 0xf, 0x6, 0x7, 0x0, 0xa, 0x5, 0x3, 0xe,
228      0x9, 0xb}
229     ,
230     {0xb, 0x3, 0x5, 0x8, 0x2, 0xf, 0xa, 0xd, 0xe, 0x1, 0x7, 0x4, 0xc, 0x9,
231      0x6, 0x0}
232     ,
233     {0x6, 0x8, 0x2, 0x3, 0x9, 0xa, 0x5, 0xc, 0x1, 0xe, 0x4, 0x7, 0xb, 0xd,
234      0x0, 0xf}
235     ,
236     {0xc, 0x4, 0x6, 0x2, 0xa, 0x5, 0xb, 0x9, 0xe, 0x8, 0xd, 0x7, 0x0, 0x3,
237      0xf, 0x1}
238 };
239
240 const byte CryptoProKeyMeshingKey[] = {
241     0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
242     0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
243     0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
244     0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
245 };
246
247 const byte ACPKM_D_const[] = {
248     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
249     0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
250     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
251     0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
252 };
253
254 /* Initialization of gost_ctx subst blocks*/
255 void kboxinit(gost_ctx * c, const gost_subst_block * b)
256 {
257     int i;
258
259     for (i = 0; i < 256; i++) {
260         c->k87[i] = (word32) (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24;
261         c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16;
262         c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8;
263         c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15];
264
265     }
266 }
267
268 /* Part of GOST 28147 algorithm moved into separate function */
269 static word32 f(gost_ctx * c, word32 x)
270 {
271     x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] |
272         c->k43[x >> 8 & 255] | c->k21[x & 255];
273     /* Rotate left 11 bits */
274     return x << 11 | x >> (32 - 11);
275 }
276
277 /* Low-level encryption routine - encrypts one 64 bit block*/
278 void gostcrypt(gost_ctx * c, const byte * in, byte * out)
279 {
280     register word32 n1, n2;     /* As named in the GOST */
281     n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
282     n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
283     /* Instead of swapping halves, swap names each round */
284
285     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
286     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
287     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
288     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
289     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
290     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
291     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
292     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
293
294     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
295     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
296     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
297     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
298     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
299     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
300     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
301     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
302
303     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
304     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
305     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
306     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
307     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
308     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
309     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
310     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
311
312     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
313     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
314     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
315     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
316     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
317     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
318     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
319     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
320
321     out[0] = (byte) (n2 & 0xff);
322     out[1] = (byte) ((n2 >> 8) & 0xff);
323     out[2] = (byte) ((n2 >> 16) & 0xff);
324     out[3] = (byte) (n2 >> 24);
325     out[4] = (byte) (n1 & 0xff);
326     out[5] = (byte) ((n1 >> 8) & 0xff);
327     out[6] = (byte) ((n1 >> 16) & 0xff);
328     out[7] = (byte) (n1 >> 24);
329 }
330
331 /* Low-level encryption routine - encrypts one 64 bit block*/
332 void magmacrypt(gost_ctx * c, const byte * in, byte * out)
333 {
334     register word32 n1, n2;     /* As named in the GOST */
335     n1 = in[7-0] | (in[7-1] << 8) | (in[7-2] << 16) | ((word32) in[7-3] << 24);
336     n2 = in[7-4] | (in[7-5] << 8) | (in[7-6] << 16) | ((word32) in[7-7] << 24);
337     /* Instead of swapping halves, swap names each round */
338
339     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
340     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
341     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
342     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
343     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
344     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
345     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
346     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
347
348     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
349     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
350     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
351     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
352     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
353     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
354     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
355     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
356
357     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
358     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
359     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
360     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
361     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
362     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
363     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
364     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
365
366     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
367     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
368     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
369     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
370     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
371     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
372     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
373     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
374
375     out[7-0] = (byte) (n2 & 0xff);
376     out[7-1] = (byte) ((n2 >> 8) & 0xff);
377     out[7-2] = (byte) ((n2 >> 16) & 0xff);
378     out[7-3] = (byte) (n2 >> 24);
379     out[7-4] = (byte) (n1 & 0xff);
380     out[7-5] = (byte) ((n1 >> 8) & 0xff);
381     out[7-6] = (byte) ((n1 >> 16) & 0xff);
382     out[7-7] = (byte) (n1 >> 24);
383 }
384
385 /* Low-level decryption routine. Decrypts one 64-bit block */
386 void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
387 {
388     register word32 n1, n2;     /* As named in the GOST */
389     n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
390     n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
391
392     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
393     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
394     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
395     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
396     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
397     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
398     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
399     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
400
401     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
402     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
403     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
404     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
405     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
406     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
407     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
408     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
409
410     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
411     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
412     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
413     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
414     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
415     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
416     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
417     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
418
419     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
420     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
421     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
422     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
423     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
424     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
425     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
426     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
427
428     out[0] = (byte) (n2 & 0xff);
429     out[1] = (byte) ((n2 >> 8) & 0xff);
430     out[2] = (byte) ((n2 >> 16) & 0xff);
431     out[3] = (byte) (n2 >> 24);
432     out[4] = (byte) (n1 & 0xff);
433     out[5] = (byte) ((n1 >> 8) & 0xff);
434     out[6] = (byte) ((n1 >> 16) & 0xff);
435     out[7] = (byte) (n1 >> 24);
436 }
437
438 /* Low-level decryption routine. Decrypts one 64-bit block */
439 void magmadecrypt(gost_ctx * c, const byte * in, byte * out)
440 {
441     register word32 n1, n2;     /* As named in the GOST */
442     n1 = in[7-0] | (in[7-1] << 8) | (in[7-2] << 16) | ((word32) in[7-3] << 24);
443     n2 = in[7-4] | (in[7-5] << 8) | (in[7-6] << 16) | ((word32) in[7-7] << 24);
444
445     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
446     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
447     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
448     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
449     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
450     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
451     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
452     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
453
454     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
455     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
456     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
457     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
458     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
459     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
460     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
461     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
462
463     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
464     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
465     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
466     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
467     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
468     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
469     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
470     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
471
472     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
473     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
474     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
475     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
476     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
477     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
478     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
479     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
480
481     out[7-0] = (byte) (n2 & 0xff);
482     out[7-1] = (byte) ((n2 >> 8) & 0xff);
483     out[7-2] = (byte) ((n2 >> 16) & 0xff);
484     out[7-3] = (byte) (n2 >> 24);
485     out[7-4] = (byte) (n1 & 0xff);
486     out[7-5] = (byte) ((n1 >> 8) & 0xff);
487     out[7-6] = (byte) ((n1 >> 16) & 0xff);
488     out[7-7] = (byte) (n1 >> 24);
489 }
490
491
492 /* Encrypts several blocks in ECB mode */
493 void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
494 {
495     int i;
496     for (i = 0; i < blocks; i++) {
497         gostcrypt(c, clear, cipher);
498         clear += 8;
499         cipher += 8;
500     }
501 }
502
503 /* Decrypts several blocks in ECB mode */
504 void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks)
505 {
506     int i;
507     for (i = 0; i < blocks; i++) {
508         gostdecrypt(c, cipher, clear);
509         clear += 8;
510         cipher += 8;
511     }
512 }
513
514 /* Encrypts several full blocks in CFB mode using 8byte IV */
515 void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear,
516                   byte * cipher, int blocks)
517 {
518     byte cur_iv[8];
519     byte gamma[8];
520     int i, j;
521     const byte *in;
522     byte *out;
523     memcpy(cur_iv, iv, 8);
524     for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) {
525         gostcrypt(ctx, cur_iv, gamma);
526         for (j = 0; j < 8; j++) {
527             cur_iv[j] = out[j] = in[j] ^ gamma[j];
528         }
529     }
530 }
531
532 /* Decrypts several full blocks in CFB mode using 8byte IV */
533 void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher,
534                   byte * clear, int blocks)
535 {
536     byte cur_iv[8];
537     byte gamma[8];
538     int i, j;
539     const byte *in;
540     byte *out;
541     memcpy(cur_iv, iv, 8);
542     for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) {
543         gostcrypt(ctx, cur_iv, gamma);
544         for (j = 0; j < 8; j++) {
545             out[j] = (cur_iv[j] = in[j]) ^ gamma[j];
546         }
547     }
548 }
549
550 /* Encrypts one block using specified key */
551 void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
552                        byte * outblock)
553 {
554     gost_key_nomask(c, key);
555     gostcrypt(c, inblock, outblock);
556 }
557
558 static void gost_key_impl(gost_ctx * c, const byte * k)
559 {
560     int i, j;
561     for (i = 0, j = 0; i < 8; ++i, j += 4) {
562         c->key[i] =
563             (k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
564                                                          24)) - c->mask[i];
565     }
566 }
567
568 /* Set 256 bit gost89 key into context */
569 void gost_key(gost_ctx * c, const byte * k)
570 {
571     RAND_priv_bytes((unsigned char *)c->mask, sizeof(c->mask));
572     gost_key_impl(c, k);
573 }
574
575 /* Set 256 bit gost89 key into context without key mask */
576 void gost_key_nomask(gost_ctx * c, const byte * k)
577 {
578     memset(c->mask, 0, sizeof(c->mask));
579     gost_key_impl(c, k);
580 }
581
582 /* Set 256 bit Magma key into context */
583 void magma_key(gost_ctx * c, const byte * k)
584 {
585     int i, j;
586     RAND_priv_bytes((unsigned char *)c->mask, sizeof(c->mask));
587     for (i = 0, j = 0; i < 8; ++i, j += 4) {
588         c->key[i] =
589             (k[j + 3] | (k[j + 2] << 8) | (k[j + 1] << 16) | ((word32) k[j] <<
590                                                              24))  - c->mask[i];
591     }
592 }
593
594 void magma_master_key(gost_ctx *c, const byte *k) {
595     memcpy(c->master_key, k, sizeof(c->master_key));
596 }
597
598 /* Retrieve 256-bit gost89 key from context */
599 void gost_get_key(gost_ctx * c, byte * k)
600 {
601     int i, j;
602     for (i = 0, j = 0; i < 8; i++, j += 4) {
603         k[j] = (byte)((c->key[i] + c->mask[i]) & 0xFF);
604         k[j+1] = (byte)(((c->key[i] + c->mask[i]) >> 8 )& 0xFF);
605         k[j+2] = (byte)(((c->key[i] + c->mask[i]) >> 16) & 0xFF);
606         k[j+3] = (byte)(((c->key[i] + c->mask[i]) >> 24) & 0xFF);
607     }
608 }
609
610 /* Retrieve 256-bit magma key from context */
611 void magma_get_key(gost_ctx * c, byte * k)
612 {
613     int i, j;
614     for (i = 0, j = 0; i < 8; i++, j += 4) {
615         k[j + 3] = (byte) ((c->key[i] + c->mask[i]) & 0xFF);
616         k[j + 2] = (byte) (((c->key[i] + c->mask[i]) >> 8) & 0xFF);
617         k[j + 1] = (byte) (((c->key[i] + c->mask[i]) >> 16) & 0xFF);
618         k[j + 0] = (byte) (((c->key[i] + c->mask[i]) >> 24) & 0xFF);
619     }
620 }
621
622 /* Initalize context. Provides default value for subst_block */
623 void gost_init(gost_ctx * c, const gost_subst_block * b)
624 {
625     if (!b) {
626         b = &GostR3411_94_TestParamSet;
627     }
628     kboxinit(c, b);
629 }
630
631 /* Cleans up key from context */
632 void gost_destroy(gost_ctx * c)
633 {
634     OPENSSL_cleanse(c->master_key, sizeof(c->master_key));
635     OPENSSL_cleanse(c->key, sizeof(c->key));
636     OPENSSL_cleanse(c->mask, sizeof(c->mask));
637 }
638
639 /*
640  * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized
641  * with substitution blocks and key buffer - 8-byte mac state buffer block
642  * 8-byte block to process.
643  */
644 void mac_block(gost_ctx * c, byte * buffer, const byte * block)
645 {
646     register word32 n1, n2;     /* As named in the GOST */
647     int i;
648     for (i = 0; i < 8; i++) {
649         buffer[i] ^= block[i];
650     }
651     n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32)
652                                                              buffer[3] << 24);
653     n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32)
654                                                              buffer[7] << 24);
655     /* Instead of swapping halves, swap names each round */
656
657     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
658     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
659     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
660     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
661     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
662     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
663     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
664     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
665
666     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
667     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
668     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
669     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
670     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
671     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
672     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
673     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
674
675     buffer[0] = (byte) (n1 & 0xff);
676     buffer[1] = (byte) ((n1 >> 8) & 0xff);
677     buffer[2] = (byte) ((n1 >> 16) & 0xff);
678     buffer[3] = (byte) (n1 >> 24);
679     buffer[4] = (byte) (n2 & 0xff);
680     buffer[5] = (byte) ((n2 >> 8) & 0xff);
681     buffer[6] = (byte) ((n2 >> 16) & 0xff);
682     buffer[7] = (byte) (n2 >> 24);
683 }
684
685 /* Get mac with specified number of bits from MAC state buffer */
686 void get_mac(byte * buffer, int nbits, byte * out)
687 {
688     int nbytes = nbits >> 3;
689     int rembits = nbits & 7;
690     int mask = rembits ? ((1 < rembits) - 1) : 0;
691     int i;
692     for (i = 0; i < nbytes; i++)
693         out[i] = buffer[i];
694     if (rembits)
695         out[i] = buffer[i] & mask;
696 }
697
698 /*
699  * Compute mac of specified length (in bits) from data. Context should be
700  * initialized with key and subst blocks
701  */
702 int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data,
703              unsigned int data_len, unsigned char *mac)
704 {
705     byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
706     byte buf2[8];
707     unsigned int i;
708     for (i = 0; i + 8 <= data_len; i += 8)
709         mac_block(ctx, buffer, data + i);
710     if (i < data_len) {
711         memset(buf2, 0, 8);
712         memcpy(buf2, data + i, data_len - i);
713         mac_block(ctx, buffer, buf2);
714         i += 8;
715     }
716     if (i == 8) {
717         memset(buf2, 0, 8);
718         mac_block(ctx, buffer, buf2);
719     }
720     get_mac(buffer, mac_len, mac);
721     return 1;
722 }
723
724 /* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
725 int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv,
726                 const unsigned char *data, unsigned int data_len,
727                 unsigned char *mac)
728 {
729     byte buffer[8];
730     byte buf2[8];
731     unsigned int i;
732     memcpy(buffer, iv, 8);
733     for (i = 0; i + 8 <= data_len; i += 8)
734         mac_block(ctx, buffer, data + i);
735     if (i < data_len) {
736         memset(buf2, 0, 8);
737         memcpy(buf2, data + i, data_len - i);
738         mac_block(ctx, buffer, buf2);
739         i += 8;
740     }
741     if (i == 8) {
742         memset(buf2, 0, 8);
743         mac_block(ctx, buffer, buf2);
744     }
745     get_mac(buffer, mac_len, mac);
746     return 1;
747 }
748
749 /* Implements key meshing algorithm by modifing ctx and IV in place */
750 void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
751 {
752     unsigned char newkey[32];
753     /* Set static keymeshing key */
754     /* "Decrypt" key with keymeshing key */
755     gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4);
756     /* set new key */
757     gost_key(ctx, newkey);
758     OPENSSL_cleanse(newkey, sizeof(newkey));
759     /* Encrypt iv with new key */
760     if (iv != NULL ) {
761         unsigned char newiv[8];
762         gostcrypt(ctx, iv, newiv);
763         memcpy(iv, newiv, 8);
764         OPENSSL_cleanse(newiv, sizeof(newiv));
765     }
766 }
767
768 void acpkm_magma_key_meshing(gost_ctx * ctx)
769 {
770     unsigned char newkey[32];
771     int i;
772     for (i = 0; i < 4; i++) {
773         magmacrypt(ctx, ACPKM_D_const + 8 * i, newkey + 8 * i);
774     }
775     /* set new key */
776     magma_key(ctx, newkey);
777     OPENSSL_cleanse(newkey, sizeof(newkey));
778 }