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