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