1 /* $OpenBSD: gostr341194.c,v 1.5 2015/09/10 15:56:25 jsing Exp $ */
2 /*
3  * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4  * Copyright (c) 2005-2006 Cryptocom LTD
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  *    software must display the following acknowledgment:
20  *    "This product includes software developed by the OpenSSL Project
21  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22  *
23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24  *    endorse or promote products derived from this software without
25  *    prior written permission. For written permission, please contact
26  *    openssl-core@openssl.org.
27  *
28  * 5. Products derived from this software may not be called "OpenSSL"
29  *    nor may "OpenSSL" appear in their names without prior written
30  *    permission of the OpenSSL Project.
31  *
32  * 6. Redistributions of any form whatsoever must retain the following
33  *    acknowledgment:
34  *    "This product includes software developed by the OpenSSL Project
35  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48  * OF THE POSSIBILITY OF SUCH DAMAGE.
49  * ====================================================================
50  */
51 
52 #include <string.h>
53 
54 #include <openssl/opensslconf.h>
55 
56 #ifndef OPENSSL_NO_GOST
57 #include <openssl/crypto.h>
58 #include <openssl/objects.h>
59 #include <openssl/gost.h>
60 
61 #include "gost_locl.h"
62 
63 /* Following functions are various bit meshing routines used in
64  * GOST R 34.11-94 algorithms */
65 static void
swap_bytes(unsigned char * w,unsigned char * k)66 swap_bytes(unsigned char *w, unsigned char *k)
67 {
68 	int i, j;
69 
70 	for (i = 0; i < 4; i++)
71 		for (j = 0; j < 8; j++)
72 			k[i + 4 * j] = w[8 * i + j];
73 }
74 
75 /* was A_A */
76 static void
circle_xor8(const unsigned char * w,unsigned char * k)77 circle_xor8(const unsigned char *w, unsigned char *k)
78 {
79 	unsigned char buf[8];
80 	int i;
81 
82 	memcpy(buf, w, 8);
83 	memmove(k, w + 8, 24);
84 	for (i = 0; i < 8; i++)
85 		k[i + 24] = buf[i] ^ k[i];
86 }
87 
88 /* was R_R */
89 static void
transform_3(unsigned char * data)90 transform_3(unsigned char *data)
91 {
92 	unsigned short int acc;
93 
94 	acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) |
95 	     ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8);
96 	memmove(data, data + 2, 30);
97 	data[30] = acc & 0xff;
98 	data[31] = acc >> 8;
99 }
100 
101 /* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
102 static int
add_blocks(int n,unsigned char * left,const unsigned char * right)103 add_blocks(int n, unsigned char *left, const unsigned char *right)
104 {
105 	int i;
106 	int carry = 0;
107 	int sum;
108 
109 	for (i = 0; i < n; i++) {
110 		sum = (int)left[i] + (int)right[i] + carry;
111 		left[i] = sum & 0xff;
112 		carry = sum >> 8;
113 	}
114 	return carry;
115 }
116 
117 /* Xor two sequences of bytes */
118 static void
xor_blocks(unsigned char * result,const unsigned char * a,const unsigned char * b,size_t len)119 xor_blocks(unsigned char *result, const unsigned char *a,
120     const unsigned char *b, size_t len)
121 {
122 	size_t i;
123 
124 	for (i = 0; i < len; i++)
125 		result[i] = a[i] ^ b[i];
126 }
127 
128 /*
129  * 	Calculate H(i+1) = Hash(Hi,Mi)
130  * 	Where H and M are 32 bytes long
131  */
132 static int
hash_step(GOSTR341194_CTX * c,unsigned char * H,const unsigned char * M)133 hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
134 {
135 	unsigned char U[32], W[32], V[32], S[32], Key[32];
136 	int i;
137 
138 	/* Compute first key */
139 	xor_blocks(W, H, M, 32);
140 	swap_bytes(W, Key);
141 	/* Encrypt first 8 bytes of H with first key */
142 	Gost2814789_set_key(&c->cipher, Key, 256);
143 	Gost2814789_encrypt(H, S, &c->cipher);
144 
145 	/* Compute second key */
146 	circle_xor8(H, U);
147 	circle_xor8(M, V);
148 	circle_xor8(V, V);
149 	xor_blocks(W, U, V, 32);
150 	swap_bytes(W, Key);
151 	/* encrypt second 8 bytes of H with second key */
152 	Gost2814789_set_key(&c->cipher, Key, 256);
153 	Gost2814789_encrypt(H+8, S+8, &c->cipher);
154 
155 	/* compute third key */
156 	circle_xor8(U, U);
157 	U[31] = ~U[31];
158 	U[29] = ~U[29];
159 	U[28] = ~U[28];
160 	U[24] = ~U[24];
161 	U[23] = ~U[23];
162 	U[20] = ~U[20];
163 	U[18] = ~U[18];
164 	U[17] = ~U[17];
165 	U[14] = ~U[14];
166 	U[12] = ~U[12];
167 	U[10] = ~U[10];
168 	U[8] = ~U[8];
169 	U[7] = ~U[7];
170 	U[5] = ~U[5];
171 	U[3] = ~U[3];
172 	U[1] = ~U[1];
173 	circle_xor8(V, V);
174 	circle_xor8(V, V);
175 	xor_blocks(W, U, V, 32);
176 	swap_bytes(W, Key);
177 	/* encrypt third 8 bytes of H with third key */
178 	Gost2814789_set_key(&c->cipher, Key, 256);
179 	Gost2814789_encrypt(H+16, S+16, &c->cipher);
180 
181 	/* Compute fourth key */
182 	circle_xor8(U, U);
183 	circle_xor8(V, V);
184 	circle_xor8(V, V);
185 	xor_blocks(W, U, V, 32);
186 	swap_bytes(W, Key);
187 	/* Encrypt last 8 bytes with fourth key */
188 	Gost2814789_set_key(&c->cipher, Key, 256);
189 	Gost2814789_encrypt(H+24, S+24, &c->cipher);
190 
191 	for (i = 0; i < 12; i++)
192 		transform_3(S);
193 	xor_blocks(S, S, M, 32);
194 	transform_3(S);
195 	xor_blocks(S, S, H, 32);
196 	for (i = 0; i < 61; i++)
197 		transform_3(S);
198 	memcpy(H, S, 32);
199 	return 1;
200 }
201 
202 int
GOSTR341194_Init(GOSTR341194_CTX * c,int nid)203 GOSTR341194_Init(GOSTR341194_CTX *c, int nid)
204 {
205 	memset(c, 0, sizeof(*c));
206 	return Gost2814789_set_sbox(&c->cipher, nid);
207 }
208 
209 static void
GOSTR341194_block_data_order(GOSTR341194_CTX * ctx,const unsigned char * p,size_t num)210 GOSTR341194_block_data_order(GOSTR341194_CTX *ctx, const unsigned char *p,
211     size_t num)
212 {
213 	int i;
214 
215 	for (i = 0; i < num; i++) {
216 		hash_step(ctx, ctx->H, p);
217 		add_blocks(32, ctx->S, p);
218 		p += 32;
219 	}
220 }
221 
222 #define DATA_ORDER_IS_LITTLE_ENDIAN
223 
224 #define HASH_CBLOCK	GOSTR341194_CBLOCK
225 #define HASH_LONG	GOSTR341194_LONG
226 #define HASH_CTX	GOSTR341194_CTX
227 #define HASH_UPDATE	GOSTR341194_Update
228 #define HASH_TRANSFORM	GOSTR341194_Transform
229 #define HASH_NO_FINAL	1
230 #define HASH_BLOCK_DATA_ORDER	GOSTR341194_block_data_order
231 
232 #include "md32_common.h"
233 
234 int
GOSTR341194_Final(unsigned char * md,GOSTR341194_CTX * c)235 GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX * c)
236 {
237 	unsigned char *p = (unsigned char *)c->data;
238 	unsigned char T[32];
239 
240 	if (c->num > 0) {
241 		memset(p + c->num, 0, 32 - c->num);
242 		hash_step(c, c->H, p);
243 		add_blocks(32, c->S, p);
244 	}
245 
246 	p = T;
247 	HOST_l2c(c->Nl, p);
248 	HOST_l2c(c->Nh, p);
249 	memset(p, 0, 32 - 8);
250 	hash_step(c, c->H, T);
251 	hash_step(c, c->H, c->S);
252 
253 	memcpy(md, c->H, 32);
254 
255 	return 1;
256 }
257 
258 unsigned char *
GOSTR341194(const unsigned char * d,size_t n,unsigned char * md,int nid)259 GOSTR341194(const unsigned char *d, size_t n, unsigned char *md, int nid)
260 {
261 	GOSTR341194_CTX c;
262 	static unsigned char m[GOSTR341194_LENGTH];
263 
264 	if (md == NULL)
265 		md = m;
266 	if (!GOSTR341194_Init(&c, nid))
267 		return 0;
268 	GOSTR341194_Update(&c, d, n);
269 	GOSTR341194_Final(md, &c);
270 	explicit_bzero(&c, sizeof(c));
271 	return (md);
272 }
273 #endif
274