]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost89.c
Delete .travis.yml
[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 decryption routine. Decrypts one 64-bit block */
332 void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
333 {
334     register word32 n1, n2;     /* As named in the GOST */
335     n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
336     n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
337
338     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
339     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
340     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
341     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
342     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
343     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
344     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
345     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
346
347     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
348     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
349     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
350     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
351     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
352     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
353     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
354     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
355
356     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
357     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
358     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
359     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
360     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
361     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
362     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
363     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
364
365     n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
366     n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
367     n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
368     n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
369     n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
370     n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
371     n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
372     n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
373
374     out[0] = (byte) (n2 & 0xff);
375     out[1] = (byte) ((n2 >> 8) & 0xff);
376     out[2] = (byte) ((n2 >> 16) & 0xff);
377     out[3] = (byte) (n2 >> 24);
378     out[4] = (byte) (n1 & 0xff);
379     out[5] = (byte) ((n1 >> 8) & 0xff);
380     out[6] = (byte) ((n1 >> 16) & 0xff);
381     out[7] = (byte) (n1 >> 24);
382 }
383
384
385 /* Encrypts several blocks in ECB mode */
386 void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
387 {
388     int i;
389     for (i = 0; i < blocks; i++) {
390         gostcrypt(c, clear, cipher);
391         clear += 8;
392         cipher += 8;
393     }
394 }
395
396 /* Decrypts several blocks in ECB mode */
397 void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks)
398 {
399     int i;
400     for (i = 0; i < blocks; i++) {
401         gostdecrypt(c, cipher, clear);
402         clear += 8;
403         cipher += 8;
404     }
405 }
406
407 /* Encrypts several full blocks in CFB mode using 8byte IV */
408 void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear,
409                   byte * cipher, int blocks)
410 {
411     byte cur_iv[8];
412     byte gamma[8];
413     int i, j;
414     const byte *in;
415     byte *out;
416     memcpy(cur_iv, iv, 8);
417     for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) {
418         gostcrypt(ctx, cur_iv, gamma);
419         for (j = 0; j < 8; j++) {
420             cur_iv[j] = out[j] = in[j] ^ gamma[j];
421         }
422     }
423 }
424
425 /* Decrypts several full blocks in CFB mode using 8byte IV */
426 void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher,
427                   byte * clear, int blocks)
428 {
429     byte cur_iv[8];
430     byte gamma[8];
431     int i, j;
432     const byte *in;
433     byte *out;
434     memcpy(cur_iv, iv, 8);
435     for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) {
436         gostcrypt(ctx, cur_iv, gamma);
437         for (j = 0; j < 8; j++) {
438             out[j] = (cur_iv[j] = in[j]) ^ gamma[j];
439         }
440     }
441 }
442
443 /* Encrypts one block using specified key */
444 void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
445                        byte * outblock)
446 {
447     gost_key(c, key);
448     gostcrypt(c, inblock, outblock);
449 }
450
451 /* Set 256 bit gost89 key into context */
452 void gost_key(gost_ctx * c, const byte * k)
453 {
454     int i, j;
455     RAND_priv_bytes((unsigned char *)c->mask, sizeof(c->mask));
456     for (i = 0, j = 0; i < 8; ++i, j += 4) {
457         c->key[i] =
458             (k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
459                                                          24)) - c->mask[i];
460     }
461 }
462
463 /* Set 256 bit Magma key into context */
464 void magma_key(gost_ctx * c, const byte * k)
465 {
466     int i, j;
467     RAND_priv_bytes((unsigned char *)c->mask, sizeof(c->mask));
468     for (i = 0, j = 0; i < 8; ++i, j += 4) {
469         c->key[i] =
470             (k[j + 3] | (k[j + 2] << 8) | (k[j + 1] << 16) | ((word32) k[j] <<
471                                                              24))  - c->mask[i];
472     }
473 }
474
475 void magma_master_key(gost_ctx *c, const byte *k) {
476     memcpy(c->master_key, k, sizeof(c->master_key));
477 }
478
479 /* Retrieve 256-bit gost89 key from context */
480 void gost_get_key(gost_ctx * c, byte * k)
481 {
482     int i, j;
483     for (i = 0, j = 0; i < 8; i++, j += 4) {
484         k[j] = (byte)((c->key[i] + c->mask[i]) & 0xFF);
485         k[j+1] = (byte)(((c->key[i] + c->mask[i]) >> 8 )& 0xFF);
486         k[j+2] = (byte)(((c->key[i] + c->mask[i]) >> 16) & 0xFF);
487         k[j+3] = (byte)(((c->key[i] + c->mask[i]) >> 24) & 0xFF);
488     }
489 }
490
491 /* Retrieve 256-bit magma key from context */
492 void magma_get_key(gost_ctx * c, byte * k)
493 {
494     int i, j;
495     for (i = 0, j = 0; i < 8; i++, j += 4) {
496         k[j + 3] = (byte) ((c->key[i] + c->mask[i]) & 0xFF);
497         k[j + 2] = (byte) (((c->key[i] + c->mask[i]) >> 8) & 0xFF);
498         k[j + 1] = (byte) (((c->key[i] + c->mask[i]) >> 16) & 0xFF);
499         k[j + 0] = (byte) (((c->key[i] + c->mask[i]) >> 24) & 0xFF);
500     }
501 }
502
503 /* Initalize context. Provides default value for subst_block */
504 void gost_init(gost_ctx * c, const gost_subst_block * b)
505 {
506     if (!b) {
507         b = &GostR3411_94_TestParamSet;
508     }
509     kboxinit(c, b);
510 }
511
512 /* Cleans up key from context */
513 void gost_destroy(gost_ctx * c)
514 {
515     OPENSSL_cleanse(c->master_key, sizeof(c->master_key));
516     OPENSSL_cleanse(c->key, sizeof(c->key));
517     OPENSSL_cleanse(c->mask, sizeof(c->mask));
518 }
519
520 /*
521  * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized
522  * with substitution blocks and key buffer - 8-byte mac state buffer block
523  * 8-byte block to process.
524  */
525 void mac_block(gost_ctx * c, byte * buffer, const byte * block)
526 {
527     register word32 n1, n2;     /* As named in the GOST */
528     int i;
529     for (i = 0; i < 8; i++) {
530         buffer[i] ^= block[i];
531     }
532     n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32)
533                                                              buffer[3] << 24);
534     n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32)
535                                                              buffer[7] << 24);
536     /* Instead of swapping halves, swap names each round */
537
538     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
539     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
540     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
541     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
542     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
543     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
544     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
545     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
546
547     n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
548     n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
549     n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
550     n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
551     n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
552     n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
553     n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
554     n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
555
556     buffer[0] = (byte) (n1 & 0xff);
557     buffer[1] = (byte) ((n1 >> 8) & 0xff);
558     buffer[2] = (byte) ((n1 >> 16) & 0xff);
559     buffer[3] = (byte) (n1 >> 24);
560     buffer[4] = (byte) (n2 & 0xff);
561     buffer[5] = (byte) ((n2 >> 8) & 0xff);
562     buffer[6] = (byte) ((n2 >> 16) & 0xff);
563     buffer[7] = (byte) (n2 >> 24);
564 }
565
566 /* Get mac with specified number of bits from MAC state buffer */
567 void get_mac(byte * buffer, int nbits, byte * out)
568 {
569     int nbytes = nbits >> 3;
570     int rembits = nbits & 7;
571     int mask = rembits ? ((1 < rembits) - 1) : 0;
572     int i;
573     for (i = 0; i < nbytes; i++)
574         out[i] = buffer[i];
575     if (rembits)
576         out[i] = buffer[i] & mask;
577 }
578
579 /*
580  * Compute mac of specified length (in bits) from data. Context should be
581  * initialized with key and subst blocks
582  */
583 int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data,
584              unsigned int data_len, unsigned char *mac)
585 {
586     byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
587     byte buf2[8];
588     unsigned int i;
589     for (i = 0; i + 8 <= data_len; i += 8)
590         mac_block(ctx, buffer, data + i);
591     if (i < data_len) {
592         memset(buf2, 0, 8);
593         memcpy(buf2, data + i, data_len - i);
594         mac_block(ctx, buffer, buf2);
595         i += 8;
596     }
597     if (i == 8) {
598         memset(buf2, 0, 8);
599         mac_block(ctx, buffer, buf2);
600     }
601     get_mac(buffer, mac_len, mac);
602     return 1;
603 }
604
605 /* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
606 int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv,
607                 const unsigned char *data, unsigned int data_len,
608                 unsigned char *mac)
609 {
610     byte buffer[8];
611     byte buf2[8];
612     unsigned int i;
613     memcpy(buffer, iv, 8);
614     for (i = 0; i + 8 <= data_len; i += 8)
615         mac_block(ctx, buffer, data + i);
616     if (i < data_len) {
617         memset(buf2, 0, 8);
618         memcpy(buf2, data + i, data_len - i);
619         mac_block(ctx, buffer, buf2);
620         i += 8;
621     }
622     if (i == 8) {
623         memset(buf2, 0, 8);
624         mac_block(ctx, buffer, buf2);
625     }
626     get_mac(buffer, mac_len, mac);
627     return 1;
628 }
629
630 /* Implements key meshing algorithm by modifing ctx and IV in place */
631 void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
632 {
633     unsigned char newkey[32];
634     /* Set static keymeshing key */
635     /* "Decrypt" key with keymeshing key */
636     gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4);
637     /* set new key */
638     gost_key(ctx, newkey);
639     OPENSSL_cleanse(newkey, sizeof(newkey));
640     /* Encrypt iv with new key */
641     if (iv != NULL ) {
642         unsigned char newiv[8];
643         gostcrypt(ctx, iv, newiv);
644         memcpy(iv, newiv, 8);
645         OPENSSL_cleanse(newiv, sizeof(newiv));
646     }
647 }
648
649 void acpkm_magma_key_meshing(gost_ctx * ctx)
650 {
651     unsigned char newkey[32];
652     int i, j;
653
654     for (i = 0; i < 4; i++) {
655         unsigned char buf[8], keybuf[8];
656         for (j = 0; j < 8; j++) {
657             buf[j] = ACPKM_D_const[8 * i + 7 - j];
658         }
659         gostcrypt(ctx, buf, keybuf);
660         memcpy(newkey + 8 * i, keybuf + 4, 4);
661         memcpy(newkey + 8 * i + 4, keybuf, 4);
662         OPENSSL_cleanse(keybuf, sizeof(keybuf));
663         OPENSSL_cleanse(buf, sizeof(buf));
664     }
665     /* set new key */
666     gost_key(ctx, newkey);
667     OPENSSL_cleanse(newkey, sizeof(newkey));
668 }