diff options
Diffstat (limited to 'src/lib/libcrypto/gost/gost2814789.c')
-rw-r--r-- | src/lib/libcrypto/gost/gost2814789.c | 270 |
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 | ||
62 | static inline unsigned int f(const GOST2814789_KEY *c, unsigned int x) | 62 | static inline unsigned int |
63 | f(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 | ||
68 | void Gost2814789_encrypt(const unsigned char *in, unsigned char *out, | 69 | void |
69 | const GOST2814789_KEY *key) | 70 | Gost2814789_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 | ||
100 | void Gost2814789_decrypt(const unsigned char *in, unsigned char *out, | 103 | void |
101 | const GOST2814789_KEY *key) | 104 | Gost2814789_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 | ||
132 | static void Gost2814789_mac(const unsigned char *in, | 137 | static void |
133 | unsigned char *mac, | 138 | Gost2814789_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 | 168 | void | |
164 | void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out, | 169 | Gost2814789_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 | ||
178 | static inline void Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key) | 183 | static inline void |
184 | Gost2814789_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 | ||
189 | static inline void Gost2814789_mac_mesh(const unsigned char *data, | 195 | static inline void |
190 | unsigned char *mac, | 196 | Gost2814789_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 | ||
201 | void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out, | 207 | void |
202 | size_t len, GOST2814789_KEY *key, | 208 | Gost2814789_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 | ||
307 | static inline void Gost2814789_cnt_next(unsigned char *ivec, | 323 | static inline void |
308 | unsigned char *out, | 324 | Gost2814789_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 | ||
337 | void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, | 353 | void |
338 | size_t len, GOST2814789_KEY *key, | 354 | Gost2814789_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 | ||
393 | int GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid) | 410 | int |
411 | GOST2814789IMIT_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 | ||
400 | static void GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx, const void *p, size_t num) | 418 | static void |
419 | GOST2814789IMIT_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 | ||
421 | int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c) | 442 | int |
443 | GOST2814789IMIT_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 | ||
435 | unsigned char *GOST2814789IMIT(const unsigned char *d, size_t n, | 457 | unsigned char * |
436 | unsigned char *md, int nid, | 458 | GOST2814789IMIT(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]; |