rmd160.c revision 104476
1104476Ssam/*	$FreeBSD: head/sys/opencrypto/rmd160.c 104476 2002-10-04 20:31:23Z sam $	*/
2104476Ssam/*	$OpenBSD: rmd160.c,v 1.3 2001/09/26 21:40:13 markus Exp $	*/
3104476Ssam/*
4104476Ssam * Copyright (c) 2001 Markus Friedl.  All rights reserved.
5104476Ssam *
6104476Ssam * Redistribution and use in source and binary forms, with or without
7104476Ssam * modification, are permitted provided that the following conditions
8104476Ssam * are met:
9104476Ssam * 1. Redistributions of source code must retain the above copyright
10104476Ssam *    notice, this list of conditions and the following disclaimer.
11104476Ssam * 2. Redistributions in binary form must reproduce the above copyright
12104476Ssam *    notice, this list of conditions and the following disclaimer in the
13104476Ssam *    documentation and/or other materials provided with the distribution.
14104476Ssam *
15104476Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16104476Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17104476Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18104476Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19104476Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20104476Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21104476Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22104476Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23104476Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24104476Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25104476Ssam */
26104476Ssam/*
27104476Ssam * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
28104476Ssam * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
29104476Ssam * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
30104476Ssam */
31104476Ssam#include <sys/param.h>
32104476Ssam#include <sys/systm.h>
33104476Ssam#include <sys/endian.h>
34104476Ssam#include <opencrypto/rmd160.h>
35104476Ssam
36104476Ssam#define PUT_64BIT_LE(cp, value) do { \
37104476Ssam	(cp)[7] = (value) >> 56; \
38104476Ssam	(cp)[6] = (value) >> 48; \
39104476Ssam	(cp)[5] = (value) >> 40; \
40104476Ssam	(cp)[4] = (value) >> 32; \
41104476Ssam	(cp)[3] = (value) >> 24; \
42104476Ssam	(cp)[2] = (value) >> 16; \
43104476Ssam	(cp)[1] = (value) >> 8; \
44104476Ssam	(cp)[0] = (value); } while (0)
45104476Ssam
46104476Ssam#define PUT_32BIT_LE(cp, value) do { \
47104476Ssam	(cp)[3] = (value) >> 24; \
48104476Ssam	(cp)[2] = (value) >> 16; \
49104476Ssam	(cp)[1] = (value) >> 8; \
50104476Ssam	(cp)[0] = (value); } while (0)
51104476Ssam
52104476Ssam#define	H0	0x67452301U
53104476Ssam#define	H1	0xEFCDAB89U
54104476Ssam#define	H2	0x98BADCFEU
55104476Ssam#define	H3	0x10325476U
56104476Ssam#define	H4	0xC3D2E1F0U
57104476Ssam
58104476Ssam#define	K0	0x00000000U
59104476Ssam#define	K1	0x5A827999U
60104476Ssam#define	K2	0x6ED9EBA1U
61104476Ssam#define	K3	0x8F1BBCDCU
62104476Ssam#define	K4	0xA953FD4EU
63104476Ssam
64104476Ssam#define	KK0	0x50A28BE6U
65104476Ssam#define	KK1	0x5C4DD124U
66104476Ssam#define	KK2	0x6D703EF3U
67104476Ssam#define	KK3	0x7A6D76E9U
68104476Ssam#define	KK4	0x00000000U
69104476Ssam
70104476Ssam/* rotate x left n bits.  */
71104476Ssam#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n))))
72104476Ssam
73104476Ssam#define F0(x, y, z) ((x) ^ (y) ^ (z))
74104476Ssam#define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
75104476Ssam#define F2(x, y, z) (((x) | (~y)) ^ (z))
76104476Ssam#define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))
77104476Ssam#define F4(x, y, z) ((x) ^ ((y) | (~z)))
78104476Ssam
79104476Ssam#define R(a, b, c, d, e, Fj, Kj, sj, rj) \
80104476Ssam	do { \
81104476Ssam		a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \
82104476Ssam		c = ROL(10, c); \
83104476Ssam	} while(0)
84104476Ssam
85104476Ssam#define X(i)	x[i]
86104476Ssam
87104476Ssamstatic u_char PADDING[64] = {
88104476Ssam	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89104476Ssam	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90104476Ssam	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
91104476Ssam};
92104476Ssam
93104476Ssamvoid
94104476SsamRMD160Init(RMD160_CTX *ctx)
95104476Ssam{
96104476Ssam	ctx->count = 0;
97104476Ssam	ctx->state[0] = H0;
98104476Ssam	ctx->state[1] = H1;
99104476Ssam	ctx->state[2] = H2;
100104476Ssam	ctx->state[3] = H3;
101104476Ssam	ctx->state[4] = H4;
102104476Ssam}
103104476Ssam
104104476Ssamvoid
105104476SsamRMD160Update(RMD160_CTX *ctx, const u_char *input, u_int32_t len)
106104476Ssam{
107104476Ssam	u_int32_t have, off, need;
108104476Ssam
109104476Ssam	have = (ctx->count/8) % 64;
110104476Ssam	need = 64 - have;
111104476Ssam	ctx->count += 8 * len;
112104476Ssam	off = 0;
113104476Ssam
114104476Ssam	if (len >= need) {
115104476Ssam		if (have) {
116104476Ssam			memcpy(ctx->buffer + have, input, need);
117104476Ssam			RMD160Transform(ctx->state, ctx->buffer);
118104476Ssam			off = need;
119104476Ssam			have = 0;
120104476Ssam		}
121104476Ssam		/* now the buffer is empty */
122104476Ssam		while (off + 64 <= len) {
123104476Ssam			RMD160Transform(ctx->state, input+off);
124104476Ssam			off += 64;
125104476Ssam		}
126104476Ssam	}
127104476Ssam	if (off < len)
128104476Ssam		memcpy(ctx->buffer + have, input+off, len-off);
129104476Ssam}
130104476Ssam
131104476Ssamvoid
132104476SsamRMD160Final(u_char digest[20], RMD160_CTX *ctx)
133104476Ssam{
134104476Ssam	int i;
135104476Ssam	u_char size[8];
136104476Ssam	u_int32_t padlen;
137104476Ssam
138104476Ssam	PUT_64BIT_LE(size, ctx->count);
139104476Ssam
140104476Ssam	/*
141104476Ssam	 * pad to 64 byte blocks, at least one byte from PADDING plus 8 bytes
142104476Ssam	 * for the size
143104476Ssam	 */
144104476Ssam	padlen = 64 - ((ctx->count/8) % 64);
145104476Ssam	if (padlen < 1 + 8)
146104476Ssam		padlen += 64;
147104476Ssam	RMD160Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
148104476Ssam	RMD160Update(ctx, size, 8);
149104476Ssam
150104476Ssam	if (digest != NULL)
151104476Ssam		for (i = 0; i < 5; i++)
152104476Ssam			PUT_32BIT_LE(digest + i*4, ctx->state[i]);
153104476Ssam
154104476Ssam	memset(ctx, 0, sizeof (*ctx));
155104476Ssam}
156104476Ssam
157104476Ssamvoid
158104476SsamRMD160Transform(u_int32_t state[5], const u_char block[64])
159104476Ssam{
160104476Ssam	u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];
161104476Ssam
162104476Ssam#if BYTE_ORDER == LITTLE_ENDIAN
163104476Ssam	memcpy(x, block, 64);
164104476Ssam#else
165104476Ssam	int i;
166104476Ssam
167104476Ssam	for (i = 0; i < 16; i++)
168104476Ssam		x[i] = bswap32(*(const u_int32_t*)(block+i*4));
169104476Ssam#endif
170104476Ssam
171104476Ssam	a = state[0];
172104476Ssam	b = state[1];
173104476Ssam	c = state[2];
174104476Ssam	d = state[3];
175104476Ssam	e = state[4];
176104476Ssam
177104476Ssam	/* Round 1 */
178104476Ssam	R(a, b, c, d, e, F0, K0, 11,  0);
179104476Ssam	R(e, a, b, c, d, F0, K0, 14,  1);
180104476Ssam	R(d, e, a, b, c, F0, K0, 15,  2);
181104476Ssam	R(c, d, e, a, b, F0, K0, 12,  3);
182104476Ssam	R(b, c, d, e, a, F0, K0,  5,  4);
183104476Ssam	R(a, b, c, d, e, F0, K0,  8,  5);
184104476Ssam	R(e, a, b, c, d, F0, K0,  7,  6);
185104476Ssam	R(d, e, a, b, c, F0, K0,  9,  7);
186104476Ssam	R(c, d, e, a, b, F0, K0, 11,  8);
187104476Ssam	R(b, c, d, e, a, F0, K0, 13,  9);
188104476Ssam	R(a, b, c, d, e, F0, K0, 14, 10);
189104476Ssam	R(e, a, b, c, d, F0, K0, 15, 11);
190104476Ssam	R(d, e, a, b, c, F0, K0,  6, 12);
191104476Ssam	R(c, d, e, a, b, F0, K0,  7, 13);
192104476Ssam	R(b, c, d, e, a, F0, K0,  9, 14);
193104476Ssam	R(a, b, c, d, e, F0, K0,  8, 15); /* #15 */
194104476Ssam	/* Round 2 */
195104476Ssam	R(e, a, b, c, d, F1, K1,  7,  7);
196104476Ssam	R(d, e, a, b, c, F1, K1,  6,  4);
197104476Ssam	R(c, d, e, a, b, F1, K1,  8, 13);
198104476Ssam	R(b, c, d, e, a, F1, K1, 13,  1);
199104476Ssam	R(a, b, c, d, e, F1, K1, 11, 10);
200104476Ssam	R(e, a, b, c, d, F1, K1,  9,  6);
201104476Ssam	R(d, e, a, b, c, F1, K1,  7, 15);
202104476Ssam	R(c, d, e, a, b, F1, K1, 15,  3);
203104476Ssam	R(b, c, d, e, a, F1, K1,  7, 12);
204104476Ssam	R(a, b, c, d, e, F1, K1, 12,  0);
205104476Ssam	R(e, a, b, c, d, F1, K1, 15,  9);
206104476Ssam	R(d, e, a, b, c, F1, K1,  9,  5);
207104476Ssam	R(c, d, e, a, b, F1, K1, 11,  2);
208104476Ssam	R(b, c, d, e, a, F1, K1,  7, 14);
209104476Ssam	R(a, b, c, d, e, F1, K1, 13, 11);
210104476Ssam	R(e, a, b, c, d, F1, K1, 12,  8); /* #31 */
211104476Ssam	/* Round 3 */
212104476Ssam	R(d, e, a, b, c, F2, K2, 11,  3);
213104476Ssam	R(c, d, e, a, b, F2, K2, 13, 10);
214104476Ssam	R(b, c, d, e, a, F2, K2,  6, 14);
215104476Ssam	R(a, b, c, d, e, F2, K2,  7,  4);
216104476Ssam	R(e, a, b, c, d, F2, K2, 14,  9);
217104476Ssam	R(d, e, a, b, c, F2, K2,  9, 15);
218104476Ssam	R(c, d, e, a, b, F2, K2, 13,  8);
219104476Ssam	R(b, c, d, e, a, F2, K2, 15,  1);
220104476Ssam	R(a, b, c, d, e, F2, K2, 14,  2);
221104476Ssam	R(e, a, b, c, d, F2, K2,  8,  7);
222104476Ssam	R(d, e, a, b, c, F2, K2, 13,  0);
223104476Ssam	R(c, d, e, a, b, F2, K2,  6,  6);
224104476Ssam	R(b, c, d, e, a, F2, K2,  5, 13);
225104476Ssam	R(a, b, c, d, e, F2, K2, 12, 11);
226104476Ssam	R(e, a, b, c, d, F2, K2,  7,  5);
227104476Ssam	R(d, e, a, b, c, F2, K2,  5, 12); /* #47 */
228104476Ssam	/* Round 4 */
229104476Ssam	R(c, d, e, a, b, F3, K3, 11,  1);
230104476Ssam	R(b, c, d, e, a, F3, K3, 12,  9);
231104476Ssam	R(a, b, c, d, e, F3, K3, 14, 11);
232104476Ssam	R(e, a, b, c, d, F3, K3, 15, 10);
233104476Ssam	R(d, e, a, b, c, F3, K3, 14,  0);
234104476Ssam	R(c, d, e, a, b, F3, K3, 15,  8);
235104476Ssam	R(b, c, d, e, a, F3, K3,  9, 12);
236104476Ssam	R(a, b, c, d, e, F3, K3,  8,  4);
237104476Ssam	R(e, a, b, c, d, F3, K3,  9, 13);
238104476Ssam	R(d, e, a, b, c, F3, K3, 14,  3);
239104476Ssam	R(c, d, e, a, b, F3, K3,  5,  7);
240104476Ssam	R(b, c, d, e, a, F3, K3,  6, 15);
241104476Ssam	R(a, b, c, d, e, F3, K3,  8, 14);
242104476Ssam	R(e, a, b, c, d, F3, K3,  6,  5);
243104476Ssam	R(d, e, a, b, c, F3, K3,  5,  6);
244104476Ssam	R(c, d, e, a, b, F3, K3, 12,  2); /* #63 */
245104476Ssam	/* Round 5 */
246104476Ssam	R(b, c, d, e, a, F4, K4,  9,  4);
247104476Ssam	R(a, b, c, d, e, F4, K4, 15,  0);
248104476Ssam	R(e, a, b, c, d, F4, K4,  5,  5);
249104476Ssam	R(d, e, a, b, c, F4, K4, 11,  9);
250104476Ssam	R(c, d, e, a, b, F4, K4,  6,  7);
251104476Ssam	R(b, c, d, e, a, F4, K4,  8, 12);
252104476Ssam	R(a, b, c, d, e, F4, K4, 13,  2);
253104476Ssam	R(e, a, b, c, d, F4, K4, 12, 10);
254104476Ssam	R(d, e, a, b, c, F4, K4,  5, 14);
255104476Ssam	R(c, d, e, a, b, F4, K4, 12,  1);
256104476Ssam	R(b, c, d, e, a, F4, K4, 13,  3);
257104476Ssam	R(a, b, c, d, e, F4, K4, 14,  8);
258104476Ssam	R(e, a, b, c, d, F4, K4, 11, 11);
259104476Ssam	R(d, e, a, b, c, F4, K4,  8,  6);
260104476Ssam	R(c, d, e, a, b, F4, K4,  5, 15);
261104476Ssam	R(b, c, d, e, a, F4, K4,  6, 13); /* #79 */
262104476Ssam
263104476Ssam	aa = a ; bb = b; cc = c; dd = d; ee = e;
264104476Ssam
265104476Ssam	a = state[0];
266104476Ssam	b = state[1];
267104476Ssam	c = state[2];
268104476Ssam	d = state[3];
269104476Ssam	e = state[4];
270104476Ssam
271104476Ssam	/* Parallel round 1 */
272104476Ssam	R(a, b, c, d, e, F4, KK0,  8,  5);
273104476Ssam	R(e, a, b, c, d, F4, KK0,  9, 14);
274104476Ssam	R(d, e, a, b, c, F4, KK0,  9,  7);
275104476Ssam	R(c, d, e, a, b, F4, KK0, 11,  0);
276104476Ssam	R(b, c, d, e, a, F4, KK0, 13,  9);
277104476Ssam	R(a, b, c, d, e, F4, KK0, 15,  2);
278104476Ssam	R(e, a, b, c, d, F4, KK0, 15, 11);
279104476Ssam	R(d, e, a, b, c, F4, KK0,  5,  4);
280104476Ssam	R(c, d, e, a, b, F4, KK0,  7, 13);
281104476Ssam	R(b, c, d, e, a, F4, KK0,  7,  6);
282104476Ssam	R(a, b, c, d, e, F4, KK0,  8, 15);
283104476Ssam	R(e, a, b, c, d, F4, KK0, 11,  8);
284104476Ssam	R(d, e, a, b, c, F4, KK0, 14,  1);
285104476Ssam	R(c, d, e, a, b, F4, KK0, 14, 10);
286104476Ssam	R(b, c, d, e, a, F4, KK0, 12,  3);
287104476Ssam	R(a, b, c, d, e, F4, KK0,  6, 12); /* #15 */
288104476Ssam	/* Parallel round 2 */
289104476Ssam	R(e, a, b, c, d, F3, KK1,  9,  6);
290104476Ssam	R(d, e, a, b, c, F3, KK1, 13, 11);
291104476Ssam	R(c, d, e, a, b, F3, KK1, 15,  3);
292104476Ssam	R(b, c, d, e, a, F3, KK1,  7,  7);
293104476Ssam	R(a, b, c, d, e, F3, KK1, 12,  0);
294104476Ssam	R(e, a, b, c, d, F3, KK1,  8, 13);
295104476Ssam	R(d, e, a, b, c, F3, KK1,  9,  5);
296104476Ssam	R(c, d, e, a, b, F3, KK1, 11, 10);
297104476Ssam	R(b, c, d, e, a, F3, KK1,  7, 14);
298104476Ssam	R(a, b, c, d, e, F3, KK1,  7, 15);
299104476Ssam	R(e, a, b, c, d, F3, KK1, 12,  8);
300104476Ssam	R(d, e, a, b, c, F3, KK1,  7, 12);
301104476Ssam	R(c, d, e, a, b, F3, KK1,  6,  4);
302104476Ssam	R(b, c, d, e, a, F3, KK1, 15,  9);
303104476Ssam	R(a, b, c, d, e, F3, KK1, 13,  1);
304104476Ssam	R(e, a, b, c, d, F3, KK1, 11,  2); /* #31 */
305104476Ssam	/* Parallel round 3 */
306104476Ssam	R(d, e, a, b, c, F2, KK2,  9, 15);
307104476Ssam	R(c, d, e, a, b, F2, KK2,  7,  5);
308104476Ssam	R(b, c, d, e, a, F2, KK2, 15,  1);
309104476Ssam	R(a, b, c, d, e, F2, KK2, 11,  3);
310104476Ssam	R(e, a, b, c, d, F2, KK2,  8,  7);
311104476Ssam	R(d, e, a, b, c, F2, KK2,  6, 14);
312104476Ssam	R(c, d, e, a, b, F2, KK2,  6,  6);
313104476Ssam	R(b, c, d, e, a, F2, KK2, 14,  9);
314104476Ssam	R(a, b, c, d, e, F2, KK2, 12, 11);
315104476Ssam	R(e, a, b, c, d, F2, KK2, 13,  8);
316104476Ssam	R(d, e, a, b, c, F2, KK2,  5, 12);
317104476Ssam	R(c, d, e, a, b, F2, KK2, 14,  2);
318104476Ssam	R(b, c, d, e, a, F2, KK2, 13, 10);
319104476Ssam	R(a, b, c, d, e, F2, KK2, 13,  0);
320104476Ssam	R(e, a, b, c, d, F2, KK2,  7,  4);
321104476Ssam	R(d, e, a, b, c, F2, KK2,  5, 13); /* #47 */
322104476Ssam	/* Parallel round 4 */
323104476Ssam	R(c, d, e, a, b, F1, KK3, 15,  8);
324104476Ssam	R(b, c, d, e, a, F1, KK3,  5,  6);
325104476Ssam	R(a, b, c, d, e, F1, KK3,  8,  4);
326104476Ssam	R(e, a, b, c, d, F1, KK3, 11,  1);
327104476Ssam	R(d, e, a, b, c, F1, KK3, 14,  3);
328104476Ssam	R(c, d, e, a, b, F1, KK3, 14, 11);
329104476Ssam	R(b, c, d, e, a, F1, KK3,  6, 15);
330104476Ssam	R(a, b, c, d, e, F1, KK3, 14,  0);
331104476Ssam	R(e, a, b, c, d, F1, KK3,  6,  5);
332104476Ssam	R(d, e, a, b, c, F1, KK3,  9, 12);
333104476Ssam	R(c, d, e, a, b, F1, KK3, 12,  2);
334104476Ssam	R(b, c, d, e, a, F1, KK3,  9, 13);
335104476Ssam	R(a, b, c, d, e, F1, KK3, 12,  9);
336104476Ssam	R(e, a, b, c, d, F1, KK3,  5,  7);
337104476Ssam	R(d, e, a, b, c, F1, KK3, 15, 10);
338104476Ssam	R(c, d, e, a, b, F1, KK3,  8, 14); /* #63 */
339104476Ssam	/* Parallel round 5 */
340104476Ssam	R(b, c, d, e, a, F0, KK4,  8, 12);
341104476Ssam	R(a, b, c, d, e, F0, KK4,  5, 15);
342104476Ssam	R(e, a, b, c, d, F0, KK4, 12, 10);
343104476Ssam	R(d, e, a, b, c, F0, KK4,  9,  4);
344104476Ssam	R(c, d, e, a, b, F0, KK4, 12,  1);
345104476Ssam	R(b, c, d, e, a, F0, KK4,  5,  5);
346104476Ssam	R(a, b, c, d, e, F0, KK4, 14,  8);
347104476Ssam	R(e, a, b, c, d, F0, KK4,  6,  7);
348104476Ssam	R(d, e, a, b, c, F0, KK4,  8,  6);
349104476Ssam	R(c, d, e, a, b, F0, KK4, 13,  2);
350104476Ssam	R(b, c, d, e, a, F0, KK4,  6, 13);
351104476Ssam	R(a, b, c, d, e, F0, KK4,  5, 14);
352104476Ssam	R(e, a, b, c, d, F0, KK4, 15,  0);
353104476Ssam	R(d, e, a, b, c, F0, KK4, 13,  3);
354104476Ssam	R(c, d, e, a, b, F0, KK4, 11,  9);
355104476Ssam	R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */
356104476Ssam
357104476Ssam	t =        state[1] + cc + d;
358104476Ssam	state[1] = state[2] + dd + e;
359104476Ssam	state[2] = state[3] + ee + a;
360104476Ssam	state[3] = state[4] + aa + b;
361104476Ssam	state[4] = state[0] + bb + c;
362104476Ssam	state[0] = t;
363104476Ssam}
364