xref: /freebsd/sys/contrib/openzfs/module/icp/algs/edonr/edonr.c (revision 9e5787d2284e187abb5b654d924394a65772e004)
1 /*
2  * IDI,NTNU
3  *
4  * CDDL HEADER START
5  *
6  * The contents of this file are subject to the terms of the
7  * Common Development and Distribution License (the "License").
8  * You may not use this file except in compliance with the License.
9  *
10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11  * or http://opensource.org/licenses/CDDL-1.0.
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  *
23  * Copyright (C) 2009, 2010, Jorn Amundsen <jorn.amundsen@ntnu.no>
24  * Tweaked Edon-R implementation for SUPERCOP, based on NIST API.
25  *
26  * $Id: edonr.c 517 2013-02-17 20:34:39Z joern $
27  */
28 /*
29  * Portions copyright (c) 2013, Saso Kiselkov, All rights reserved
30  */
31 
32 #include <sys/strings.h>
33 #include <sys/edonr.h>
34 #include <sys/debug.h>
35 
36 /* big endian support, provides no-op's if run on little endian hosts */
37 #include "edonr_byteorder.h"
38 
39 #define	hashState224(x)	((x)->pipe->p256)
40 #define	hashState256(x)	((x)->pipe->p256)
41 #define	hashState384(x)	((x)->pipe->p512)
42 #define	hashState512(x)	((x)->pipe->p512)
43 
44 /* shift and rotate shortcuts */
45 #define	shl(x, n)	((x) << n)
46 #define	shr(x, n)	((x) >> n)
47 
48 #define	rotl32(x, n)	(((x) << (n)) | ((x) >> (32 - (n))))
49 #define	rotr32(x, n)	(((x) >> (n)) | ((x) << (32 - (n))))
50 
51 #define	rotl64(x, n)	(((x) << (n)) | ((x) >> (64 - (n))))
52 #define	rotr64(x, n)	(((x) >> (n)) | ((x) << (64 - (n))))
53 
54 #if !defined(__C99_RESTRICT)
55 #define	restrict	/* restrict */
56 #endif
57 
58 #define	EDONR_VALID_HASHBITLEN(x) \
59 	((x) == 512 || (x) == 384 || (x) == 256 || (x) == 224)
60 
61 /* EdonR224 initial double chaining pipe */
62 static const uint32_t i224p2[16] = {
63 	0x00010203ul, 0x04050607ul, 0x08090a0bul, 0x0c0d0e0ful,
64 	0x10111213ul, 0x14151617ul, 0x18191a1bul, 0x1c1d1e1ful,
65 	0x20212223ul, 0x24252627ul, 0x28292a2bul, 0x2c2d2e2ful,
66 	0x30313233ul, 0x34353637ul, 0x38393a3bul, 0x3c3d3e3ful,
67 };
68 
69 /* EdonR256 initial double chaining pipe */
70 static const uint32_t i256p2[16] = {
71 	0x40414243ul, 0x44454647ul, 0x48494a4bul, 0x4c4d4e4ful,
72 	0x50515253ul, 0x54555657ul, 0x58595a5bul, 0x5c5d5e5ful,
73 	0x60616263ul, 0x64656667ul, 0x68696a6bul, 0x6c6d6e6ful,
74 	0x70717273ul, 0x74757677ul, 0x78797a7bul, 0x7c7d7e7ful,
75 };
76 
77 /* EdonR384 initial double chaining pipe */
78 static const uint64_t i384p2[16] = {
79 	0x0001020304050607ull, 0x08090a0b0c0d0e0full,
80 	0x1011121314151617ull, 0x18191a1b1c1d1e1full,
81 	0x2021222324252627ull, 0x28292a2b2c2d2e2full,
82 	0x3031323334353637ull, 0x38393a3b3c3d3e3full,
83 	0x4041424344454647ull, 0x48494a4b4c4d4e4full,
84 	0x5051525354555657ull, 0x58595a5b5c5d5e5full,
85 	0x6061626364656667ull, 0x68696a6b6c6d6e6full,
86 	0x7071727374757677ull, 0x78797a7b7c7d7e7full
87 };
88 
89 /* EdonR512 initial double chaining pipe */
90 static const uint64_t i512p2[16] = {
91 	0x8081828384858687ull, 0x88898a8b8c8d8e8full,
92 	0x9091929394959697ull, 0x98999a9b9c9d9e9full,
93 	0xa0a1a2a3a4a5a6a7ull, 0xa8a9aaabacadaeafull,
94 	0xb0b1b2b3b4b5b6b7ull, 0xb8b9babbbcbdbebfull,
95 	0xc0c1c2c3c4c5c6c7ull, 0xc8c9cacbcccdcecfull,
96 	0xd0d1d2d3d4d5d6d7ull, 0xd8d9dadbdcdddedfull,
97 	0xe0e1e2e3e4e5e6e7ull, 0xe8e9eaebecedeeefull,
98 	0xf0f1f2f3f4f5f6f7ull, 0xf8f9fafbfcfdfeffull
99 };
100 
101 /*
102  * First Latin Square
103  * 0   7   1   3   2   4   6   5
104  * 4   1   7   6   3   0   5   2
105  * 7   0   4   2   5   3   1   6
106  * 1   4   0   5   6   2   7   3
107  * 2   3   6   7   1   5   0   4
108  * 5   2   3   1   7   6   4   0
109  * 3   6   5   0   4   7   2   1
110  * 6   5   2   4   0   1   3   7
111  */
112 #define	LS1_256(c, x0, x1, x2, x3, x4, x5, x6, x7)			\
113 {									\
114 	uint32_t x04, x17, x23, x56, x07, x26;				\
115 	x04 = x0+x4, x17 = x1+x7, x07 = x04+x17;			\
116 	s0 = c + x07 + x2;						\
117 	s1 = rotl32(x07 + x3, 4);					\
118 	s2 = rotl32(x07 + x6, 8);					\
119 	x23 = x2 + x3;							\
120 	s5 = rotl32(x04 + x23 + x5, 22);				\
121 	x56 = x5 + x6;							\
122 	s6 = rotl32(x17 + x56 + x0, 24);				\
123 	x26 = x23+x56;							\
124 	s3 = rotl32(x26 + x7, 13);					\
125 	s4 = rotl32(x26 + x1, 17);					\
126 	s7 = rotl32(x26 + x4, 29);					\
127 }
128 
129 #define	LS1_512(c, x0, x1, x2, x3, x4, x5, x6, x7)			\
130 {									\
131 	uint64_t x04, x17, x23, x56, x07, x26;				\
132 	x04 = x0+x4, x17 = x1+x7, x07 = x04+x17;			\
133 	s0 = c + x07 + x2;						\
134 	s1 = rotl64(x07 + x3, 5);					\
135 	s2 = rotl64(x07 + x6, 15);					\
136 	x23 = x2 + x3;							\
137 	s5 = rotl64(x04 + x23 + x5, 40);				\
138 	x56 = x5 + x6;							\
139 	s6 = rotl64(x17 + x56 + x0, 50);				\
140 	x26 = x23+x56;							\
141 	s3 = rotl64(x26 + x7, 22);					\
142 	s4 = rotl64(x26 + x1, 31);					\
143 	s7 = rotl64(x26 + x4, 59);					\
144 }
145 
146 /*
147  * Second Orthogonal Latin Square
148  * 0   4   2   3   1   6   5   7
149  * 7   6   3   2   5   4   1   0
150  * 5   3   1   6   0   2   7   4
151  * 1   0   5   4   3   7   2   6
152  * 2   1   0   7   4   5   6   3
153  * 3   5   7   0   6   1   4   2
154  * 4   7   6   1   2   0   3   5
155  * 6   2   4   5   7   3   0   1
156  */
157 #define	LS2_256(c, y0, y1, y2, y3, y4, y5, y6, y7)			\
158 {									\
159 	uint32_t y01, y25, y34, y67, y04, y05, y27, y37;		\
160 	y01 = y0+y1, y25 = y2+y5, y05 = y01+y25;			\
161 	t0  = ~c + y05 + y7;						\
162 	t2 = rotl32(y05 + y3, 9);					\
163 	y34 = y3+y4, y04 = y01+y34;					\
164 	t1 = rotl32(y04 + y6, 5);					\
165 	t4 = rotl32(y04 + y5, 15);					\
166 	y67 = y6+y7, y37 = y34+y67;					\
167 	t3 = rotl32(y37 + y2, 11);					\
168 	t7 = rotl32(y37 + y0, 27);					\
169 	y27 = y25+y67;							\
170 	t5 = rotl32(y27 + y4, 20);					\
171 	t6 = rotl32(y27 + y1, 25);					\
172 }
173 
174 #define	LS2_512(c, y0, y1, y2, y3, y4, y5, y6, y7)			\
175 {									\
176 	uint64_t y01, y25, y34, y67, y04, y05, y27, y37;		\
177 	y01 = y0+y1, y25 = y2+y5, y05 = y01+y25;			\
178 	t0  = ~c + y05 + y7;						\
179 	t2 = rotl64(y05 + y3, 19);					\
180 	y34 = y3+y4, y04 = y01+y34;					\
181 	t1 = rotl64(y04 + y6, 10);					\
182 	t4 = rotl64(y04 + y5, 36);					\
183 	y67 = y6+y7, y37 = y34+y67;					\
184 	t3 = rotl64(y37 + y2, 29);					\
185 	t7 = rotl64(y37 + y0, 55);					\
186 	y27 = y25+y67;							\
187 	t5 = rotl64(y27 + y4, 44);					\
188 	t6 = rotl64(y27 + y1, 48);					\
189 }
190 
191 #define	quasi_exform256(r0, r1, r2, r3, r4, r5, r6, r7)			\
192 {									\
193 	uint32_t s04, s17, s23, s56, t01, t25, t34, t67;		\
194 	s04 = s0 ^ s4, t01 = t0 ^ t1;					\
195 	r0 = (s04 ^ s1) + (t01 ^ t5);					\
196 	t67 = t6 ^ t7;							\
197 	r1 = (s04 ^ s7) + (t2 ^ t67);					\
198 	s23 = s2 ^ s3;							\
199 	r7 = (s23 ^ s5) + (t4 ^ t67);					\
200 	t34 = t3 ^ t4;							\
201 	r3 = (s23 ^ s4) + (t0 ^ t34);					\
202 	s56 = s5 ^ s6;							\
203 	r5 = (s3 ^ s56) + (t34 ^ t6);					\
204 	t25 = t2 ^ t5;							\
205 	r6 = (s2 ^ s56) + (t25 ^ t7);					\
206 	s17 = s1 ^ s7;							\
207 	r4 = (s0 ^ s17) + (t1 ^ t25);					\
208 	r2 = (s17 ^ s6) + (t01 ^ t3);					\
209 }
210 
211 #define	quasi_exform512(r0, r1, r2, r3, r4, r5, r6, r7)			\
212 {									\
213 	uint64_t s04, s17, s23, s56, t01, t25, t34, t67;		\
214 	s04 = s0 ^ s4, t01 = t0 ^ t1;					\
215 	r0 = (s04 ^ s1) + (t01 ^ t5);					\
216 	t67 = t6 ^ t7;							\
217 	r1 = (s04 ^ s7) + (t2 ^ t67);					\
218 	s23 = s2 ^ s3;							\
219 	r7 = (s23 ^ s5) + (t4 ^ t67);					\
220 	t34 = t3 ^ t4;							\
221 	r3 = (s23 ^ s4) + (t0 ^ t34);					\
222 	s56 = s5 ^ s6;							\
223 	r5 = (s3 ^ s56) + (t34 ^ t6);					\
224 	t25 = t2 ^ t5;							\
225 	r6 = (s2 ^ s56) + (t25 ^ t7);					\
226 	s17 = s1 ^ s7;							\
227 	r4 = (s0 ^ s17) + (t1 ^ t25);					\
228 	r2 = (s17 ^ s6) + (t01 ^ t3);					\
229 }
230 
231 static size_t
232 Q256(size_t bitlen, const uint32_t *data, uint32_t *restrict p)
233 {
234 	size_t bl;
235 
236 	for (bl = bitlen; bl >= EdonR256_BLOCK_BITSIZE;
237 	    bl -= EdonR256_BLOCK_BITSIZE, data += 16) {
238 		uint32_t s0, s1, s2, s3, s4, s5, s6, s7, t0, t1, t2, t3, t4,
239 		    t5, t6, t7;
240 		uint32_t p0, p1, p2, p3, p4, p5, p6, p7, q0, q1, q2, q3, q4,
241 		    q5, q6, q7;
242 		const uint32_t defix = 0xaaaaaaaa;
243 #if defined(MACHINE_IS_BIG_ENDIAN)
244 		uint32_t swp0, swp1, swp2, swp3, swp4, swp5, swp6, swp7, swp8,
245 		    swp9, swp10, swp11, swp12, swp13, swp14, swp15;
246 #define	d(j)	swp ## j
247 #define	s32(j)	ld_swap32((uint32_t *)data + j, swp ## j)
248 #else
249 #define	d(j)	data[j]
250 #endif
251 
252 		/* First row of quasigroup e-transformations */
253 #if defined(MACHINE_IS_BIG_ENDIAN)
254 		s32(8);
255 		s32(9);
256 		s32(10);
257 		s32(11);
258 		s32(12);
259 		s32(13);
260 		s32(14);
261 		s32(15);
262 #endif
263 		LS1_256(defix, d(15), d(14), d(13), d(12), d(11), d(10), d(9),
264 		    d(8));
265 #if defined(MACHINE_IS_BIG_ENDIAN)
266 		s32(0);
267 		s32(1);
268 		s32(2);
269 		s32(3);
270 		s32(4);
271 		s32(5);
272 		s32(6);
273 		s32(7);
274 #undef s32
275 #endif
276 		LS2_256(defix, d(0), d(1), d(2), d(3), d(4), d(5), d(6), d(7));
277 		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
278 
279 		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
280 		LS2_256(defix, d(8), d(9), d(10), d(11), d(12), d(13), d(14),
281 		    d(15));
282 		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
283 
284 		/* Second row of quasigroup e-transformations */
285 		LS1_256(defix, p[8], p[9], p[10], p[11], p[12], p[13], p[14],
286 		    p[15]);
287 		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
288 		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
289 
290 		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
291 		LS2_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
292 		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
293 
294 		/* Third row of quasigroup e-transformations */
295 		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
296 		LS2_256(defix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
297 		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
298 
299 		LS1_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
300 		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
301 		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
302 
303 		/* Fourth row of quasigroup e-transformations */
304 		LS1_256(defix, d(7), d(6), d(5), d(4), d(3), d(2), d(1), d(0));
305 		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
306 		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
307 
308 		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
309 		LS2_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
310 		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
311 
312 		/* Edon-R tweak on the original SHA-3 Edon-R submission. */
313 		p[0] ^= d(8) ^ p0;
314 		p[1] ^= d(9) ^ p1;
315 		p[2] ^= d(10) ^ p2;
316 		p[3] ^= d(11) ^ p3;
317 		p[4] ^= d(12) ^ p4;
318 		p[5] ^= d(13) ^ p5;
319 		p[6] ^= d(14) ^ p6;
320 		p[7] ^= d(15) ^ p7;
321 		p[8] ^= d(0) ^ q0;
322 		p[9] ^= d(1) ^ q1;
323 		p[10] ^= d(2) ^ q2;
324 		p[11] ^= d(3) ^ q3;
325 		p[12] ^= d(4) ^ q4;
326 		p[13] ^= d(5) ^ q5;
327 		p[14] ^= d(6) ^ q6;
328 		p[15] ^= d(7) ^ q7;
329 	}
330 
331 #undef d
332 	return (bitlen - bl);
333 }
334 
335 /*
336  * Why is this #pragma here?
337  *
338  * Checksum functions like this one can go over the stack frame size check
339  * Linux imposes on 32-bit platforms (-Wframe-larger-than=1024).  We can
340  * safely ignore the compiler error since we know that in ZoL, that
341  * the function will be called from a worker thread that won't be using
342  * much stack.  The only function that goes over the 1k limit is Q512(),
343  * which only goes over it by a hair (1248 bytes on ARM32).
344  */
345 #include <sys/isa_defs.h>	/* for _ILP32 */
346 #ifdef _ILP32   /* We're 32-bit, assume small stack frames */
347 #pragma GCC diagnostic ignored "-Wframe-larger-than="
348 #endif
349 
350 #if defined(__IBMC__) && defined(_AIX) && defined(__64BIT__)
351 static inline size_t
352 #else
353 static size_t
354 #endif
355 Q512(size_t bitlen, const uint64_t *data, uint64_t *restrict p)
356 {
357 	size_t bl;
358 
359 	for (bl = bitlen; bl >= EdonR512_BLOCK_BITSIZE;
360 	    bl -= EdonR512_BLOCK_BITSIZE, data += 16) {
361 		uint64_t s0, s1, s2, s3, s4, s5, s6, s7, t0, t1, t2, t3, t4,
362 		    t5, t6, t7;
363 		uint64_t p0, p1, p2, p3, p4, p5, p6, p7, q0, q1, q2, q3, q4,
364 		    q5, q6, q7;
365 		const uint64_t defix = 0xaaaaaaaaaaaaaaaaull;
366 #if defined(MACHINE_IS_BIG_ENDIAN)
367 		uint64_t swp0, swp1, swp2, swp3, swp4, swp5, swp6, swp7, swp8,
368 		    swp9, swp10, swp11, swp12, swp13, swp14, swp15;
369 #define	d(j)	swp##j
370 #define	s64(j)	ld_swap64((uint64_t *)data+j, swp##j)
371 #else
372 #define	d(j)	data[j]
373 #endif
374 
375 		/* First row of quasigroup e-transformations */
376 #if defined(MACHINE_IS_BIG_ENDIAN)
377 		s64(8);
378 		s64(9);
379 		s64(10);
380 		s64(11);
381 		s64(12);
382 		s64(13);
383 		s64(14);
384 		s64(15);
385 #endif
386 		LS1_512(defix, d(15), d(14), d(13), d(12), d(11), d(10), d(9),
387 		    d(8));
388 #if defined(MACHINE_IS_BIG_ENDIAN)
389 		s64(0);
390 		s64(1);
391 		s64(2);
392 		s64(3);
393 		s64(4);
394 		s64(5);
395 		s64(6);
396 		s64(7);
397 #undef s64
398 #endif
399 		LS2_512(defix, d(0), d(1), d(2), d(3), d(4), d(5), d(6), d(7));
400 		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
401 
402 		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
403 		LS2_512(defix, d(8), d(9), d(10), d(11), d(12), d(13), d(14),
404 		    d(15));
405 		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
406 
407 		/* Second row of quasigroup e-transformations */
408 		LS1_512(defix, p[8], p[9], p[10], p[11], p[12], p[13], p[14],
409 		    p[15]);
410 		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
411 		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
412 
413 		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
414 		LS2_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
415 		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
416 
417 		/* Third row of quasigroup e-transformations */
418 		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
419 		LS2_512(defix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
420 		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
421 
422 		LS1_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
423 		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
424 		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
425 
426 		/* Fourth row of quasigroup e-transformations */
427 		LS1_512(defix, d(7), d(6), d(5), d(4), d(3), d(2), d(1), d(0));
428 		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
429 		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
430 
431 		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
432 		LS2_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
433 		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
434 
435 		/* Edon-R tweak on the original SHA-3 Edon-R submission. */
436 		p[0] ^= d(8) ^ p0;
437 		p[1] ^= d(9) ^ p1;
438 		p[2] ^= d(10) ^ p2;
439 		p[3] ^= d(11) ^ p3;
440 		p[4] ^= d(12) ^ p4;
441 		p[5] ^= d(13) ^ p5;
442 		p[6] ^= d(14) ^ p6;
443 		p[7] ^= d(15) ^ p7;
444 		p[8] ^= d(0) ^ q0;
445 		p[9] ^= d(1) ^ q1;
446 		p[10] ^= d(2) ^ q2;
447 		p[11] ^= d(3) ^ q3;
448 		p[12] ^= d(4) ^ q4;
449 		p[13] ^= d(5) ^ q5;
450 		p[14] ^= d(6) ^ q6;
451 		p[15] ^= d(7) ^ q7;
452 	}
453 
454 #undef d
455 	return (bitlen - bl);
456 }
457 
458 void
459 EdonRInit(EdonRState *state, size_t hashbitlen)
460 {
461 	ASSERT(EDONR_VALID_HASHBITLEN(hashbitlen));
462 	switch (hashbitlen) {
463 	case 224:
464 		state->hashbitlen = 224;
465 		state->bits_processed = 0;
466 		state->unprocessed_bits = 0;
467 		bcopy(i224p2, hashState224(state)->DoublePipe,
468 		    16 * sizeof (uint32_t));
469 		break;
470 
471 	case 256:
472 		state->hashbitlen = 256;
473 		state->bits_processed = 0;
474 		state->unprocessed_bits = 0;
475 		bcopy(i256p2, hashState256(state)->DoublePipe,
476 		    16 * sizeof (uint32_t));
477 		break;
478 
479 	case 384:
480 		state->hashbitlen = 384;
481 		state->bits_processed = 0;
482 		state->unprocessed_bits = 0;
483 		bcopy(i384p2, hashState384(state)->DoublePipe,
484 		    16 * sizeof (uint64_t));
485 		break;
486 
487 	case 512:
488 		state->hashbitlen = 512;
489 		state->bits_processed = 0;
490 		state->unprocessed_bits = 0;
491 		bcopy(i512p2, hashState224(state)->DoublePipe,
492 		    16 * sizeof (uint64_t));
493 		break;
494 	}
495 }
496 
497 
498 void
499 EdonRUpdate(EdonRState *state, const uint8_t *data, size_t databitlen)
500 {
501 	uint32_t *data32;
502 	uint64_t *data64;
503 
504 	size_t bits_processed;
505 
506 	ASSERT(EDONR_VALID_HASHBITLEN(state->hashbitlen));
507 	switch (state->hashbitlen) {
508 	case 224:
509 	case 256:
510 		if (state->unprocessed_bits > 0) {
511 			/* LastBytes = databitlen / 8 */
512 			int LastBytes = (int)databitlen >> 3;
513 
514 			ASSERT(state->unprocessed_bits + databitlen <=
515 			    EdonR256_BLOCK_SIZE * 8);
516 
517 			bcopy(data, hashState256(state)->LastPart
518 			    + (state->unprocessed_bits >> 3), LastBytes);
519 			state->unprocessed_bits += (int)databitlen;
520 			databitlen = state->unprocessed_bits;
521 			/* LINTED E_BAD_PTR_CAST_ALIGN */
522 			data32 = (uint32_t *)hashState256(state)->LastPart;
523 		} else
524 			/* LINTED E_BAD_PTR_CAST_ALIGN */
525 			data32 = (uint32_t *)data;
526 
527 		bits_processed = Q256(databitlen, data32,
528 		    hashState256(state)->DoublePipe);
529 		state->bits_processed += bits_processed;
530 		databitlen -= bits_processed;
531 		state->unprocessed_bits = (int)databitlen;
532 		if (databitlen > 0) {
533 			/* LastBytes = Ceil(databitlen / 8) */
534 			int LastBytes =
535 			    ((~(((-(int)databitlen) >> 3) & 0x01ff)) +
536 			    1) & 0x01ff;
537 
538 			data32 += bits_processed >> 5;	/* byte size update */
539 			bcopy(data32, hashState256(state)->LastPart, LastBytes);
540 		}
541 		break;
542 
543 	case 384:
544 	case 512:
545 		if (state->unprocessed_bits > 0) {
546 			/* LastBytes = databitlen / 8 */
547 			int LastBytes = (int)databitlen >> 3;
548 
549 			ASSERT(state->unprocessed_bits + databitlen <=
550 			    EdonR512_BLOCK_SIZE * 8);
551 
552 			bcopy(data, hashState512(state)->LastPart
553 			    + (state->unprocessed_bits >> 3), LastBytes);
554 			state->unprocessed_bits += (int)databitlen;
555 			databitlen = state->unprocessed_bits;
556 			/* LINTED E_BAD_PTR_CAST_ALIGN */
557 			data64 = (uint64_t *)hashState512(state)->LastPart;
558 		} else
559 			/* LINTED E_BAD_PTR_CAST_ALIGN */
560 			data64 = (uint64_t *)data;
561 
562 		bits_processed = Q512(databitlen, data64,
563 		    hashState512(state)->DoublePipe);
564 		state->bits_processed += bits_processed;
565 		databitlen -= bits_processed;
566 		state->unprocessed_bits = (int)databitlen;
567 		if (databitlen > 0) {
568 			/* LastBytes = Ceil(databitlen / 8) */
569 			int LastBytes =
570 			    ((~(((-(int)databitlen) >> 3) & 0x03ff)) +
571 			    1) & 0x03ff;
572 
573 			data64 += bits_processed >> 6;	/* byte size update */
574 			bcopy(data64, hashState512(state)->LastPart, LastBytes);
575 		}
576 		break;
577 	}
578 }
579 
580 void
581 EdonRFinal(EdonRState *state, uint8_t *hashval)
582 {
583 	uint32_t *data32;
584 	uint64_t *data64, num_bits;
585 
586 	size_t databitlen;
587 	int LastByte, PadOnePosition;
588 
589 	num_bits = state->bits_processed + state->unprocessed_bits;
590 	ASSERT(EDONR_VALID_HASHBITLEN(state->hashbitlen));
591 	switch (state->hashbitlen) {
592 	case 224:
593 	case 256:
594 		LastByte = (int)state->unprocessed_bits >> 3;
595 		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
596 		hashState256(state)->LastPart[LastByte] =
597 		    (hashState256(state)->LastPart[LastByte]
598 		    & (0xff << (PadOnePosition + 1))) ^
599 		    (0x01 << PadOnePosition);
600 		/* LINTED E_BAD_PTR_CAST_ALIGN */
601 		data64 = (uint64_t *)hashState256(state)->LastPart;
602 
603 		if (state->unprocessed_bits < 448) {
604 			(void) memset((hashState256(state)->LastPart) +
605 			    LastByte + 1, 0x00,
606 			    EdonR256_BLOCK_SIZE - LastByte - 9);
607 			databitlen = EdonR256_BLOCK_SIZE * 8;
608 #if defined(MACHINE_IS_BIG_ENDIAN)
609 			st_swap64(num_bits, data64 + 7);
610 #else
611 			data64[7] = num_bits;
612 #endif
613 		} else {
614 			(void) memset((hashState256(state)->LastPart) +
615 			    LastByte + 1, 0x00,
616 			    EdonR256_BLOCK_SIZE * 2 - LastByte - 9);
617 			databitlen = EdonR256_BLOCK_SIZE * 16;
618 #if defined(MACHINE_IS_BIG_ENDIAN)
619 			st_swap64(num_bits, data64 + 15);
620 #else
621 			data64[15] = num_bits;
622 #endif
623 		}
624 
625 		/* LINTED E_BAD_PTR_CAST_ALIGN */
626 		data32 = (uint32_t *)hashState256(state)->LastPart;
627 		state->bits_processed += Q256(databitlen, data32,
628 		    hashState256(state)->DoublePipe);
629 		break;
630 
631 	case 384:
632 	case 512:
633 		LastByte = (int)state->unprocessed_bits >> 3;
634 		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
635 		hashState512(state)->LastPart[LastByte] =
636 		    (hashState512(state)->LastPart[LastByte]
637 		    & (0xff << (PadOnePosition + 1))) ^
638 		    (0x01 << PadOnePosition);
639 		/* LINTED E_BAD_PTR_CAST_ALIGN */
640 		data64 = (uint64_t *)hashState512(state)->LastPart;
641 
642 		if (state->unprocessed_bits < 960) {
643 			(void) memset((hashState512(state)->LastPart) +
644 			    LastByte + 1, 0x00,
645 			    EdonR512_BLOCK_SIZE - LastByte - 9);
646 			databitlen = EdonR512_BLOCK_SIZE * 8;
647 #if defined(MACHINE_IS_BIG_ENDIAN)
648 			st_swap64(num_bits, data64 + 15);
649 #else
650 			data64[15] = num_bits;
651 #endif
652 		} else {
653 			(void) memset((hashState512(state)->LastPart) +
654 			    LastByte + 1, 0x00,
655 			    EdonR512_BLOCK_SIZE * 2 - LastByte - 9);
656 			databitlen = EdonR512_BLOCK_SIZE * 16;
657 #if defined(MACHINE_IS_BIG_ENDIAN)
658 			st_swap64(num_bits, data64 + 31);
659 #else
660 			data64[31] = num_bits;
661 #endif
662 		}
663 
664 		state->bits_processed += Q512(databitlen, data64,
665 		    hashState512(state)->DoublePipe);
666 		break;
667 	}
668 
669 	switch (state->hashbitlen) {
670 	case 224: {
671 #if defined(MACHINE_IS_BIG_ENDIAN)
672 		uint32_t *d32 = (uint32_t *)hashval;
673 		uint32_t *s32 = hashState224(state)->DoublePipe + 9;
674 		int j;
675 
676 		for (j = 0; j < EdonR224_DIGEST_SIZE >> 2; j++)
677 			st_swap32(s32[j], d32 + j);
678 #else
679 		bcopy(hashState256(state)->DoublePipe + 9, hashval,
680 		    EdonR224_DIGEST_SIZE);
681 #endif
682 		break;
683 	}
684 	case 256: {
685 #if defined(MACHINE_IS_BIG_ENDIAN)
686 		uint32_t *d32 = (uint32_t *)hashval;
687 		uint32_t *s32 = hashState224(state)->DoublePipe + 8;
688 		int j;
689 
690 		for (j = 0; j < EdonR256_DIGEST_SIZE >> 2; j++)
691 			st_swap32(s32[j], d32 + j);
692 #else
693 		bcopy(hashState256(state)->DoublePipe + 8, hashval,
694 		    EdonR256_DIGEST_SIZE);
695 #endif
696 		break;
697 	}
698 	case 384: {
699 #if defined(MACHINE_IS_BIG_ENDIAN)
700 		uint64_t *d64 = (uint64_t *)hashval;
701 		uint64_t *s64 = hashState384(state)->DoublePipe + 10;
702 		int j;
703 
704 		for (j = 0; j < EdonR384_DIGEST_SIZE >> 3; j++)
705 			st_swap64(s64[j], d64 + j);
706 #else
707 		bcopy(hashState384(state)->DoublePipe + 10, hashval,
708 		    EdonR384_DIGEST_SIZE);
709 #endif
710 		break;
711 	}
712 	case 512: {
713 #if defined(MACHINE_IS_BIG_ENDIAN)
714 		uint64_t *d64 = (uint64_t *)hashval;
715 		uint64_t *s64 = hashState512(state)->DoublePipe + 8;
716 		int j;
717 
718 		for (j = 0; j < EdonR512_DIGEST_SIZE >> 3; j++)
719 			st_swap64(s64[j], d64 + j);
720 #else
721 		bcopy(hashState512(state)->DoublePipe + 8, hashval,
722 		    EdonR512_DIGEST_SIZE);
723 #endif
724 		break;
725 	}
726 	}
727 }
728 
729 
730 void
731 EdonRHash(size_t hashbitlen, const uint8_t *data, size_t databitlen,
732     uint8_t *hashval)
733 {
734 	EdonRState state;
735 
736 	EdonRInit(&state, hashbitlen);
737 	EdonRUpdate(&state, data, databitlen);
738 	EdonRFinal(&state, hashval);
739 }
740 
741 #ifdef _KERNEL
742 EXPORT_SYMBOL(EdonRInit);
743 EXPORT_SYMBOL(EdonRUpdate);
744 EXPORT_SYMBOL(EdonRHash);
745 EXPORT_SYMBOL(EdonRFinal);
746 #endif
747