summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/gost/gost2814789.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/gost/gost2814789.c')
-rw-r--r--src/lib/libcrypto/gost/gost2814789.c471
1 files changed, 0 insertions, 471 deletions
diff --git a/src/lib/libcrypto/gost/gost2814789.c b/src/lib/libcrypto/gost/gost2814789.c
deleted file mode 100644
index e285413ed4..0000000000
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/* $OpenBSD: gost2814789.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/objects.h>
58#include <openssl/gost.h>
59
60#include "gost_locl.h"
61
62static inline unsigned int
63f(const GOST2814789_KEY *c, unsigned int x)
64{
65 return c->k87[(x>>24) & 255] | c->k65[(x>>16) & 255]|
66 c->k43[(x>> 8) & 255] | c->k21[(x ) & 255];
67}
68
69void
70Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
71 const GOST2814789_KEY *key)
72{
73 unsigned int n1, n2; /* As named in the GOST */
74
75 c2l(in, n1);
76 c2l(in, n2);
77
78 /* Instead of swapping halves, swap names each round */
79 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
80 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
81 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
82 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
83
84 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
85 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
86 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
87 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
88
89 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
90 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
91 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
92 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
93
94 n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
95 n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
96 n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
97 n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
98
99 l2c(n2, out);
100 l2c(n1, out);
101}
102
103void
104Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
105 const GOST2814789_KEY *key)
106{
107 unsigned int n1, n2; /* As named in the GOST */
108
109 c2l(in, n1);
110 c2l(in, n2);
111
112 /* Instead of swapping halves, swap names each round */
113 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
114 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
115 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
116 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
117
118 n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
119 n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
120 n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
121 n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
122
123 n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
124 n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
125 n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
126 n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
127
128 n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
129 n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
130 n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
131 n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
132
133 l2c(n2, out);
134 l2c(n1, out);
135}
136
137static void
138Gost2814789_mac(const unsigned char *in, unsigned char *mac,
139 GOST2814789_KEY *key)
140{
141 unsigned int n1, n2; /* As named in the GOST */
142 unsigned char *p;
143 int i;
144
145 for (i = 0; i < 8; i++)
146 mac[i] ^= in[i];
147
148 p = mac;
149 c2l(p, n1);
150 c2l(p, n2);
151
152 /* Instead of swapping halves, swap names each round */
153 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
154 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
155 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
156 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
157
158 n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
159 n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
160 n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
161 n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
162
163 p = mac;
164 l2c(n1, p);
165 l2c(n2, p);
166}
167
168void
169Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
170 GOST2814789_KEY *key, const int enc)
171{
172 if (key->key_meshing && key->count == 1024) {
173 Gost2814789_cryptopro_key_mesh(key);
174 key->count = 0;
175 }
176
177 if (enc)
178 Gost2814789_encrypt(in, out, key);
179 else
180 Gost2814789_decrypt(in, out, key);
181}
182
183static inline void
184Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key)
185{
186 if (key->key_meshing && key->count == 1024) {
187 Gost2814789_cryptopro_key_mesh(key);
188 Gost2814789_encrypt(iv, iv, key);
189 key->count = 0;
190 }
191 Gost2814789_encrypt(iv, iv, key);
192 key->count += 8;
193}
194
195static inline void
196Gost2814789_mac_mesh(const unsigned char *data, unsigned char *mac,
197 GOST2814789_KEY *key)
198{
199 if (key->key_meshing && key->count == 1024) {
200 Gost2814789_cryptopro_key_mesh(key);
201 key->count = 0;
202 }
203 Gost2814789_mac(data, mac, key);
204 key->count += 8;
205}
206
207void
208Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out,
209 size_t len, GOST2814789_KEY *key, unsigned char *ivec, int *num,
210 const int enc)
211{
212 unsigned int n;
213 size_t l = 0;
214
215 n = *num;
216
217 if (enc) {
218#if !defined(OPENSSL_SMALL_FOOTPRINT)
219 if (8 % sizeof(size_t) == 0) do { /* always true actually */
220 while (n && len) {
221 *(out++) = ivec[n] ^= *(in++);
222 --len;
223 n = (n + 1) % 8;
224 }
225#ifdef __STRICT_ALIGNMENT
226 if (((size_t)in | (size_t)out | (size_t)ivec) %
227 sizeof(size_t) != 0)
228 break;
229#endif
230 while (len >= 8) {
231 Gost2814789_encrypt_mesh(ivec, key);
232 for (; n < 8; n += sizeof(size_t)) {
233 *(size_t*)(out + n) =
234 *(size_t*)(ivec + n) ^=
235 *(size_t*)(in + n);
236 }
237 len -= 8;
238 out += 8;
239 in += 8;
240 n = 0;
241 }
242 if (len) {
243 Gost2814789_encrypt_mesh(ivec, key);
244 while (len--) {
245 out[n] = ivec[n] ^= in[n];
246 ++n;
247 }
248 }
249 *num = n;
250 return;
251 } while (0);
252 /* the rest would be commonly eliminated by x86* compiler */
253#endif
254 while (l<len) {
255 if (n == 0) {
256 Gost2814789_encrypt_mesh(ivec, key);
257 }
258 out[l] = ivec[n] ^= in[l];
259 ++l;
260 n = (n + 1) % 8;
261 }
262 *num = n;
263 } else {
264#if !defined(OPENSSL_SMALL_FOOTPRINT)
265 if (8 % sizeof(size_t) == 0) do { /* always true actually */
266 while (n && len) {
267 unsigned char c;
268
269 *(out++) = ivec[n] ^ (c = *(in++));
270 ivec[n] = c;
271 --len;
272 n = (n + 1) % 8;
273 }
274#ifdef __STRICT_ALIGNMENT
275 if (((size_t)in | (size_t)out | (size_t)ivec) %
276 sizeof(size_t) != 0)
277 break;
278#endif
279 while (len >= 8) {
280 Gost2814789_encrypt_mesh(ivec, key);
281 for (; n < 8; n += sizeof(size_t)) {
282 size_t t = *(size_t*)(in + n);
283 *(size_t*)(out + n) =
284 *(size_t*)(ivec + n) ^ t;
285 *(size_t*)(ivec + n) = t;
286 }
287 len -= 8;
288 out += 8;
289 in += 8;
290 n = 0;
291 }
292 if (len) {
293 Gost2814789_encrypt_mesh(ivec, key);
294 while (len--) {
295 unsigned char c;
296
297 out[n] = ivec[n] ^ (c = in[n]);
298 ivec[n] = c;
299 ++n;
300 }
301 }
302 *num = n;
303 return;
304 } while (0);
305 /* the rest would be commonly eliminated by x86* compiler */
306#endif
307 while (l < len) {
308 unsigned char c;
309
310 if (n == 0) {
311 Gost2814789_encrypt_mesh(ivec, key);
312 }
313 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
314 ++l;
315 n = (n + 1) % 8;
316 }
317 *num = n;
318 }
319}
320
321static inline void
322Gost2814789_cnt_next(unsigned char *ivec, unsigned char *out,
323 GOST2814789_KEY *key)
324{
325 unsigned char *p = ivec, *p2 = ivec;
326 unsigned int val, val2;
327
328 if (key->count == 0)
329 Gost2814789_encrypt(ivec, ivec, key);
330
331 if (key->key_meshing && key->count == 1024) {
332 Gost2814789_cryptopro_key_mesh(key);
333 Gost2814789_encrypt(ivec, ivec, key);
334 key->count = 0;
335 }
336
337 c2l(p, val);
338 val2 = val + 0x01010101;
339 l2c(val2, p2);
340
341 c2l(p, val);
342 val2 = val + 0x01010104;
343 if (val > val2) /* overflow */
344 val2++;
345 l2c(val2, p2);
346
347 Gost2814789_encrypt(ivec, out, key);
348 key->count += 8;
349}
350
351void
352Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, size_t len,
353 GOST2814789_KEY *key, unsigned char *ivec, unsigned char *cnt_buf, int *num)
354{
355 unsigned int n;
356 size_t l = 0;
357
358 n = *num;
359
360#if !defined(OPENSSL_SMALL_FOOTPRINT)
361 if (8 % sizeof(size_t) == 0) do { /* always true actually */
362 while (n && len) {
363 *(out++) = *(in++) ^ cnt_buf[n];
364 --len;
365 n = (n + 1) % 8;
366 }
367
368#ifdef __STRICT_ALIGNMENT
369 if (((size_t)in | (size_t)out | (size_t)ivec) %
370 sizeof(size_t) != 0)
371 break;
372#endif
373 while (len >= 8) {
374 Gost2814789_cnt_next(ivec, cnt_buf, key);
375 for (; n < 8; n += sizeof(size_t))
376 *(size_t *)(out + n) = *(size_t *)(in + n) ^
377 *(size_t *)(cnt_buf + n);
378 len -= 8;
379 out += 8;
380 in += 8;
381 n = 0;
382 }
383 if (len) {
384 Gost2814789_cnt_next(ivec, cnt_buf, key);
385 while (len--) {
386 out[n] = in[n] ^ cnt_buf[n];
387 ++n;
388 }
389 }
390 *num = n;
391 return;
392 } while(0);
393 /* the rest would be commonly eliminated by x86* compiler */
394#endif
395 while (l < len) {
396 if (n==0)
397 Gost2814789_cnt_next(ivec, cnt_buf, key);
398 out[l] = in[l] ^ cnt_buf[n];
399 ++l;
400 n = (n + 1) % 8;
401 }
402
403 *num=n;
404}
405
406int
407GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid)
408{
409 c->Nl = c->Nh = c->num = 0;
410 memset(c->mac, 0, 8);
411 return Gost2814789_set_sbox(&c->cipher, nid);
412}
413
414static void
415GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx,
416 const unsigned char *p, size_t num)
417{
418 int i;
419
420 for (i = 0; i < num; i++) {
421 Gost2814789_mac_mesh(p, ctx->mac, &ctx->cipher);
422 p += 8;
423 }
424}
425
426#define DATA_ORDER_IS_LITTLE_ENDIAN
427
428#define HASH_CBLOCK GOST2814789IMIT_CBLOCK
429#define HASH_LONG GOST2814789IMIT_LONG
430#define HASH_CTX GOST2814789IMIT_CTX
431#define HASH_UPDATE GOST2814789IMIT_Update
432#define HASH_TRANSFORM GOST2814789IMIT_Transform
433#define HASH_NO_FINAL 1
434#define HASH_BLOCK_DATA_ORDER GOST2814789IMIT_block_data_order
435
436#include "md32_common.h"
437
438int
439GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c)
440{
441 if (c->num) {
442 memset(c->data + c->num, 0, 8 - c->num);
443 Gost2814789_mac_mesh(c->data, c->mac, &c->cipher);
444 }
445 if (c->Nl <= 8 * 8 && c->Nl > 0 && c->Nh == 0) {
446 memset(c->data, 0, 8);
447 Gost2814789_mac_mesh(c->data, c->mac, &c->cipher);
448 }
449 memcpy(md, c->mac, 4);
450 return 1;
451}
452
453unsigned char *
454GOST2814789IMIT(const unsigned char *d, size_t n, unsigned char *md, int nid,
455 const unsigned char *key, const unsigned char *iv)
456{
457 GOST2814789IMIT_CTX c;
458 static unsigned char m[GOST2814789IMIT_LENGTH];
459
460 if (md == NULL)
461 md = m;
462 GOST2814789IMIT_Init(&c, nid);
463 memcpy(c.mac, iv, 8);
464 Gost2814789_set_key(&c.cipher, key, 256);
465 GOST2814789IMIT_Update(&c, d, n);
466 GOST2814789IMIT_Final(md, &c);
467 explicit_bzero(&c, sizeof(c));
468 return (md);
469}
470
471#endif