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