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