1 /* @(#)sha3.c 1.4 15/12/27 2015 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)sha3.c 1.4 15/12/27 2015 J. Schilling";
6 #endif
7 /*
8 * SHA3 hash code taken from
9 * https://github.com/rhash/RHash/tree/master/librhash
10 *
11 * Portions Copyright (c) 2015 J. Schilling
12 */
13
14 /*
15 * sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
16 * based on the
17 * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
18 * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
19 *
20 * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
21 *
22 * Permission is hereby granted, free of charge, to any person obtaining a
23 * copy of this software and associated documentation files (the "Software"),
24 * to deal in the Software without restriction, including without limitation
25 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
26 * and/or sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so.
28 *
29 * This program is distributed in the hope that it will be useful, but
30 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31 * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
32 */
33
34 #include <schily/assert.h>
35 #include <schily/string.h>
36 #include "byte_order.h"
37 #include <schily/sha3.h>
38
39 #ifdef HAVE_LONGLONG
40
41 #if !defined(HAVE_MEMCPY) || !defined(HAVE_MEMSET)
42 #include <schily/schily.h>
43 #endif
44 #if !defined(HAVE_MEMCPY) && !defined(memcpy)
45 #define memcpy(s1, s2, n) movebytes(s2, s1, n)
46 #endif
47 #if !defined(HAVE_MEMSET) && !defined(memset)
48 #define memset(s, c, n) fillbytes(s, n, c)
49 #endif
50
51 static void rhash_keccak_init __PR((sha3_ctx *ctx, unsigned bits));
52 static void keccak_theta __PR((UInt64_t *A));
53 static void keccak_pi __PR((UInt64_t *A));
54 static void keccak_chi __PR((UInt64_t *A));
55 static void rhash_sha3_permutation __PR((UInt64_t *state));
56 static void rhash_sha3_process_block __PR((UInt64_t hash[25],
57 const UInt64_t *block,
58 size_t block_size));
59
60 /*
61 * The Cygwin compile environment incorrectly implements #pragma weak.
62 * The weak symbols are only defined as local symbols making it impossible
63 * to use them from outside the scope of this source file.
64 * A platform that allows linking with global symbols has HAVE_LINK_WEAK
65 * defined.
66 */
67 #if defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK)
68 #pragma weak SHA3_224_Init = rhash_sha3_224_init
69 #pragma weak SHA3_256_Init = rhash_sha3_256_init
70 #pragma weak SHA3_384_Init = rhash_sha3_384_init
71 #pragma weak SHA3_512_Init = rhash_sha3_512_init
72 #pragma weak SHA3_Update = rhash_sha3_update
73 #else
74
75 void SHA3_224_Init __PR((SHA3_CTX *ctx));
76 void SHA3_256_Init __PR((SHA3_CTX *ctx));
77 void SHA3_384_Init __PR((SHA3_CTX *ctx));
78 void SHA3_512_Init __PR((SHA3_CTX *ctx));
79 void SHA3_Update __PR((SHA3_CTX *ctx,
80 const unsigned char *msg,
81 size_t size));
82
83 void
SHA3_224_Init(ctx)84 SHA3_224_Init(ctx)
85 SHA3_CTX *ctx;
86 {
87 rhash_sha3_224_init(ctx);
88 }
89
90 void
SHA3_256_Init(ctx)91 SHA3_256_Init(ctx)
92 SHA3_CTX *ctx;
93 {
94 rhash_sha3_256_init(ctx);
95 }
96
97 void
SHA3_384_Init(ctx)98 SHA3_384_Init(ctx)
99 SHA3_CTX *ctx;
100 {
101 rhash_sha3_384_init(ctx);
102 }
103
104 void
SHA3_512_Init(ctx)105 SHA3_512_Init(ctx)
106 SHA3_CTX *ctx;
107 {
108 rhash_sha3_512_init(ctx);
109 }
110
111 void
SHA3_Update(ctx,msg,size)112 SHA3_Update(ctx, msg, size)
113 SHA3_CTX *ctx;
114 const unsigned char *msg;
115 size_t size;
116 {
117 rhash_sha3_update(ctx, msg, size);
118 }
119 #endif /* defined(HAVE_PRAGMA_WEAK) && defined(HAVE_LINK_WEAK) */
120
121 /* constants */
122 #define NumberOfRounds 24
123
124 /* SHA3 (Keccak) constants for 24 rounds */
125 static UInt64_t keccak_round_constants[NumberOfRounds] = {
126 UI64(0x0000000000000001), UI64(0x0000000000008082),
127 UI64(0x800000000000808A), UI64(0x8000000080008000),
128 UI64(0x000000000000808B), UI64(0x0000000080000001),
129 UI64(0x8000000080008081), UI64(0x8000000000008009),
130 UI64(0x000000000000008A), UI64(0x0000000000000088),
131 UI64(0x0000000080008009), UI64(0x000000008000000A),
132 UI64(0x000000008000808B), UI64(0x800000000000008B),
133 UI64(0x8000000000008089), UI64(0x8000000000008003),
134 UI64(0x8000000000008002), UI64(0x8000000000000080),
135 UI64(0x000000000000800A), UI64(0x800000008000000A),
136 UI64(0x8000000080008081), UI64(0x8000000000008080),
137 UI64(0x0000000080000001), UI64(0x8000000080008008)
138 };
139
140 /* Initializing a sha3 context for given number of output bits */
141 static void
rhash_keccak_init(ctx,bits)142 rhash_keccak_init(ctx, bits)
143 sha3_ctx *ctx;
144 unsigned bits;
145 {
146 /* NB: The Keccak capacity parameter = bits * 2 */
147 unsigned rate = 1600 - bits * 2;
148
149 memset(ctx, 0, sizeof (sha3_ctx));
150 ctx->block_size = rate / 8;
151 assert(rate <= 1600 && (rate % 64) == 0);
152 }
153
154 /*
155 * Initialize context before calculating hash.
156 *
157 * @param ctx context to initialize
158 */
159 void
rhash_sha3_224_init(ctx)160 rhash_sha3_224_init(ctx)
161 sha3_ctx *ctx;
162 {
163 rhash_keccak_init(ctx, 224);
164 }
165
166 /*
167 * Initialize context before calculating hash.
168 *
169 * @param ctx context to initialize
170 */
171 void
rhash_sha3_256_init(ctx)172 rhash_sha3_256_init(ctx)
173 sha3_ctx *ctx;
174 {
175 rhash_keccak_init(ctx, 256);
176 }
177
178 /*
179 * Initialize context before calculating hash.
180 *
181 * @param ctx context to initialize
182 */
183 void
rhash_sha3_384_init(ctx)184 rhash_sha3_384_init(ctx)
185 sha3_ctx *ctx;
186 {
187 rhash_keccak_init(ctx, 384);
188 }
189
190 /*
191 * Initialize context before calculating hash.
192 *
193 * @param ctx context to initialize
194 */
195 void
rhash_sha3_512_init(ctx)196 rhash_sha3_512_init(ctx)
197 sha3_ctx *ctx;
198 {
199 rhash_keccak_init(ctx, 512);
200 }
201
202 /* Keccak theta() transformation */
203 static void
keccak_theta(A)204 keccak_theta(A)
205 UInt64_t *A;
206 {
207 unsigned int x;
208 UInt64_t C[5], D[5];
209
210 for (x = 0; x < 5; x++) {
211 C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
212 }
213 D[0] = ROTL64(C[1], 1) ^ C[4];
214 D[1] = ROTL64(C[2], 1) ^ C[0];
215 D[2] = ROTL64(C[3], 1) ^ C[1];
216 D[3] = ROTL64(C[4], 1) ^ C[2];
217 D[4] = ROTL64(C[0], 1) ^ C[3];
218
219 for (x = 0; x < 5; x++) {
220 A[x] ^= D[x];
221 A[x + 5] ^= D[x];
222 A[x + 10] ^= D[x];
223 A[x + 15] ^= D[x];
224 A[x + 20] ^= D[x];
225 }
226 }
227
228 /* Keccak pi() transformation */
229 static void
keccak_pi(A)230 keccak_pi(A)
231 UInt64_t *A;
232 {
233 UInt64_t A1;
234 A1 = A[1];
235 A[ 1] = A[ 6];
236 A[ 6] = A[ 9];
237 A[ 9] = A[22];
238 A[22] = A[14];
239 A[14] = A[20];
240 A[20] = A[ 2];
241 A[ 2] = A[12];
242 A[12] = A[13];
243 A[13] = A[19];
244 A[19] = A[23];
245 A[23] = A[15];
246 A[15] = A[ 4];
247 A[ 4] = A[24];
248 A[24] = A[21];
249 A[21] = A[ 8];
250 A[ 8] = A[16];
251 A[16] = A[ 5];
252 A[ 5] = A[ 3];
253 A[ 3] = A[18];
254 A[18] = A[17];
255 A[17] = A[11];
256 A[11] = A[ 7];
257 A[ 7] = A[10];
258 A[10] = A1;
259 /* note: A[ 0] is left as is */
260 }
261
262 /* Keccak chi() transformation */
263 static void
keccak_chi(A)264 keccak_chi(A)
265 UInt64_t *A;
266 {
267 int i;
268 for (i = 0; i < 25; i += 5) {
269 UInt64_t A0 = A[0 + i], A1 = A[1 + i];
270 A[0 + i] ^= ~A1 & A[2 + i];
271 A[1 + i] ^= ~A[2 + i] & A[3 + i];
272 A[2 + i] ^= ~A[3 + i] & A[4 + i];
273 A[3 + i] ^= ~A[4 + i] & A0;
274 A[4 + i] ^= ~A0 & A1;
275 }
276 }
277
278 static void
rhash_sha3_permutation(state)279 rhash_sha3_permutation(state)
280 UInt64_t *state;
281 {
282 int round;
283 for (round = 0; round < NumberOfRounds; round++)
284 {
285 keccak_theta(state);
286
287 /* apply Keccak rho() transformation */
288 state[ 1] = ROTL64(state[ 1], 1);
289 state[ 2] = ROTL64(state[ 2], 62);
290 state[ 3] = ROTL64(state[ 3], 28);
291 state[ 4] = ROTL64(state[ 4], 27);
292 state[ 5] = ROTL64(state[ 5], 36);
293 state[ 6] = ROTL64(state[ 6], 44);
294 state[ 7] = ROTL64(state[ 7], 6);
295 state[ 8] = ROTL64(state[ 8], 55);
296 state[ 9] = ROTL64(state[ 9], 20);
297 state[10] = ROTL64(state[10], 3);
298 state[11] = ROTL64(state[11], 10);
299 state[12] = ROTL64(state[12], 43);
300 state[13] = ROTL64(state[13], 25);
301 state[14] = ROTL64(state[14], 39);
302 state[15] = ROTL64(state[15], 41);
303 state[16] = ROTL64(state[16], 45);
304 state[17] = ROTL64(state[17], 15);
305 state[18] = ROTL64(state[18], 21);
306 state[19] = ROTL64(state[19], 8);
307 state[20] = ROTL64(state[20], 18);
308 state[21] = ROTL64(state[21], 2);
309 state[22] = ROTL64(state[22], 61);
310 state[23] = ROTL64(state[23], 56);
311 state[24] = ROTL64(state[24], 14);
312
313 keccak_pi(state);
314 keccak_chi(state);
315
316 /* apply iota(state, round) */
317 *state ^= keccak_round_constants[round];
318 }
319 }
320
321 /*
322 * The core transformation. Process the specified block of data.
323 *
324 * @param hash the algorithm state
325 * @param block the message block to process
326 * @param block_size the size of the processed block in bytes
327 */
328 static void
rhash_sha3_process_block(hash,block,block_size)329 rhash_sha3_process_block(hash, block, block_size)
330 UInt64_t hash[25];
331 const UInt64_t *block;
332 size_t block_size;
333 {
334 /* expanded loop */
335 hash[ 0] ^= le2me_64(block[ 0]);
336 hash[ 1] ^= le2me_64(block[ 1]);
337 hash[ 2] ^= le2me_64(block[ 2]);
338 hash[ 3] ^= le2me_64(block[ 3]);
339 hash[ 4] ^= le2me_64(block[ 4]);
340 hash[ 5] ^= le2me_64(block[ 5]);
341 hash[ 6] ^= le2me_64(block[ 6]);
342 hash[ 7] ^= le2me_64(block[ 7]);
343 hash[ 8] ^= le2me_64(block[ 8]);
344 /* if not sha3-512 */
345 if (block_size > 72) {
346 hash[ 9] ^= le2me_64(block[ 9]);
347 hash[10] ^= le2me_64(block[10]);
348 hash[11] ^= le2me_64(block[11]);
349 hash[12] ^= le2me_64(block[12]);
350 /* if not sha3-384 */
351 if (block_size > 104) {
352 hash[13] ^= le2me_64(block[13]);
353 hash[14] ^= le2me_64(block[14]);
354 hash[15] ^= le2me_64(block[15]);
355 hash[16] ^= le2me_64(block[16]);
356 /* if not sha3-256 */
357 if (block_size > 136) {
358 hash[17] ^= le2me_64(block[17]);
359 #ifdef FULL_SHA3_FAMILY_SUPPORT
360 /* if not sha3-224 */
361 if (block_size > 144) {
362 hash[18] ^= le2me_64(block[18]);
363 hash[19] ^= le2me_64(block[19]);
364 hash[20] ^= le2me_64(block[20]);
365 hash[21] ^= le2me_64(block[21]);
366 hash[22] ^= le2me_64(block[22]);
367 hash[23] ^= le2me_64(block[23]);
368 hash[24] ^= le2me_64(block[24]);
369 }
370 #endif
371 }
372 }
373 }
374 /* make a permutation of the hash */
375 rhash_sha3_permutation(hash);
376 }
377
378 #define SHA3_FINALIZED 0x80000000
379
380 /*
381 * Calculate message hash.
382 * Can be called repeatedly with chunks of the message to be hashed.
383 *
384 * @param ctx the algorithm context containing current hashing state
385 * @param msg message chunk
386 * @param size length of the message chunk
387 */
388 void
rhash_sha3_update(ctx,msg,size)389 rhash_sha3_update(ctx, msg, size)
390 sha3_ctx *ctx;
391 const unsigned char *msg;
392 size_t size;
393 {
394 size_t idx = (size_t)ctx->rest;
395 size_t block_size = (size_t)ctx->block_size;
396
397 if (ctx->rest & SHA3_FINALIZED)
398 return; /* too late for additional input */
399 ctx->rest = (unsigned)((ctx->rest + size) % block_size);
400
401 /* fill partial block */
402 if (idx) {
403 size_t left = block_size - idx;
404 memcpy((char *)ctx->message + idx, msg,
405 (size < left ? size : left));
406 if (size < left)
407 return;
408
409 /* process partial block */
410 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
411 msg += left;
412 size -= left;
413 }
414 while (size >= block_size) {
415 UInt64_t *aligned_message_block;
416 if (IS_ALIGNED_64(msg)) {
417 /*
418 * the most common case is processing of an already
419 * aligned message without copying it
420 */
421 aligned_message_block = (UInt64_t *)msg;
422 } else {
423 memcpy(ctx->message, msg, block_size);
424 aligned_message_block = ctx->message;
425 }
426
427 rhash_sha3_process_block(ctx->hash, aligned_message_block,
428 block_size);
429 msg += block_size;
430 size -= block_size;
431 }
432 if (size) {
433 memcpy(ctx->message, msg, size); /* save leftovers */
434 }
435 }
436
437 /*
438 * Store calculated hash into the given array.
439 *
440 * @param ctx the algorithm context containing current hashing state
441 * @param result calculated hash in binary form
442 */
443 void
rhash_sha3_final(ctx,result)444 rhash_sha3_final(ctx, result)
445 sha3_ctx *ctx;
446 unsigned char *result;
447 {
448 size_t digest_length = 100 - ctx->block_size / 2;
449 const size_t block_size = ctx->block_size;
450
451 if (!(ctx->rest & SHA3_FINALIZED))
452 {
453 /* clear the rest of the data queue */
454 memset((char *)ctx->message + ctx->rest, 0,
455 block_size - ctx->rest);
456 ((char *)ctx->message)[ctx->rest] |= 0x06;
457 ((char *)ctx->message)[block_size - 1] |= 0x80;
458
459 /* process final block */
460 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
461 ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
462 }
463
464 assert(block_size > digest_length);
465 if (result) me64_to_le_str(result, ctx->hash, digest_length);
466 }
467
468 void
SHA3_Final(result,ctx)469 SHA3_Final(result, ctx)
470 UInt8_t *result;
471 SHA3_CTX *ctx;
472 {
473 rhash_sha3_final(ctx, result);
474 }
475
476 #ifdef USE_KECCAK
477 /*
478 * Store calculated hash into the given array.
479 *
480 * @param ctx the algorithm context containing current hashing state
481 * @param result calculated hash in binary form
482 */
483 void
rhash_keccak_final(sha3_ctx * ctx,unsigned char * result)484 rhash_keccak_final(sha3_ctx *ctx, unsigned char *result)
485 {
486 size_t digest_length = 100 - ctx->block_size / 2;
487 const size_t block_size = ctx->block_size;
488
489 if (!(ctx->rest & SHA3_FINALIZED)) {
490 /* clear the rest of the data queue */
491 memset((char *)ctx->message + ctx->rest, 0,
492 block_size - ctx->rest);
493 ((char *)ctx->message)[ctx->rest] |= 0x01;
494 ((char *)ctx->message)[block_size - 1] |= 0x80;
495
496 /* process final block */
497 rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
498 ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
499 }
500
501 assert(block_size > digest_length);
502 if (result)
503 me64_to_le_str(result, ctx->hash, digest_length);
504 }
505 #endif /* USE_KECCAK */
506
507 #endif /* HAVE_LONGLONG */
508