1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 #include "tomcrypt_private.h" 4 5 /** 6 @param rmd128.c 7 RMD128 Hash function 8 */ 9 10 /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC 11 * 12 * This source has been radically overhauled to be portable and work within 13 * the LibTomCrypt API by Tom St Denis 14 */ 15 16 #ifdef LTC_RIPEMD128 17 18 const struct ltc_hash_descriptor rmd128_desc = 19 { 20 "rmd128", 21 8, 22 16, 23 64, 24 25 /* OID */ 26 { 1, 0, 10118, 3, 0, 50 }, 27 6, 28 29 &rmd128_init, 30 &rmd128_process, 31 &rmd128_done, 32 &rmd128_test, 33 NULL 34 }; 35 36 /* the four basic functions F(), G() and H() */ 37 #define F(x, y, z) ((x) ^ (y) ^ (z)) 38 #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) 39 #define H(x, y, z) (((x) | ~(y)) ^ (z)) 40 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) 41 42 /* the eight basic operations FF() through III() */ 43 #define FF(a, b, c, d, x, s) \ 44 (a) += F((b), (c), (d)) + (x);\ 45 (a) = ROLc((a), (s)); 46 47 #define GG(a, b, c, d, x, s) \ 48 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ 49 (a) = ROLc((a), (s)); 50 51 #define HH(a, b, c, d, x, s) \ 52 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ 53 (a) = ROLc((a), (s)); 54 55 #define II(a, b, c, d, x, s) \ 56 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ 57 (a) = ROLc((a), (s)); 58 59 #define FFF(a, b, c, d, x, s) \ 60 (a) += F((b), (c), (d)) + (x);\ 61 (a) = ROLc((a), (s)); 62 63 #define GGG(a, b, c, d, x, s) \ 64 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ 65 (a) = ROLc((a), (s)); 66 67 #define HHH(a, b, c, d, x, s) \ 68 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ 69 (a) = ROLc((a), (s)); 70 71 #define III(a, b, c, d, x, s) \ 72 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ 73 (a) = ROLc((a), (s)); 74 75 #ifdef LTC_CLEAN_STACK 76 static int ss_rmd128_compress(hash_state *md, const unsigned char *buf) 77 #else 78 static int s_rmd128_compress(hash_state *md, const unsigned char *buf) 79 #endif 80 { 81 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; 82 int i; 83 84 /* load words X */ 85 for (i = 0; i < 16; i++){ 86 LOAD32L(X[i], buf + (4 * i)); 87 } 88 89 /* load state */ 90 aa = aaa = md->rmd128.state[0]; 91 bb = bbb = md->rmd128.state[1]; 92 cc = ccc = md->rmd128.state[2]; 93 dd = ddd = md->rmd128.state[3]; 94 95 /* round 1 */ 96 FF(aa, bb, cc, dd, X[ 0], 11); 97 FF(dd, aa, bb, cc, X[ 1], 14); 98 FF(cc, dd, aa, bb, X[ 2], 15); 99 FF(bb, cc, dd, aa, X[ 3], 12); 100 FF(aa, bb, cc, dd, X[ 4], 5); 101 FF(dd, aa, bb, cc, X[ 5], 8); 102 FF(cc, dd, aa, bb, X[ 6], 7); 103 FF(bb, cc, dd, aa, X[ 7], 9); 104 FF(aa, bb, cc, dd, X[ 8], 11); 105 FF(dd, aa, bb, cc, X[ 9], 13); 106 FF(cc, dd, aa, bb, X[10], 14); 107 FF(bb, cc, dd, aa, X[11], 15); 108 FF(aa, bb, cc, dd, X[12], 6); 109 FF(dd, aa, bb, cc, X[13], 7); 110 FF(cc, dd, aa, bb, X[14], 9); 111 FF(bb, cc, dd, aa, X[15], 8); 112 113 /* round 2 */ 114 GG(aa, bb, cc, dd, X[ 7], 7); 115 GG(dd, aa, bb, cc, X[ 4], 6); 116 GG(cc, dd, aa, bb, X[13], 8); 117 GG(bb, cc, dd, aa, X[ 1], 13); 118 GG(aa, bb, cc, dd, X[10], 11); 119 GG(dd, aa, bb, cc, X[ 6], 9); 120 GG(cc, dd, aa, bb, X[15], 7); 121 GG(bb, cc, dd, aa, X[ 3], 15); 122 GG(aa, bb, cc, dd, X[12], 7); 123 GG(dd, aa, bb, cc, X[ 0], 12); 124 GG(cc, dd, aa, bb, X[ 9], 15); 125 GG(bb, cc, dd, aa, X[ 5], 9); 126 GG(aa, bb, cc, dd, X[ 2], 11); 127 GG(dd, aa, bb, cc, X[14], 7); 128 GG(cc, dd, aa, bb, X[11], 13); 129 GG(bb, cc, dd, aa, X[ 8], 12); 130 131 /* round 3 */ 132 HH(aa, bb, cc, dd, X[ 3], 11); 133 HH(dd, aa, bb, cc, X[10], 13); 134 HH(cc, dd, aa, bb, X[14], 6); 135 HH(bb, cc, dd, aa, X[ 4], 7); 136 HH(aa, bb, cc, dd, X[ 9], 14); 137 HH(dd, aa, bb, cc, X[15], 9); 138 HH(cc, dd, aa, bb, X[ 8], 13); 139 HH(bb, cc, dd, aa, X[ 1], 15); 140 HH(aa, bb, cc, dd, X[ 2], 14); 141 HH(dd, aa, bb, cc, X[ 7], 8); 142 HH(cc, dd, aa, bb, X[ 0], 13); 143 HH(bb, cc, dd, aa, X[ 6], 6); 144 HH(aa, bb, cc, dd, X[13], 5); 145 HH(dd, aa, bb, cc, X[11], 12); 146 HH(cc, dd, aa, bb, X[ 5], 7); 147 HH(bb, cc, dd, aa, X[12], 5); 148 149 /* round 4 */ 150 II(aa, bb, cc, dd, X[ 1], 11); 151 II(dd, aa, bb, cc, X[ 9], 12); 152 II(cc, dd, aa, bb, X[11], 14); 153 II(bb, cc, dd, aa, X[10], 15); 154 II(aa, bb, cc, dd, X[ 0], 14); 155 II(dd, aa, bb, cc, X[ 8], 15); 156 II(cc, dd, aa, bb, X[12], 9); 157 II(bb, cc, dd, aa, X[ 4], 8); 158 II(aa, bb, cc, dd, X[13], 9); 159 II(dd, aa, bb, cc, X[ 3], 14); 160 II(cc, dd, aa, bb, X[ 7], 5); 161 II(bb, cc, dd, aa, X[15], 6); 162 II(aa, bb, cc, dd, X[14], 8); 163 II(dd, aa, bb, cc, X[ 5], 6); 164 II(cc, dd, aa, bb, X[ 6], 5); 165 II(bb, cc, dd, aa, X[ 2], 12); 166 167 /* parallel round 1 */ 168 III(aaa, bbb, ccc, ddd, X[ 5], 8); 169 III(ddd, aaa, bbb, ccc, X[14], 9); 170 III(ccc, ddd, aaa, bbb, X[ 7], 9); 171 III(bbb, ccc, ddd, aaa, X[ 0], 11); 172 III(aaa, bbb, ccc, ddd, X[ 9], 13); 173 III(ddd, aaa, bbb, ccc, X[ 2], 15); 174 III(ccc, ddd, aaa, bbb, X[11], 15); 175 III(bbb, ccc, ddd, aaa, X[ 4], 5); 176 III(aaa, bbb, ccc, ddd, X[13], 7); 177 III(ddd, aaa, bbb, ccc, X[ 6], 7); 178 III(ccc, ddd, aaa, bbb, X[15], 8); 179 III(bbb, ccc, ddd, aaa, X[ 8], 11); 180 III(aaa, bbb, ccc, ddd, X[ 1], 14); 181 III(ddd, aaa, bbb, ccc, X[10], 14); 182 III(ccc, ddd, aaa, bbb, X[ 3], 12); 183 III(bbb, ccc, ddd, aaa, X[12], 6); 184 185 /* parallel round 2 */ 186 HHH(aaa, bbb, ccc, ddd, X[ 6], 9); 187 HHH(ddd, aaa, bbb, ccc, X[11], 13); 188 HHH(ccc, ddd, aaa, bbb, X[ 3], 15); 189 HHH(bbb, ccc, ddd, aaa, X[ 7], 7); 190 HHH(aaa, bbb, ccc, ddd, X[ 0], 12); 191 HHH(ddd, aaa, bbb, ccc, X[13], 8); 192 HHH(ccc, ddd, aaa, bbb, X[ 5], 9); 193 HHH(bbb, ccc, ddd, aaa, X[10], 11); 194 HHH(aaa, bbb, ccc, ddd, X[14], 7); 195 HHH(ddd, aaa, bbb, ccc, X[15], 7); 196 HHH(ccc, ddd, aaa, bbb, X[ 8], 12); 197 HHH(bbb, ccc, ddd, aaa, X[12], 7); 198 HHH(aaa, bbb, ccc, ddd, X[ 4], 6); 199 HHH(ddd, aaa, bbb, ccc, X[ 9], 15); 200 HHH(ccc, ddd, aaa, bbb, X[ 1], 13); 201 HHH(bbb, ccc, ddd, aaa, X[ 2], 11); 202 203 /* parallel round 3 */ 204 GGG(aaa, bbb, ccc, ddd, X[15], 9); 205 GGG(ddd, aaa, bbb, ccc, X[ 5], 7); 206 GGG(ccc, ddd, aaa, bbb, X[ 1], 15); 207 GGG(bbb, ccc, ddd, aaa, X[ 3], 11); 208 GGG(aaa, bbb, ccc, ddd, X[ 7], 8); 209 GGG(ddd, aaa, bbb, ccc, X[14], 6); 210 GGG(ccc, ddd, aaa, bbb, X[ 6], 6); 211 GGG(bbb, ccc, ddd, aaa, X[ 9], 14); 212 GGG(aaa, bbb, ccc, ddd, X[11], 12); 213 GGG(ddd, aaa, bbb, ccc, X[ 8], 13); 214 GGG(ccc, ddd, aaa, bbb, X[12], 5); 215 GGG(bbb, ccc, ddd, aaa, X[ 2], 14); 216 GGG(aaa, bbb, ccc, ddd, X[10], 13); 217 GGG(ddd, aaa, bbb, ccc, X[ 0], 13); 218 GGG(ccc, ddd, aaa, bbb, X[ 4], 7); 219 GGG(bbb, ccc, ddd, aaa, X[13], 5); 220 221 /* parallel round 4 */ 222 FFF(aaa, bbb, ccc, ddd, X[ 8], 15); 223 FFF(ddd, aaa, bbb, ccc, X[ 6], 5); 224 FFF(ccc, ddd, aaa, bbb, X[ 4], 8); 225 FFF(bbb, ccc, ddd, aaa, X[ 1], 11); 226 FFF(aaa, bbb, ccc, ddd, X[ 3], 14); 227 FFF(ddd, aaa, bbb, ccc, X[11], 14); 228 FFF(ccc, ddd, aaa, bbb, X[15], 6); 229 FFF(bbb, ccc, ddd, aaa, X[ 0], 14); 230 FFF(aaa, bbb, ccc, ddd, X[ 5], 6); 231 FFF(ddd, aaa, bbb, ccc, X[12], 9); 232 FFF(ccc, ddd, aaa, bbb, X[ 2], 12); 233 FFF(bbb, ccc, ddd, aaa, X[13], 9); 234 FFF(aaa, bbb, ccc, ddd, X[ 9], 12); 235 FFF(ddd, aaa, bbb, ccc, X[ 7], 5); 236 FFF(ccc, ddd, aaa, bbb, X[10], 15); 237 FFF(bbb, ccc, ddd, aaa, X[14], 8); 238 239 /* combine results */ 240 ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ 241 md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; 242 md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; 243 md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; 244 md->rmd128.state[0] = ddd; 245 246 return CRYPT_OK; 247 } 248 249 #ifdef LTC_CLEAN_STACK 250 static int s_rmd128_compress(hash_state *md, const unsigned char *buf) 251 { 252 int err; 253 err = ss_rmd128_compress(md, buf); 254 burn_stack(sizeof(ulong32) * 24 + sizeof(int)); 255 return err; 256 } 257 #endif 258 259 /** 260 Initialize the hash state 261 @param md The hash state you wish to initialize 262 @return CRYPT_OK if successful 263 */ 264 int rmd128_init(hash_state * md) 265 { 266 LTC_ARGCHK(md != NULL); 267 md->rmd128.state[0] = 0x67452301UL; 268 md->rmd128.state[1] = 0xefcdab89UL; 269 md->rmd128.state[2] = 0x98badcfeUL; 270 md->rmd128.state[3] = 0x10325476UL; 271 md->rmd128.curlen = 0; 272 md->rmd128.length = 0; 273 return CRYPT_OK; 274 } 275 276 /** 277 Process a block of memory though the hash 278 @param md The hash state 279 @param in The data to hash 280 @param inlen The length of the data (octets) 281 @return CRYPT_OK if successful 282 */ 283 HASH_PROCESS(rmd128_process, s_rmd128_compress, rmd128, 64) 284 285 /** 286 Terminate the hash to get the digest 287 @param md The hash state 288 @param out [out] The destination of the hash (16 bytes) 289 @return CRYPT_OK if successful 290 */ 291 int rmd128_done(hash_state * md, unsigned char *out) 292 { 293 int i; 294 295 LTC_ARGCHK(md != NULL); 296 LTC_ARGCHK(out != NULL); 297 298 if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { 299 return CRYPT_INVALID_ARG; 300 } 301 302 303 /* increase the length of the message */ 304 md->rmd128.length += md->rmd128.curlen * 8; 305 306 /* append the '1' bit */ 307 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; 308 309 /* if the length is currently above 56 bytes we append zeros 310 * then compress. Then we can fall back to padding zeros and length 311 * encoding like normal. 312 */ 313 if (md->rmd128.curlen > 56) { 314 while (md->rmd128.curlen < 64) { 315 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; 316 } 317 s_rmd128_compress(md, md->rmd128.buf); 318 md->rmd128.curlen = 0; 319 } 320 321 /* pad upto 56 bytes of zeroes */ 322 while (md->rmd128.curlen < 56) { 323 md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; 324 } 325 326 /* store length */ 327 STORE64L(md->rmd128.length, md->rmd128.buf+56); 328 s_rmd128_compress(md, md->rmd128.buf); 329 330 /* copy output */ 331 for (i = 0; i < 4; i++) { 332 STORE32L(md->rmd128.state[i], out+(4*i)); 333 } 334 #ifdef LTC_CLEAN_STACK 335 zeromem(md, sizeof(hash_state)); 336 #endif 337 return CRYPT_OK; 338 } 339 340 /** 341 Self-test the hash 342 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled 343 */ 344 int rmd128_test(void) 345 { 346 #ifndef LTC_TEST 347 return CRYPT_NOP; 348 #else 349 static const struct { 350 const char *msg; 351 unsigned char hash[16]; 352 } tests[] = { 353 { "", 354 { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, 355 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } 356 }, 357 { "a", 358 { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, 359 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } 360 }, 361 { "abc", 362 { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, 363 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } 364 }, 365 { "message digest", 366 { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, 367 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } 368 }, 369 { "abcdefghijklmnopqrstuvwxyz", 370 { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, 371 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } 372 }, 373 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 374 { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, 375 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } 376 } 377 }; 378 379 int i; 380 unsigned char tmp[16]; 381 hash_state md; 382 383 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { 384 rmd128_init(&md); 385 rmd128_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); 386 rmd128_done(&md, tmp); 387 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD128", i)) { 388 return CRYPT_FAIL_TESTVECTOR; 389 } 390 } 391 return CRYPT_OK; 392 #endif 393 } 394 395 #endif 396 397