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.c270
1 files changed, 146 insertions, 124 deletions
diff --git a/src/lib/libcrypto/gost/gost2814789.c b/src/lib/libcrypto/gost/gost2814789.c
index b80f692f10..1c11ddd93e 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gost2814789.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */ 1/* $OpenBSD: gost2814789.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4 * Copyright (c) 2005-2006 Cryptocom LTD 4 * Copyright (c) 2005-2006 Cryptocom LTD
@@ -59,16 +59,19 @@
59 59
60#include "gost_locl.h" 60#include "gost_locl.h"
61 61
62static inline unsigned int f(const GOST2814789_KEY *c, unsigned int x) 62static inline unsigned int
63f(const GOST2814789_KEY *c, unsigned int x)
63{ 64{
64 return c->k87[(x>>24) & 255] | c->k65[(x>>16) & 255]| 65 return c->k87[(x>>24) & 255] | c->k65[(x>>16) & 255]|
65 c->k43[(x>> 8) & 255] | c->k21[(x ) & 255]; 66 c->k43[(x>> 8) & 255] | c->k21[(x ) & 255];
66} 67}
67 68
68void Gost2814789_encrypt(const unsigned char *in, unsigned char *out, 69void
69 const GOST2814789_KEY *key) 70Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
71 const GOST2814789_KEY *key)
70{ 72{
71 unsigned int n1, n2; /* As named in the GOST */ 73 unsigned int n1, n2; /* As named in the GOST */
74
72 c2l(in, n1); 75 c2l(in, n1);
73 c2l(in, n2); 76 c2l(in, n2);
74 77
@@ -97,10 +100,12 @@ void Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
97 l2c(n1, out); 100 l2c(n1, out);
98} 101}
99 102
100void Gost2814789_decrypt(const unsigned char *in, unsigned char *out, 103void
101 const GOST2814789_KEY *key) 104Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
105 const GOST2814789_KEY *key)
102{ 106{
103 unsigned int n1, n2; /* As named in the GOST */ 107 unsigned int n1, n2; /* As named in the GOST */
108
104 c2l(in, n1); 109 c2l(in, n1);
105 c2l(in, n2); 110 c2l(in, n2);
106 111
@@ -129,9 +134,9 @@ void Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
129 l2c(n1, out); 134 l2c(n1, out);
130} 135}
131 136
132static void Gost2814789_mac(const unsigned char *in, 137static void
133 unsigned char *mac, 138Gost2814789_mac(const unsigned char *in, unsigned char *mac,
134 GOST2814789_KEY *key) 139 GOST2814789_KEY *key)
135{ 140{
136 unsigned int n1, n2; /* As named in the GOST */ 141 unsigned int n1, n2; /* As named in the GOST */
137 unsigned char *p; 142 unsigned char *p;
@@ -160,9 +165,9 @@ static void Gost2814789_mac(const unsigned char *in,
160 l2c(n2, p); 165 l2c(n2, p);
161} 166}
162 167
163 168void
164void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out, 169Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
165 GOST2814789_KEY *key, const int enc) 170 GOST2814789_KEY *key, const int enc)
166{ 171{
167 if (key->key_meshing && key->count == 1024) { 172 if (key->key_meshing && key->count == 1024) {
168 Gost2814789_cryptopro_key_mesh(key); 173 Gost2814789_cryptopro_key_mesh(key);
@@ -175,7 +180,8 @@ void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
175 Gost2814789_decrypt(in, out, key); 180 Gost2814789_decrypt(in, out, key);
176} 181}
177 182
178static inline void Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key) 183static inline void
184Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key)
179{ 185{
180 if (key->key_meshing && key->count == 1024) { 186 if (key->key_meshing && key->count == 1024) {
181 Gost2814789_cryptopro_key_mesh(key); 187 Gost2814789_cryptopro_key_mesh(key);
@@ -186,9 +192,9 @@ static inline void Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *
186 key->count += 8; 192 key->count += 8;
187} 193}
188 194
189static inline void Gost2814789_mac_mesh(const unsigned char *data, 195static inline void
190 unsigned char *mac, 196Gost2814789_mac_mesh(const unsigned char *data, unsigned char *mac,
191 GOST2814789_KEY *key) 197 GOST2814789_KEY *key)
192{ 198{
193 if (key->key_meshing && key->count == 1024) { 199 if (key->key_meshing && key->count == 1024) {
194 Gost2814789_cryptopro_key_mesh(key); 200 Gost2814789_cryptopro_key_mesh(key);
@@ -198,115 +204,125 @@ static inline void Gost2814789_mac_mesh(const unsigned char *data,
198 key->count += 8; 204 key->count += 8;
199} 205}
200 206
201void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out, 207void
202 size_t len, GOST2814789_KEY *key, 208Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out,
203 unsigned char *ivec, int *num, const int enc) 209 size_t len, GOST2814789_KEY *key, unsigned char *ivec, int *num,
210 const int enc)
204{ 211{
205 unsigned int n; 212 unsigned int n;
206 size_t l = 0; 213 size_t l = 0;
207 214
208 OPENSSL_assert(in && out && key && ivec && num); 215 OPENSSL_assert(in && out && key && ivec && num);
209 216
210 n = *num; 217 n = *num;
211 218
212 if (enc) { 219 if (enc) {
213#if !defined(OPENSSL_SMALL_FOOTPRINT) 220#if !defined(OPENSSL_SMALL_FOOTPRINT)
214 if (8%sizeof(size_t) == 0) do { /* always true actually */ 221 if (8 % sizeof(size_t) == 0) do { /* always true actually */
215 while (n && len) { 222 while (n && len) {
216 *(out++) = ivec[n] ^= *(in++); 223 *(out++) = ivec[n] ^= *(in++);
217 --len; 224 --len;
218 n = (n+1) % 8; 225 n = (n + 1) % 8;
219 } 226 }
220#ifdef __STRICT_ALIGNMENT 227#ifdef __STRICT_ALIGNMENT
221 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) 228 if (((size_t)in | (size_t)out | (size_t)ivec) %
222 break; 229 sizeof(size_t) != 0)
230 break;
223#endif 231#endif
224 while (len>=8) { 232 while (len >= 8) {
225 Gost2814789_encrypt_mesh(ivec, key); 233 Gost2814789_encrypt_mesh(ivec, key);
226 for (; n<8; n+=sizeof(size_t)) { 234 for (; n < 8; n += sizeof(size_t)) {
227 *(size_t*)(out+n) = 235 *(size_t*)(out + n) =
228 *(size_t*)(ivec+n) ^= *(size_t*)(in+n); 236 *(size_t*)(ivec + n) ^=
237 *(size_t*)(in + n);
238 }
239 len -= 8;
240 out += 8;
241 in += 8;
242 n = 0;
229 } 243 }
230 len -= 8; 244 if (len) {
231 out += 8; 245 Gost2814789_encrypt_mesh(ivec, key);
232 in += 8; 246 while (len--) {
233 n = 0; 247 out[n] = ivec[n] ^= in[n];
234 } 248 ++n;
235 if (len) { 249 }
236 Gost2814789_encrypt_mesh(ivec, key);
237 while (len--) {
238 out[n] = ivec[n] ^= in[n];
239 ++n;
240 } 250 }
241 } 251 *num = n;
242 *num = n; 252 return;
243 return; 253 } while (0);
244 } while (0); 254 /* the rest would be commonly eliminated by x86* compiler */
245 /* the rest would be commonly eliminated by x86* compiler */
246#endif 255#endif
247 while (l<len) { 256 while (l<len) {
248 if (n == 0) { 257 if (n == 0) {
249 Gost2814789_encrypt_mesh(ivec, key); 258 Gost2814789_encrypt_mesh(ivec, key);
259 }
260 out[l] = ivec[n] ^= in[l];
261 ++l;
262 n = (n + 1) % 8;
250 } 263 }
251 out[l] = ivec[n] ^= in[l]; 264 *num = n;
252 ++l; 265 } else {
253 n = (n+1) % 8;
254 }
255 *num = n;
256 } else {
257#if !defined(OPENSSL_SMALL_FOOTPRINT) 266#if !defined(OPENSSL_SMALL_FOOTPRINT)
258 if (8%sizeof(size_t) == 0) do { /* always true actually */ 267 if (8 % sizeof(size_t) == 0) do { /* always true actually */
259 while (n && len) { 268 while (n && len) {
260 unsigned char c; 269 unsigned char c;
261 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c; 270
262 --len; 271 *(out++) = ivec[n] ^ (c = *(in++));
263 n = (n+1) % 8; 272 ivec[n] = c;
264 } 273 --len;
274 n = (n + 1) % 8;
275 }
265#ifdef __STRICT_ALIGNMENT 276#ifdef __STRICT_ALIGNMENT
266 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) 277 if (((size_t)in | (size_t)out | (size_t)ivec) %
267 break; 278 sizeof(size_t) != 0)
279 break;
268#endif 280#endif
269 while (len>=8) { 281 while (len >= 8) {
270 Gost2814789_encrypt_mesh(ivec, key); 282 Gost2814789_encrypt_mesh(ivec, key);
271 for (; n<8; n+=sizeof(size_t)) { 283 for (; n < 8; n += sizeof(size_t)) {
272 size_t t = *(size_t*)(in+n); 284 size_t t = *(size_t*)(in + n);
273 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t; 285 *(size_t*)(out + n) =
274 *(size_t*)(ivec+n) = t; 286 *(size_t*)(ivec + n) ^ t;
275 } 287 *(size_t*)(ivec + n) = t;
276 len -= 8; 288 }
277 out += 8; 289 len -= 8;
278 in += 8; 290 out += 8;
279 n = 0; 291 in += 8;
280 } 292 n = 0;
281 if (len) {
282 Gost2814789_encrypt_mesh(ivec, key);
283 while (len--) {
284 unsigned char c;
285 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
286 ++n;
287 } 293 }
288 } 294 if (len) {
289 *num = n; 295 Gost2814789_encrypt_mesh(ivec, key);
290 return; 296 while (len--) {
291 } while (0); 297 unsigned char c;
292 /* the rest would be commonly eliminated by x86* compiler */ 298
299 out[n] = ivec[n] ^ (c = in[n]);
300 ivec[n] = c;
301 ++n;
302 }
303 }
304 *num = n;
305 return;
306 } while (0);
307 /* the rest would be commonly eliminated by x86* compiler */
293#endif 308#endif
294 while (l<len) { 309 while (l < len) {
295 unsigned char c; 310 unsigned char c;
296 if (n == 0) { 311
297 Gost2814789_encrypt_mesh(ivec, key); 312 if (n == 0) {
313 Gost2814789_encrypt_mesh(ivec, key);
314 }
315 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
316 ++l;
317 n = (n + 1) % 8;
298 } 318 }
299 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; 319 *num = n;
300 ++l;
301 n = (n+1) % 8;
302 } 320 }
303 *num=n;
304 }
305} 321}
306 322
307static inline void Gost2814789_cnt_next(unsigned char *ivec, 323static inline void
308 unsigned char *out, 324Gost2814789_cnt_next(unsigned char *ivec, unsigned char *out,
309 GOST2814789_KEY *key) 325 GOST2814789_KEY *key)
310{ 326{
311 unsigned char *p = ivec, *p2 = ivec; 327 unsigned char *p = ivec, *p2 = ivec;
312 unsigned int val, val2; 328 unsigned int val, val2;
@@ -334,34 +350,35 @@ static inline void Gost2814789_cnt_next(unsigned char *ivec,
334 key->count += 8; 350 key->count += 8;
335} 351}
336 352
337void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, 353void
338 size_t len, GOST2814789_KEY *key, 354Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, size_t len,
339 unsigned char *ivec, unsigned char *cnt_buf, int *num) 355 GOST2814789_KEY *key, unsigned char *ivec, unsigned char *cnt_buf, int *num)
340{ 356{
341 unsigned int n; 357 unsigned int n;
342 size_t l=0; 358 size_t l = 0;
343 359
344 OPENSSL_assert(in && out && key && cnt_buf && num); 360 OPENSSL_assert(in && out && key && cnt_buf && num);
345 361
346 n = *num; 362 n = *num;
347 363
348#if !defined(OPENSSL_SMALL_FOOTPRINT) 364#if !defined(OPENSSL_SMALL_FOOTPRINT)
349 if (8%sizeof(size_t) == 0) do { /* always true actually */ 365 if (8 % sizeof(size_t) == 0) do { /* always true actually */
350 while (n && len) { 366 while (n && len) {
351 *(out++) = *(in++) ^ cnt_buf[n]; 367 *(out++) = *(in++) ^ cnt_buf[n];
352 --len; 368 --len;
353 n = (n+1) % 8; 369 n = (n + 1) % 8;
354 } 370 }
355 371
356#ifdef __STRICT_ALIGNMENT 372#ifdef __STRICT_ALIGNMENT
357 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) 373 if (((size_t)in | (size_t)out | (size_t)ivec) %
374 sizeof(size_t) != 0)
358 break; 375 break;
359#endif 376#endif
360 while (len>=8) { 377 while (len >= 8) {
361 Gost2814789_cnt_next(ivec, cnt_buf, key); 378 Gost2814789_cnt_next(ivec, cnt_buf, key);
362 for (; n<8; n+=sizeof(size_t)) 379 for (; n < 8; n += sizeof(size_t))
363 *(size_t *)(out+n) = 380 *(size_t *)(out + n) = *(size_t *)(in + n) ^
364 *(size_t *)(in+n) ^ *(size_t *)(cnt_buf+n); 381 *(size_t *)(cnt_buf + n);
365 len -= 8; 382 len -= 8;
366 out += 8; 383 out += 8;
367 in += 8; 384 in += 8;
@@ -379,27 +396,31 @@ void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out,
379 } while(0); 396 } while(0);
380 /* the rest would be commonly eliminated by x86* compiler */ 397 /* the rest would be commonly eliminated by x86* compiler */
381#endif 398#endif
382 while (l<len) { 399 while (l < len) {
383 if (n==0) 400 if (n==0)
384 Gost2814789_cnt_next(ivec, cnt_buf, key); 401 Gost2814789_cnt_next(ivec, cnt_buf, key);
385 out[l] = in[l] ^ cnt_buf[n]; 402 out[l] = in[l] ^ cnt_buf[n];
386 ++l; 403 ++l;
387 n = (n+1) % 8; 404 n = (n + 1) % 8;
388 } 405 }
389 406
390 *num=n; 407 *num=n;
391} 408}
392 409
393int GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid) 410int
411GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid)
394{ 412{
395 c->Nl = c->Nh = c->num = 0; 413 c->Nl = c->Nh = c->num = 0;
396 memset(c->mac, 0, 8); 414 memset(c->mac, 0, 8);
397 return Gost2814789_set_sbox(&c->cipher, nid); 415 return Gost2814789_set_sbox(&c->cipher, nid);
398} 416}
399 417
400static void GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx, const void *p, size_t num) 418static void
419GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx, const void *p,
420 size_t num)
401{ 421{
402 int i; 422 int i;
423
403 for (i = 0; i < num; i++) { 424 for (i = 0; i < num; i++) {
404 Gost2814789_mac_mesh(p, ctx->mac, &ctx->cipher); 425 Gost2814789_mac_mesh(p, ctx->mac, &ctx->cipher);
405 p += 8; 426 p += 8;
@@ -418,7 +439,8 @@ static void GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx, const voi
418 439
419#include "md32_common.h" 440#include "md32_common.h"
420 441
421int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c) 442int
443GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c)
422{ 444{
423 if (c->num) { 445 if (c->num) {
424 memset(c->data + c->num, 0, 8 - c->num); 446 memset(c->data + c->num, 0, 8 - c->num);
@@ -432,9 +454,9 @@ int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c)
432 return 1; 454 return 1;
433} 455}
434 456
435unsigned char *GOST2814789IMIT(const unsigned char *d, size_t n, 457unsigned char *
436 unsigned char *md, int nid, 458GOST2814789IMIT(const unsigned char *d, size_t n, unsigned char *md, int nid,
437 const unsigned char *key, const unsigned char *iv) 459 const unsigned char *key, const unsigned char *iv)
438{ 460{
439 GOST2814789IMIT_CTX c; 461 GOST2814789IMIT_CTX c;
440 static unsigned char m[GOST2814789IMIT_LENGTH]; 462 static unsigned char m[GOST2814789IMIT_LENGTH];