Coverage Report

Created: 2022-11-30 06:20

/src/openssl/engines/ccgost/gost89.c
Line
Count
Source (jump to first uncovered line)
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 "gost89.h"
12
/*-
13
   Substitution blocks from RFC 4357
14
15
   Note: our implementation of gost 28147-89 algorithm
16
   uses S-box matrix rotated 90 degrees counterclockwise, relative to
17
   examples given in RFC.
18
19
20
*/
21
22
/* Substitution blocks from test examples for GOST R 34.11-94*/
23
gost_subst_block GostR3411_94_TestParamSet = {
24
    {0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB,
25
     0X8, 0XC}
26
    ,
27
    {0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8,
28
     0X2, 0XC}
29
    ,
30
    {0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC,
31
     0XF, 0XE}
32
    ,
33
    {0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3,
34
     0XB, 0X2}
35
    ,
36
    {0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2,
37
     0X5, 0X3}
38
    ,
39
    {0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0,
40
     0X9, 0XB}
41
    ,
42
    {0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7,
43
     0X5, 0X9}
44
    ,
45
    {0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF,
46
     0X5, 0X3}
47
};
48
49
/* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
50
gost_subst_block GostR3411_94_CryptoProParamSet = {
51
    {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0,
52
     0x2, 0xC}
53
    ,
54
    {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2,
55
     0x9, 0xB}
56
    ,
57
    {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE,
58
     0xC, 0x3}
59
    ,
60
    {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD,
61
     0x3, 0x5}
62
    ,
63
    {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB,
64
     0x9, 0x3}
65
    ,
66
    {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA,
67
     0x8, 0xD}
68
    ,
69
    {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE,
70
     0xA, 0x8}
71
    ,
72
    {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2,
73
     0xB, 0xF}
74
};
75
76
/* Test paramset from GOST 28147 */
77
gost_subst_block Gost28147_TestParamSet = {
78
    {0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4,
79
     0x1, 0x8}
80
    ,
81
    {0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA,
82
     0x2, 0xD}
83
    ,
84
    {0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE,
85
     0x2, 0x4}
86
    ,
87
    {0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1,
88
     0xF, 0x4}
89
    ,
90
    {0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4,
91
     0x3, 0x8}
92
    ,
93
    {0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF,
94
     0x0, 0xB}
95
    ,
96
    {0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0,
97
     0xB, 0x5}
98
    ,
99
    {0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7,
100
     0xA, 0x6}
101
};
102
103
/* 1.2.643.2.2.31.1 */
104
gost_subst_block Gost28147_CryptoProParamSetA = {
105
    {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7,
106
     0xD, 0x4}
107
    ,
108
    {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3,
109
     0xB, 0xE}
110
    ,
111
    {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF,
112
     0xE, 0x6}
113
    ,
114
    {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7,
115
     0xA, 0x6}
116
    ,
117
    {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8,
118
     0x5, 0x6}
119
    ,
120
    {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7,
121
     0x1, 0x9}
122
    ,
123
    {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4,
124
     0xD, 0x1}
125
    ,
126
    {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0,
127
     0xD, 0x5}
128
};
129
130
/* 1.2.643.2.2.31.2 */
131
gost_subst_block Gost28147_CryptoProParamSetB = {
132
    {0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD,
133
     0x5, 0xC}
134
    ,
135
    {0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF,
136
     0x8, 0xE}
137
    ,
138
    {0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0,
139
     0x9, 0x5}
140
    ,
141
    {0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8,
142
     0xE, 0x3}
143
    ,
144
    {0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE,
145
     0x9, 0x8}
146
    ,
147
    {0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6,
148
     0x1, 0x4}
149
    ,
150
    {0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8,
151
     0x6, 0xE}
152
    ,
153
    {0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6,
154
     0x7, 0xF}
155
};
156
157
/* 1.2.643.2.2.31.3 */
158
gost_subst_block Gost28147_CryptoProParamSetC = {
159
    {0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9,
160
     0x3, 0x8}
161
    ,
162
    {0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1,
163
     0xC, 0x7}
164
    ,
165
    {0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0,
166
     0xF, 0xD}
167
    ,
168
    {0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF,
169
     0xA, 0x7}
170
    ,
171
    {0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF,
172
     0xC, 0x4}
173
    ,
174
    {0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE,
175
     0x1, 0xB}
176
    ,
177
    {0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA,
178
     0x6, 0x3}
179
    ,
180
    {0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7,
181
     0x6, 0x3}
182
};
183
184
/* 1.2.643.2.2.31.4 */
185
gost_subst_block Gost28147_CryptoProParamSetD = {
186
    {0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD,
187
     0x2, 0xE}
188
    ,
189
    {0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA,
190
     0x5, 0x7}
191
    ,
192
    {0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9,
193
     0xD, 0x6}
194
    ,
195
    {0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE,
196
     0xF, 0x1}
197
    ,
198
    {0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3,
199
     0xF, 0x8}
200
    ,
201
    {0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3,
202
     0x7, 0x2}
203
    ,
204
    {0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA,
205
     0x9, 0x1}
206
    ,
207
    {0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB,
208
     0x8, 0x3}
209
};
210
211
const byte CryptoProKeyMeshingKey[] = {
212
    0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
213
    0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
214
    0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
215
    0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
216
};
217
218
/* Initialization of gost_ctx subst blocks*/
219
static void kboxinit(gost_ctx * c, const gost_subst_block * b)
220
0
{
221
0
    int i;
222
223
0
    for (i = 0; i < 256; i++) {
224
0
        c->k87[i] = (word32) (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24;
225
0
        c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16;
226
0
        c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8;
227
0
        c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15];
228
229
0
    }
230
0
}
231
232
/* Part of GOST 28147 algorithm moved into separate function */
233
static word32 f(gost_ctx * c, word32 x)
234
0
{
235
0
    x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] |
236
0
        c->k43[x >> 8 & 255] | c->k21[x & 255];
237
    /* Rotate left 11 bits */
238
0
    return x << 11 | x >> (32 - 11);
239
0
}
240
241
/* Low-level encryption routine - encrypts one 64 bit block*/
242
void gostcrypt(gost_ctx * c, const byte * in, byte * out)
243
0
{
244
0
    register word32 n1, n2;     /* As named in the GOST */
245
0
    n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
246
0
    n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
247
    /* Instead of swapping halves, swap names each round */
248
249
0
    n2 ^= f(c, n1 + c->k[0]);
250
0
    n1 ^= f(c, n2 + c->k[1]);
251
0
    n2 ^= f(c, n1 + c->k[2]);
252
0
    n1 ^= f(c, n2 + c->k[3]);
253
0
    n2 ^= f(c, n1 + c->k[4]);
254
0
    n1 ^= f(c, n2 + c->k[5]);
255
0
    n2 ^= f(c, n1 + c->k[6]);
256
0
    n1 ^= f(c, n2 + c->k[7]);
257
258
0
    n2 ^= f(c, n1 + c->k[0]);
259
0
    n1 ^= f(c, n2 + c->k[1]);
260
0
    n2 ^= f(c, n1 + c->k[2]);
261
0
    n1 ^= f(c, n2 + c->k[3]);
262
0
    n2 ^= f(c, n1 + c->k[4]);
263
0
    n1 ^= f(c, n2 + c->k[5]);
264
0
    n2 ^= f(c, n1 + c->k[6]);
265
0
    n1 ^= f(c, n2 + c->k[7]);
266
267
0
    n2 ^= f(c, n1 + c->k[0]);
268
0
    n1 ^= f(c, n2 + c->k[1]);
269
0
    n2 ^= f(c, n1 + c->k[2]);
270
0
    n1 ^= f(c, n2 + c->k[3]);
271
0
    n2 ^= f(c, n1 + c->k[4]);
272
0
    n1 ^= f(c, n2 + c->k[5]);
273
0
    n2 ^= f(c, n1 + c->k[6]);
274
0
    n1 ^= f(c, n2 + c->k[7]);
275
276
0
    n2 ^= f(c, n1 + c->k[7]);
277
0
    n1 ^= f(c, n2 + c->k[6]);
278
0
    n2 ^= f(c, n1 + c->k[5]);
279
0
    n1 ^= f(c, n2 + c->k[4]);
280
0
    n2 ^= f(c, n1 + c->k[3]);
281
0
    n1 ^= f(c, n2 + c->k[2]);
282
0
    n2 ^= f(c, n1 + c->k[1]);
283
0
    n1 ^= f(c, n2 + c->k[0]);
284
285
0
    out[0] = (byte) (n2 & 0xff);
286
0
    out[1] = (byte) ((n2 >> 8) & 0xff);
287
0
    out[2] = (byte) ((n2 >> 16) & 0xff);
288
0
    out[3] = (byte) (n2 >> 24);
289
0
    out[4] = (byte) (n1 & 0xff);
290
0
    out[5] = (byte) ((n1 >> 8) & 0xff);
291
0
    out[6] = (byte) ((n1 >> 16) & 0xff);
292
0
    out[7] = (byte) (n1 >> 24);
293
0
}
294
295
/* Low-level decryption routine. Decrypts one 64-bit block */
296
void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
297
0
{
298
0
    register word32 n1, n2;     /* As named in the GOST */
299
0
    n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
300
0
    n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
301
302
0
    n2 ^= f(c, n1 + c->k[0]);
303
0
    n1 ^= f(c, n2 + c->k[1]);
304
0
    n2 ^= f(c, n1 + c->k[2]);
305
0
    n1 ^= f(c, n2 + c->k[3]);
306
0
    n2 ^= f(c, n1 + c->k[4]);
307
0
    n1 ^= f(c, n2 + c->k[5]);
308
0
    n2 ^= f(c, n1 + c->k[6]);
309
0
    n1 ^= f(c, n2 + c->k[7]);
310
311
0
    n2 ^= f(c, n1 + c->k[7]);
312
0
    n1 ^= f(c, n2 + c->k[6]);
313
0
    n2 ^= f(c, n1 + c->k[5]);
314
0
    n1 ^= f(c, n2 + c->k[4]);
315
0
    n2 ^= f(c, n1 + c->k[3]);
316
0
    n1 ^= f(c, n2 + c->k[2]);
317
0
    n2 ^= f(c, n1 + c->k[1]);
318
0
    n1 ^= f(c, n2 + c->k[0]);
319
320
0
    n2 ^= f(c, n1 + c->k[7]);
321
0
    n1 ^= f(c, n2 + c->k[6]);
322
0
    n2 ^= f(c, n1 + c->k[5]);
323
0
    n1 ^= f(c, n2 + c->k[4]);
324
0
    n2 ^= f(c, n1 + c->k[3]);
325
0
    n1 ^= f(c, n2 + c->k[2]);
326
0
    n2 ^= f(c, n1 + c->k[1]);
327
0
    n1 ^= f(c, n2 + c->k[0]);
328
329
0
    n2 ^= f(c, n1 + c->k[7]);
330
0
    n1 ^= f(c, n2 + c->k[6]);
331
0
    n2 ^= f(c, n1 + c->k[5]);
332
0
    n1 ^= f(c, n2 + c->k[4]);
333
0
    n2 ^= f(c, n1 + c->k[3]);
334
0
    n1 ^= f(c, n2 + c->k[2]);
335
0
    n2 ^= f(c, n1 + c->k[1]);
336
0
    n1 ^= f(c, n2 + c->k[0]);
337
338
0
    out[0] = (byte) (n2 & 0xff);
339
0
    out[1] = (byte) ((n2 >> 8) & 0xff);
340
0
    out[2] = (byte) ((n2 >> 16) & 0xff);
341
0
    out[3] = (byte) (n2 >> 24);
342
0
    out[4] = (byte) (n1 & 0xff);
343
0
    out[5] = (byte) ((n1 >> 8) & 0xff);
344
0
    out[6] = (byte) ((n1 >> 16) & 0xff);
345
0
    out[7] = (byte) (n1 >> 24);
346
0
}
347
348
/* Encrypts several blocks in ECB mode */
349
void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
350
0
{
351
0
    int i;
352
0
    for (i = 0; i < blocks; i++) {
353
0
        gostcrypt(c, clear, cipher);
354
0
        clear += 8;
355
0
        cipher += 8;
356
0
    }
357
0
}
358
359
/* Decrypts several blocks in ECB mode */
360
void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks)
361
0
{
362
0
    int i;
363
0
    for (i = 0; i < blocks; i++) {
364
0
        gostdecrypt(c, cipher, clear);
365
0
        clear += 8;
366
0
        cipher += 8;
367
0
    }
368
0
}
369
370
/* Encrypts several full blocks in CFB mode using 8byte IV */
371
void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear,
372
                  byte * cipher, int blocks)
373
0
{
374
0
    byte cur_iv[8];
375
0
    byte gamma[8];
376
0
    int i, j;
377
0
    const byte *in;
378
0
    byte *out;
379
0
    memcpy(cur_iv, iv, 8);
380
0
    for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) {
381
0
        gostcrypt(ctx, cur_iv, gamma);
382
0
        for (j = 0; j < 8; j++) {
383
0
            cur_iv[j] = out[j] = in[j] ^ gamma[j];
384
0
        }
385
0
    }
386
0
}
387
388
/* Decrypts several full blocks in CFB mode using 8byte IV */
389
void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher,
390
                  byte * clear, int blocks)
391
0
{
392
0
    byte cur_iv[8];
393
0
    byte gamma[8];
394
0
    int i, j;
395
0
    const byte *in;
396
0
    byte *out;
397
0
    memcpy(cur_iv, iv, 8);
398
0
    for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) {
399
0
        gostcrypt(ctx, cur_iv, gamma);
400
0
        for (j = 0; j < 8; j++) {
401
0
            out[j] = (cur_iv[j] = in[j]) ^ gamma[j];
402
0
        }
403
0
    }
404
0
}
405
406
/* Encrypts one block using specified key */
407
void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
408
                       byte * outblock)
409
0
{
410
0
    gost_key(c, key);
411
0
    gostcrypt(c, inblock, outblock);
412
0
}
413
414
/* Set 256 bit  key into context */
415
void gost_key(gost_ctx * c, const byte * k)
416
0
{
417
0
    int i, j;
418
0
    for (i = 0, j = 0; i < 8; i++, j += 4) {
419
0
        c->k[i] =
420
0
            k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
421
0
                                                         24);
422
0
    }
423
0
}
424
425
/* Retrieve 256-bit key from context */
426
void gost_get_key(gost_ctx * c, byte * k)
427
0
{
428
0
    int i, j;
429
0
    for (i = 0, j = 0; i < 8; i++, j += 4) {
430
0
        k[j] = (byte) (c->k[i] & 0xFF);
431
0
        k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF);
432
0
        k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF);
433
0
        k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF);
434
0
    }
435
0
}
436
437
/* Initalize context. Provides default value for subst_block */
438
void gost_init(gost_ctx * c, const gost_subst_block * b)
439
0
{
440
0
    if (!b) {
441
0
        b = &GostR3411_94_TestParamSet;
442
0
    }
443
0
    kboxinit(c, b);
444
0
}
445
446
/* Cleans up key from context */
447
void gost_destroy(gost_ctx * c)
448
0
{
449
0
    int i;
450
0
    for (i = 0; i < 8; i++)
451
0
        c->k[i] = 0;
452
0
}
453
454
/*
455
 * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized
456
 * with substitution blocks and key buffer - 8-byte mac state buffer block
457
 * 8-byte block to process.
458
 */
459
void mac_block(gost_ctx * c, byte * buffer, const byte * block)
460
0
{
461
0
    register word32 n1, n2;     /* As named in the GOST */
462
0
    int i;
463
0
    for (i = 0; i < 8; i++) {
464
0
        buffer[i] ^= block[i];
465
0
    }
466
0
    n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32)
467
0
                                                             buffer[3] << 24);
468
0
    n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32)
469
0
                                                             buffer[7] << 24);
470
    /* Instead of swapping halves, swap names each round */
471
472
0
    n2 ^= f(c, n1 + c->k[0]);
473
0
    n1 ^= f(c, n2 + c->k[1]);
474
0
    n2 ^= f(c, n1 + c->k[2]);
475
0
    n1 ^= f(c, n2 + c->k[3]);
476
0
    n2 ^= f(c, n1 + c->k[4]);
477
0
    n1 ^= f(c, n2 + c->k[5]);
478
0
    n2 ^= f(c, n1 + c->k[6]);
479
0
    n1 ^= f(c, n2 + c->k[7]);
480
481
0
    n2 ^= f(c, n1 + c->k[0]);
482
0
    n1 ^= f(c, n2 + c->k[1]);
483
0
    n2 ^= f(c, n1 + c->k[2]);
484
0
    n1 ^= f(c, n2 + c->k[3]);
485
0
    n2 ^= f(c, n1 + c->k[4]);
486
0
    n1 ^= f(c, n2 + c->k[5]);
487
0
    n2 ^= f(c, n1 + c->k[6]);
488
0
    n1 ^= f(c, n2 + c->k[7]);
489
490
0
    buffer[0] = (byte) (n1 & 0xff);
491
0
    buffer[1] = (byte) ((n1 >> 8) & 0xff);
492
0
    buffer[2] = (byte) ((n1 >> 16) & 0xff);
493
0
    buffer[3] = (byte) (n1 >> 24);
494
0
    buffer[4] = (byte) (n2 & 0xff);
495
0
    buffer[5] = (byte) ((n2 >> 8) & 0xff);
496
0
    buffer[6] = (byte) ((n2 >> 16) & 0xff);
497
0
    buffer[7] = (byte) (n2 >> 24);
498
0
}
499
500
/* Get mac with specified number of bits from MAC state buffer */
501
void get_mac(byte * buffer, int nbits, byte * out)
502
0
{
503
0
    int nbytes = nbits >> 3;
504
0
    int rembits = nbits & 7;
505
0
    int mask = rembits ? ((1 < rembits) - 1) : 0;
506
0
    int i;
507
0
    for (i = 0; i < nbytes; i++)
508
0
        out[i] = buffer[i];
509
0
    if (rembits)
510
0
        out[i] = buffer[i] & mask;
511
0
}
512
513
/*
514
 * Compute mac of specified length (in bits) from data. Context should be
515
 * initialized with key and subst blocks
516
 */
517
int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data,
518
             unsigned int data_len, unsigned char *mac)
519
0
{
520
0
    byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
521
0
    byte buf2[8];
522
0
    unsigned int i;
523
0
    for (i = 0; i + 8 <= data_len; i += 8)
524
0
        mac_block(ctx, buffer, data + i);
525
0
    if (i < data_len) {
526
0
        memset(buf2, 0, 8);
527
0
        memcpy(buf2, data + i, data_len - i);
528
0
        mac_block(ctx, buffer, buf2);
529
0
        i += 8;
530
0
    }
531
0
    if (i == 8) {
532
0
        memset(buf2, 0, 8);
533
0
        mac_block(ctx, buffer, buf2);
534
0
    }
535
0
    get_mac(buffer, mac_len, mac);
536
0
    return 1;
537
0
}
538
539
/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
540
int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv,
541
                const unsigned char *data, unsigned int data_len,
542
                unsigned char *mac)
543
0
{
544
0
    byte buffer[8];
545
0
    byte buf2[8];
546
0
    unsigned int i;
547
0
    memcpy(buffer, iv, 8);
548
0
    for (i = 0; i + 8 <= data_len; i += 8)
549
0
        mac_block(ctx, buffer, data + i);
550
0
    if (i < data_len) {
551
0
        memset(buf2, 0, 8);
552
0
        memcpy(buf2, data + i, data_len - i);
553
0
        mac_block(ctx, buffer, buf2);
554
0
        i += 8;
555
0
    }
556
0
    if (i == 8) {
557
0
        memset(buf2, 0, 8);
558
0
        mac_block(ctx, buffer, buf2);
559
0
    }
560
0
    get_mac(buffer, mac_len, mac);
561
0
    return 1;
562
0
}
563
564
/* Implements key meshing algorithm by modifing ctx and IV in place */
565
void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
566
0
{
567
0
    unsigned char newkey[32], newiv[8];
568
    /* Set static keymeshing key */
569
    /* "Decrypt" key with keymeshing key */
570
0
    gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4);
571
    /* set new key */
572
0
    gost_key(ctx, newkey);
573
    /* Encrypt iv with new key */
574
0
    gostcrypt(ctx, iv, newiv);
575
0
    memcpy(iv, newiv, 8);
576
0
}