1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 #include "tomcrypt_private.h" 4 5 /** 6 @param rmd256.c 7 RLTC_MD256 Hash function 8 */ 9 10 #ifdef LTC_RIPEMD256 11 12 const struct ltc_hash_descriptor rmd256_desc = 13 { 14 "rmd256", 15 13, 16 32, 17 64, 18 19 /* OID */ 20 { 1, 3, 36, 3, 2, 3 }, 21 6, 22 23 &rmd256_init, 24 &rmd256_process, 25 &rmd256_done, 26 &rmd256_test, 27 NULL 28 }; 29 30 /* the four basic functions F(), G() and H() */ 31 #define F(x, y, z) ((x) ^ (y) ^ (z)) 32 #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) 33 #define H(x, y, z) (((x) | ~(y)) ^ (z)) 34 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) 35 36 /* the eight basic operations FF() through III() */ 37 #define FF(a, b, c, d, x, s) \ 38 (a) += F((b), (c), (d)) + (x);\ 39 (a) = ROLc((a), (s)); 40 41 #define GG(a, b, c, d, x, s) \ 42 (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ 43 (a) = ROLc((a), (s)); 44 45 #define HH(a, b, c, d, x, s) \ 46 (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ 47 (a) = ROLc((a), (s)); 48 49 #define II(a, b, c, d, x, s) \ 50 (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ 51 (a) = ROLc((a), (s)); 52 53 #define FFF(a, b, c, d, x, s) \ 54 (a) += F((b), (c), (d)) + (x);\ 55 (a) = ROLc((a), (s)); 56 57 #define GGG(a, b, c, d, x, s) \ 58 (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ 59 (a) = ROLc((a), (s)); 60 61 #define HHH(a, b, c, d, x, s) \ 62 (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ 63 (a) = ROLc((a), (s)); 64 65 #define III(a, b, c, d, x, s) \ 66 (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ 67 (a) = ROLc((a), (s)); 68 69 #ifdef LTC_CLEAN_STACK 70 static int ss_rmd256_compress(hash_state *md, const unsigned char *buf) 71 #else 72 static int s_rmd256_compress(hash_state *md, const unsigned char *buf) 73 #endif 74 { 75 ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16]; 76 int i; 77 78 /* load words X */ 79 for (i = 0; i < 16; i++){ 80 LOAD32L(X[i], buf + (4 * i)); 81 } 82 83 /* load state */ 84 aa = md->rmd256.state[0]; 85 bb = md->rmd256.state[1]; 86 cc = md->rmd256.state[2]; 87 dd = md->rmd256.state[3]; 88 aaa = md->rmd256.state[4]; 89 bbb = md->rmd256.state[5]; 90 ccc = md->rmd256.state[6]; 91 ddd = md->rmd256.state[7]; 92 93 /* round 1 */ 94 FF(aa, bb, cc, dd, X[ 0], 11); 95 FF(dd, aa, bb, cc, X[ 1], 14); 96 FF(cc, dd, aa, bb, X[ 2], 15); 97 FF(bb, cc, dd, aa, X[ 3], 12); 98 FF(aa, bb, cc, dd, X[ 4], 5); 99 FF(dd, aa, bb, cc, X[ 5], 8); 100 FF(cc, dd, aa, bb, X[ 6], 7); 101 FF(bb, cc, dd, aa, X[ 7], 9); 102 FF(aa, bb, cc, dd, X[ 8], 11); 103 FF(dd, aa, bb, cc, X[ 9], 13); 104 FF(cc, dd, aa, bb, X[10], 14); 105 FF(bb, cc, dd, aa, X[11], 15); 106 FF(aa, bb, cc, dd, X[12], 6); 107 FF(dd, aa, bb, cc, X[13], 7); 108 FF(cc, dd, aa, bb, X[14], 9); 109 FF(bb, cc, dd, aa, X[15], 8); 110 111 /* parallel round 1 */ 112 III(aaa, bbb, ccc, ddd, X[ 5], 8); 113 III(ddd, aaa, bbb, ccc, X[14], 9); 114 III(ccc, ddd, aaa, bbb, X[ 7], 9); 115 III(bbb, ccc, ddd, aaa, X[ 0], 11); 116 III(aaa, bbb, ccc, ddd, X[ 9], 13); 117 III(ddd, aaa, bbb, ccc, X[ 2], 15); 118 III(ccc, ddd, aaa, bbb, X[11], 15); 119 III(bbb, ccc, ddd, aaa, X[ 4], 5); 120 III(aaa, bbb, ccc, ddd, X[13], 7); 121 III(ddd, aaa, bbb, ccc, X[ 6], 7); 122 III(ccc, ddd, aaa, bbb, X[15], 8); 123 III(bbb, ccc, ddd, aaa, X[ 8], 11); 124 III(aaa, bbb, ccc, ddd, X[ 1], 14); 125 III(ddd, aaa, bbb, ccc, X[10], 14); 126 III(ccc, ddd, aaa, bbb, X[ 3], 12); 127 III(bbb, ccc, ddd, aaa, X[12], 6); 128 129 tmp = aa; aa = aaa; aaa = tmp; 130 131 /* round 2 */ 132 GG(aa, bb, cc, dd, X[ 7], 7); 133 GG(dd, aa, bb, cc, X[ 4], 6); 134 GG(cc, dd, aa, bb, X[13], 8); 135 GG(bb, cc, dd, aa, X[ 1], 13); 136 GG(aa, bb, cc, dd, X[10], 11); 137 GG(dd, aa, bb, cc, X[ 6], 9); 138 GG(cc, dd, aa, bb, X[15], 7); 139 GG(bb, cc, dd, aa, X[ 3], 15); 140 GG(aa, bb, cc, dd, X[12], 7); 141 GG(dd, aa, bb, cc, X[ 0], 12); 142 GG(cc, dd, aa, bb, X[ 9], 15); 143 GG(bb, cc, dd, aa, X[ 5], 9); 144 GG(aa, bb, cc, dd, X[ 2], 11); 145 GG(dd, aa, bb, cc, X[14], 7); 146 GG(cc, dd, aa, bb, X[11], 13); 147 GG(bb, cc, dd, aa, X[ 8], 12); 148 149 /* parallel round 2 */ 150 HHH(aaa, bbb, ccc, ddd, X[ 6], 9); 151 HHH(ddd, aaa, bbb, ccc, X[11], 13); 152 HHH(ccc, ddd, aaa, bbb, X[ 3], 15); 153 HHH(bbb, ccc, ddd, aaa, X[ 7], 7); 154 HHH(aaa, bbb, ccc, ddd, X[ 0], 12); 155 HHH(ddd, aaa, bbb, ccc, X[13], 8); 156 HHH(ccc, ddd, aaa, bbb, X[ 5], 9); 157 HHH(bbb, ccc, ddd, aaa, X[10], 11); 158 HHH(aaa, bbb, ccc, ddd, X[14], 7); 159 HHH(ddd, aaa, bbb, ccc, X[15], 7); 160 HHH(ccc, ddd, aaa, bbb, X[ 8], 12); 161 HHH(bbb, ccc, ddd, aaa, X[12], 7); 162 HHH(aaa, bbb, ccc, ddd, X[ 4], 6); 163 HHH(ddd, aaa, bbb, ccc, X[ 9], 15); 164 HHH(ccc, ddd, aaa, bbb, X[ 1], 13); 165 HHH(bbb, ccc, ddd, aaa, X[ 2], 11); 166 167 tmp = bb; bb = bbb; bbb = tmp; 168 169 /* round 3 */ 170 HH(aa, bb, cc, dd, X[ 3], 11); 171 HH(dd, aa, bb, cc, X[10], 13); 172 HH(cc, dd, aa, bb, X[14], 6); 173 HH(bb, cc, dd, aa, X[ 4], 7); 174 HH(aa, bb, cc, dd, X[ 9], 14); 175 HH(dd, aa, bb, cc, X[15], 9); 176 HH(cc, dd, aa, bb, X[ 8], 13); 177 HH(bb, cc, dd, aa, X[ 1], 15); 178 HH(aa, bb, cc, dd, X[ 2], 14); 179 HH(dd, aa, bb, cc, X[ 7], 8); 180 HH(cc, dd, aa, bb, X[ 0], 13); 181 HH(bb, cc, dd, aa, X[ 6], 6); 182 HH(aa, bb, cc, dd, X[13], 5); 183 HH(dd, aa, bb, cc, X[11], 12); 184 HH(cc, dd, aa, bb, X[ 5], 7); 185 HH(bb, cc, dd, aa, X[12], 5); 186 187 /* parallel round 3 */ 188 GGG(aaa, bbb, ccc, ddd, X[15], 9); 189 GGG(ddd, aaa, bbb, ccc, X[ 5], 7); 190 GGG(ccc, ddd, aaa, bbb, X[ 1], 15); 191 GGG(bbb, ccc, ddd, aaa, X[ 3], 11); 192 GGG(aaa, bbb, ccc, ddd, X[ 7], 8); 193 GGG(ddd, aaa, bbb, ccc, X[14], 6); 194 GGG(ccc, ddd, aaa, bbb, X[ 6], 6); 195 GGG(bbb, ccc, ddd, aaa, X[ 9], 14); 196 GGG(aaa, bbb, ccc, ddd, X[11], 12); 197 GGG(ddd, aaa, bbb, ccc, X[ 8], 13); 198 GGG(ccc, ddd, aaa, bbb, X[12], 5); 199 GGG(bbb, ccc, ddd, aaa, X[ 2], 14); 200 GGG(aaa, bbb, ccc, ddd, X[10], 13); 201 GGG(ddd, aaa, bbb, ccc, X[ 0], 13); 202 GGG(ccc, ddd, aaa, bbb, X[ 4], 7); 203 GGG(bbb, ccc, ddd, aaa, X[13], 5); 204 205 tmp = cc; cc = ccc; ccc = tmp; 206 207 /* round 4 */ 208 II(aa, bb, cc, dd, X[ 1], 11); 209 II(dd, aa, bb, cc, X[ 9], 12); 210 II(cc, dd, aa, bb, X[11], 14); 211 II(bb, cc, dd, aa, X[10], 15); 212 II(aa, bb, cc, dd, X[ 0], 14); 213 II(dd, aa, bb, cc, X[ 8], 15); 214 II(cc, dd, aa, bb, X[12], 9); 215 II(bb, cc, dd, aa, X[ 4], 8); 216 II(aa, bb, cc, dd, X[13], 9); 217 II(dd, aa, bb, cc, X[ 3], 14); 218 II(cc, dd, aa, bb, X[ 7], 5); 219 II(bb, cc, dd, aa, X[15], 6); 220 II(aa, bb, cc, dd, X[14], 8); 221 II(dd, aa, bb, cc, X[ 5], 6); 222 II(cc, dd, aa, bb, X[ 6], 5); 223 II(bb, cc, dd, aa, X[ 2], 12); 224 225 /* parallel round 4 */ 226 FFF(aaa, bbb, ccc, ddd, X[ 8], 15); 227 FFF(ddd, aaa, bbb, ccc, X[ 6], 5); 228 FFF(ccc, ddd, aaa, bbb, X[ 4], 8); 229 FFF(bbb, ccc, ddd, aaa, X[ 1], 11); 230 FFF(aaa, bbb, ccc, ddd, X[ 3], 14); 231 FFF(ddd, aaa, bbb, ccc, X[11], 14); 232 FFF(ccc, ddd, aaa, bbb, X[15], 6); 233 FFF(bbb, ccc, ddd, aaa, X[ 0], 14); 234 FFF(aaa, bbb, ccc, ddd, X[ 5], 6); 235 FFF(ddd, aaa, bbb, ccc, X[12], 9); 236 FFF(ccc, ddd, aaa, bbb, X[ 2], 12); 237 FFF(bbb, ccc, ddd, aaa, X[13], 9); 238 FFF(aaa, bbb, ccc, ddd, X[ 9], 12); 239 FFF(ddd, aaa, bbb, ccc, X[ 7], 5); 240 FFF(ccc, ddd, aaa, bbb, X[10], 15); 241 FFF(bbb, ccc, ddd, aaa, X[14], 8); 242 243 tmp = dd; dd = ddd; ddd = tmp; 244 245 /* combine results */ 246 md->rmd256.state[0] += aa; 247 md->rmd256.state[1] += bb; 248 md->rmd256.state[2] += cc; 249 md->rmd256.state[3] += dd; 250 md->rmd256.state[4] += aaa; 251 md->rmd256.state[5] += bbb; 252 md->rmd256.state[6] += ccc; 253 md->rmd256.state[7] += ddd; 254 255 return CRYPT_OK; 256 } 257 258 #ifdef LTC_CLEAN_STACK 259 static int s_rmd256_compress(hash_state *md, const unsigned char *buf) 260 { 261 int err; 262 err = ss_rmd256_compress(md, buf); 263 burn_stack(sizeof(ulong32) * 25 + sizeof(int)); 264 return err; 265 } 266 #endif 267 268 /** 269 Initialize the hash state 270 @param md The hash state you wish to initialize 271 @return CRYPT_OK if successful 272 */ 273 int rmd256_init(hash_state * md) 274 { 275 LTC_ARGCHK(md != NULL); 276 md->rmd256.state[0] = 0x67452301UL; 277 md->rmd256.state[1] = 0xefcdab89UL; 278 md->rmd256.state[2] = 0x98badcfeUL; 279 md->rmd256.state[3] = 0x10325476UL; 280 md->rmd256.state[4] = 0x76543210UL; 281 md->rmd256.state[5] = 0xfedcba98UL; 282 md->rmd256.state[6] = 0x89abcdefUL; 283 md->rmd256.state[7] = 0x01234567UL; 284 md->rmd256.curlen = 0; 285 md->rmd256.length = 0; 286 return CRYPT_OK; 287 } 288 289 /** 290 Process a block of memory though the hash 291 @param md The hash state 292 @param in The data to hash 293 @param inlen The length of the data (octets) 294 @return CRYPT_OK if successful 295 */ 296 HASH_PROCESS(rmd256_process, s_rmd256_compress, rmd256, 64) 297 298 /** 299 Terminate the hash to get the digest 300 @param md The hash state 301 @param out [out] The destination of the hash (16 bytes) 302 @return CRYPT_OK if successful 303 */ 304 int rmd256_done(hash_state * md, unsigned char *out) 305 { 306 int i; 307 308 LTC_ARGCHK(md != NULL); 309 LTC_ARGCHK(out != NULL); 310 311 if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) { 312 return CRYPT_INVALID_ARG; 313 } 314 315 316 /* increase the length of the message */ 317 md->rmd256.length += md->rmd256.curlen * 8; 318 319 /* append the '1' bit */ 320 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80; 321 322 /* if the length is currently above 56 bytes we append zeros 323 * then compress. Then we can fall back to padding zeros and length 324 * encoding like normal. 325 */ 326 if (md->rmd256.curlen > 56) { 327 while (md->rmd256.curlen < 64) { 328 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; 329 } 330 s_rmd256_compress(md, md->rmd256.buf); 331 md->rmd256.curlen = 0; 332 } 333 334 /* pad upto 56 bytes of zeroes */ 335 while (md->rmd256.curlen < 56) { 336 md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; 337 } 338 339 /* store length */ 340 STORE64L(md->rmd256.length, md->rmd256.buf+56); 341 s_rmd256_compress(md, md->rmd256.buf); 342 343 /* copy output */ 344 for (i = 0; i < 8; i++) { 345 STORE32L(md->rmd256.state[i], out+(4*i)); 346 } 347 #ifdef LTC_CLEAN_STACK 348 zeromem(md, sizeof(hash_state)); 349 #endif 350 return CRYPT_OK; 351 } 352 353 /** 354 Self-test the hash 355 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled 356 */ 357 int rmd256_test(void) 358 { 359 #ifndef LTC_TEST 360 return CRYPT_NOP; 361 #else 362 static const struct { 363 const char *msg; 364 unsigned char hash[32]; 365 } tests[] = { 366 { "", 367 { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18, 368 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a, 369 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63, 370 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d } 371 }, 372 { "a", 373 { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9, 374 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c, 375 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf, 376 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 } 377 }, 378 { "abc", 379 { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb, 380 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1, 381 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e, 382 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 } 383 }, 384 { "message digest", 385 { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a, 386 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90, 387 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55, 388 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e } 389 }, 390 { "abcdefghijklmnopqrstuvwxyz", 391 { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16, 392 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc, 393 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87, 394 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 } 395 }, 396 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 397 { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20, 398 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f, 399 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1, 400 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 } 401 } 402 }; 403 404 int i; 405 unsigned char tmp[32]; 406 hash_state md; 407 408 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { 409 rmd256_init(&md); 410 rmd256_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); 411 rmd256_done(&md, tmp); 412 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD256", i)) { 413 return CRYPT_FAIL_TESTVECTOR; 414 } 415 } 416 return CRYPT_OK; 417 #endif 418 } 419 420 #endif 421