summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/gost/gostr341194.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/gost/gostr341194.c')
-rw-r--r--src/lib/libcrypto/gost/gostr341194.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/lib/libcrypto/gost/gostr341194.c b/src/lib/libcrypto/gost/gostr341194.c
new file mode 100644
index 0000000000..706bf3d431
--- /dev/null
+++ b/src/lib/libcrypto/gost/gostr341194.c
@@ -0,0 +1,259 @@
1/* $OpenBSD: gostr341194.c,v 1.1 2014/11/09 19:17:13 miod 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 */
65static void swap_bytes(unsigned char *w, unsigned char *k)
66{
67 int i, j;
68 for (i = 0; i < 4; i++)
69 for (j = 0; j < 8; j++)
70 k[i + 4 * j] = w[8 * i + j];
71
72}
73
74/* was A_A */
75static void circle_xor8(const unsigned char *w, unsigned char *k)
76{
77 unsigned char buf[8];
78 int i;
79
80 memcpy(buf, w, 8);
81 memmove(k, w + 8, 24);
82 for (i = 0; i < 8; i++)
83 k[i + 24] = buf[i] ^ k[i];
84}
85
86/* was R_R */
87static void transform_3(unsigned char *data)
88{
89 unsigned short int acc;
90 acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) |
91 ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8);
92 memmove(data, data + 2, 30);
93 data[30] = acc & 0xff;
94 data[31] = acc >> 8;
95}
96
97/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
98static int add_blocks(int n, unsigned char *left, const unsigned char *right)
99{
100 int i;
101 int carry = 0;
102 int sum;
103
104 for (i = 0; i < n; i++) {
105 sum = (int)left[i] + (int)right[i] + carry;
106 left[i] = sum & 0xff;
107 carry = sum >> 8;
108 }
109 return carry;
110}
111
112/* Xor two sequences of bytes */
113static void xor_blocks(unsigned char *result, const unsigned char *a,
114 const unsigned char *b, size_t len)
115{
116 size_t i;
117 for (i = 0; i < len; i++)
118 result[i] = a[i] ^ b[i];
119}
120
121/*
122 * Calculate H(i+1) = Hash(Hi,Mi)
123 * Where H and M are 32 bytes long
124 */
125static int hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
126{
127 unsigned char U[32], W[32], V[32], S[32], Key[32];
128 int i;
129
130 /* Compute first key */
131 xor_blocks(W, H, M, 32);
132 swap_bytes(W, Key);
133 /* Encrypt first 8 bytes of H with first key */
134 Gost2814789_set_key(&c->cipher, Key, 256);
135 Gost2814789_encrypt(H, S, &c->cipher);
136
137 /* Compute second key */
138 circle_xor8(H, U);
139 circle_xor8(M, V);
140 circle_xor8(V, V);
141 xor_blocks(W, U, V, 32);
142 swap_bytes(W, Key);
143 /* encrypt second 8 bytes of H with second key */
144 Gost2814789_set_key(&c->cipher, Key, 256);
145 Gost2814789_encrypt(H+8, S+8, &c->cipher);
146
147 /* compute third key */
148 circle_xor8(U, U);
149 U[31] = ~U[31];
150 U[29] = ~U[29];
151 U[28] = ~U[28];
152 U[24] = ~U[24];
153 U[23] = ~U[23];
154 U[20] = ~U[20];
155 U[18] = ~U[18];
156 U[17] = ~U[17];
157 U[14] = ~U[14];
158 U[12] = ~U[12];
159 U[10] = ~U[10];
160 U[8] = ~U[8];
161 U[7] = ~U[7];
162 U[5] = ~U[5];
163 U[3] = ~U[3];
164 U[1] = ~U[1];
165 circle_xor8(V, V);
166 circle_xor8(V, V);
167 xor_blocks(W, U, V, 32);
168 swap_bytes(W, Key);
169 /* encrypt third 8 bytes of H with third key */
170 Gost2814789_set_key(&c->cipher, Key, 256);
171 Gost2814789_encrypt(H+16, S+16, &c->cipher);
172
173 /* Compute fourth key */
174 circle_xor8(U, U);
175 circle_xor8(V, V);
176 circle_xor8(V, V);
177 xor_blocks(W, U, V, 32);
178 swap_bytes(W, Key);
179 /* Encrypt last 8 bytes with fourth key */
180 Gost2814789_set_key(&c->cipher, Key, 256);
181 Gost2814789_encrypt(H+24, S+24, &c->cipher);
182
183 for (i = 0; i < 12; i++)
184 transform_3(S);
185 xor_blocks(S, S, M, 32);
186 transform_3(S);
187 xor_blocks(S, S, H, 32);
188 for (i = 0; i < 61; i++)
189 transform_3(S);
190 memcpy(H, S, 32);
191 return 1;
192}
193
194int GOSTR341194_Init(GOSTR341194_CTX *c, int nid)
195{
196 memset (c,0,sizeof(*c));
197 return Gost2814789_set_sbox(&c->cipher, nid);
198}
199
200static void GOSTR341194_block_data_order(GOSTR341194_CTX *ctx, const void *p, size_t num)
201{
202 int i;
203 for (i = 0; i < num; i++) {
204 hash_step(ctx, ctx->H, p);
205 add_blocks(32, ctx->S, p);
206 p += 32;
207 }
208}
209
210#define DATA_ORDER_IS_LITTLE_ENDIAN
211
212#define HASH_CBLOCK GOSTR341194_CBLOCK
213#define HASH_LONG GOSTR341194_LONG
214#define HASH_CTX GOSTR341194_CTX
215#define HASH_UPDATE GOSTR341194_Update
216#define HASH_TRANSFORM GOSTR341194_Transform
217#define HASH_NO_FINAL 1
218#define HASH_BLOCK_DATA_ORDER GOSTR341194_block_data_order
219
220#include "md32_common.h"
221
222int GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX * c)
223{
224 unsigned char *p = (unsigned char *)c->data;
225 unsigned char T[32];
226
227 if (c->num > 0) {
228 memset(p + c->num, 0, 32);
229 hash_step(c, c->H, p);
230 add_blocks(32, c->S, p);
231 }
232
233 p = T;
234 HOST_l2c(c->Nl, p);
235 HOST_l2c(c->Nh, p);
236 memset(p, 0, 32-8);
237 hash_step(c, c->H, T);
238 hash_step(c, c->H, c->S);
239
240 memcpy(md, c->H, 32);
241
242 return 1;
243}
244
245unsigned char *GOSTR341194(const unsigned char *d, size_t n, unsigned char *md, int nid)
246{
247 GOSTR341194_CTX c;
248 static unsigned char m[GOSTR341194_LENGTH];
249
250 if (md == NULL)
251 md = m;
252 if (!GOSTR341194_Init(&c, nid))
253 return 0;
254 GOSTR341194_Update(&c, d, n);
255 GOSTR341194_Final(md, &c);
256 OPENSSL_cleanse(&c, sizeof(c));
257 return (md);
258}
259#endif