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