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