1/* 2 * RIPE MD-160 implementation 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 8/* 9 * The RIPEMD-160 algorithm was designed by RIPE in 1996 10 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html 11 * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 12 */ 13 14#include "common.h" 15 16#if defined(MBEDTLS_RIPEMD160_C) 17 18#include "mbedtls/ripemd160.h" 19#include "mbedtls/platform_util.h" 20#include "mbedtls/error.h" 21 22#include <string.h> 23 24#include "mbedtls/platform.h" 25 26#if !defined(MBEDTLS_RIPEMD160_ALT) 27 28void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx) 29{ 30 memset(ctx, 0, sizeof(mbedtls_ripemd160_context)); 31} 32 33void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx) 34{ 35 if (ctx == NULL) { 36 return; 37 } 38 39 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context)); 40} 41 42void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst, 43 const mbedtls_ripemd160_context *src) 44{ 45 *dst = *src; 46} 47 48/* 49 * RIPEMD-160 context setup 50 */ 51int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx) 52{ 53 ctx->total[0] = 0; 54 ctx->total[1] = 0; 55 56 ctx->state[0] = 0x67452301; 57 ctx->state[1] = 0xEFCDAB89; 58 ctx->state[2] = 0x98BADCFE; 59 ctx->state[3] = 0x10325476; 60 ctx->state[4] = 0xC3D2E1F0; 61 62 return 0; 63} 64 65#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) 66/* 67 * Process one block 68 */ 69int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx, 70 const unsigned char data[64]) 71{ 72 struct { 73 uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; 74 } local; 75 76 local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0); 77 local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4); 78 local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8); 79 local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12); 80 local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16); 81 local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20); 82 local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24); 83 local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28); 84 local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32); 85 local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36); 86 local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40); 87 local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44); 88 local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48); 89 local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52); 90 local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56); 91 local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60); 92 93 local.A = local.Ap = ctx->state[0]; 94 local.B = local.Bp = ctx->state[1]; 95 local.C = local.Cp = ctx->state[2]; 96 local.D = local.Dp = ctx->state[3]; 97 local.E = local.Ep = ctx->state[4]; 98 99#define F1(x, y, z) ((x) ^ (y) ^ (z)) 100#define F2(x, y, z) (((x) & (y)) | (~(x) & (z))) 101#define F3(x, y, z) (((x) | ~(y)) ^ (z)) 102#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z))) 103#define F5(x, y, z) ((x) ^ ((y) | ~(z))) 104 105#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 106 107#define P(a, b, c, d, e, r, s, f, k) \ 108 do \ 109 { \ 110 (a) += f((b), (c), (d)) + local.X[r] + (k); \ 111 (a) = S((a), (s)) + (e); \ 112 (c) = S((c), 10); \ 113 } while (0) 114 115#define P2(a, b, c, d, e, r, s, rp, sp) \ 116 do \ 117 { \ 118 P((a), (b), (c), (d), (e), (r), (s), F, K); \ 119 P(a ## p, b ## p, c ## p, d ## p, e ## p, \ 120 (rp), (sp), Fp, Kp); \ 121 } while (0) 122 123#define F F1 124#define K 0x00000000 125#define Fp F5 126#define Kp 0x50A28BE6 127 P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8); 128 P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9); 129 P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9); 130 P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11); 131 P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13); 132 P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15); 133 P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15); 134 P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5); 135 P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7); 136 P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7); 137 P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8); 138 P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11); 139 P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14); 140 P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14); 141 P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12); 142 P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6); 143#undef F 144#undef K 145#undef Fp 146#undef Kp 147 148#define F F2 149#define K 0x5A827999 150#define Fp F4 151#define Kp 0x5C4DD124 152 P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9); 153 P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13); 154 P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15); 155 P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7); 156 P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12); 157 P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8); 158 P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9); 159 P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11); 160 P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7); 161 P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7); 162 P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12); 163 P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7); 164 P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6); 165 P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15); 166 P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13); 167 P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11); 168#undef F 169#undef K 170#undef Fp 171#undef Kp 172 173#define F F3 174#define K 0x6ED9EBA1 175#define Fp F3 176#define Kp 0x6D703EF3 177 P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9); 178 P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7); 179 P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15); 180 P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11); 181 P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8); 182 P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6); 183 P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6); 184 P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14); 185 P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12); 186 P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13); 187 P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5); 188 P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14); 189 P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13); 190 P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13); 191 P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7); 192 P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5); 193#undef F 194#undef K 195#undef Fp 196#undef Kp 197 198#define F F4 199#define K 0x8F1BBCDC 200#define Fp F2 201#define Kp 0x7A6D76E9 202 P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15); 203 P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5); 204 P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8); 205 P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11); 206 P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14); 207 P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14); 208 P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6); 209 P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14); 210 P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6); 211 P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9); 212 P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12); 213 P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9); 214 P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12); 215 P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5); 216 P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15); 217 P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8); 218#undef F 219#undef K 220#undef Fp 221#undef Kp 222 223#define F F5 224#define K 0xA953FD4E 225#define Fp F1 226#define Kp 0x00000000 227 P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8); 228 P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5); 229 P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12); 230 P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9); 231 P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12); 232 P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5); 233 P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14); 234 P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6); 235 P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8); 236 P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13); 237 P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6); 238 P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5); 239 P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15); 240 P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13); 241 P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11); 242 P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11); 243#undef F 244#undef K 245#undef Fp 246#undef Kp 247 248 local.C = ctx->state[1] + local.C + local.Dp; 249 ctx->state[1] = ctx->state[2] + local.D + local.Ep; 250 ctx->state[2] = ctx->state[3] + local.E + local.Ap; 251 ctx->state[3] = ctx->state[4] + local.A + local.Bp; 252 ctx->state[4] = ctx->state[0] + local.B + local.Cp; 253 ctx->state[0] = local.C; 254 255 /* Zeroise variables to clear sensitive data from memory. */ 256 mbedtls_platform_zeroize(&local, sizeof(local)); 257 258 return 0; 259} 260 261#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ 262 263/* 264 * RIPEMD-160 process buffer 265 */ 266int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, 267 const unsigned char *input, 268 size_t ilen) 269{ 270 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 271 size_t fill; 272 uint32_t left; 273 274 if (ilen == 0) { 275 return 0; 276 } 277 278 left = ctx->total[0] & 0x3F; 279 fill = 64 - left; 280 281 ctx->total[0] += (uint32_t) ilen; 282 ctx->total[0] &= 0xFFFFFFFF; 283 284 if (ctx->total[0] < (uint32_t) ilen) { 285 ctx->total[1]++; 286 } 287 288 if (left && ilen >= fill) { 289 memcpy((void *) (ctx->buffer + left), input, fill); 290 291 if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) { 292 return ret; 293 } 294 295 input += fill; 296 ilen -= fill; 297 left = 0; 298 } 299 300 while (ilen >= 64) { 301 if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) { 302 return ret; 303 } 304 305 input += 64; 306 ilen -= 64; 307 } 308 309 if (ilen > 0) { 310 memcpy((void *) (ctx->buffer + left), input, ilen); 311 } 312 313 return 0; 314} 315 316static const unsigned char ripemd160_padding[64] = 317{ 318 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 322}; 323 324/* 325 * RIPEMD-160 final digest 326 */ 327int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx, 328 unsigned char output[20]) 329{ 330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 331 uint32_t last, padn; 332 uint32_t high, low; 333 unsigned char msglen[8]; 334 335 high = (ctx->total[0] >> 29) 336 | (ctx->total[1] << 3); 337 low = (ctx->total[0] << 3); 338 339 MBEDTLS_PUT_UINT32_LE(low, msglen, 0); 340 MBEDTLS_PUT_UINT32_LE(high, msglen, 4); 341 342 last = ctx->total[0] & 0x3F; 343 padn = (last < 56) ? (56 - last) : (120 - last); 344 345 ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn); 346 if (ret != 0) { 347 goto exit; 348 } 349 350 ret = mbedtls_ripemd160_update(ctx, msglen, 8); 351 if (ret != 0) { 352 goto exit; 353 } 354 355 MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0); 356 MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4); 357 MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8); 358 MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12); 359 MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16); 360 361 ret = 0; 362 363exit: 364 mbedtls_ripemd160_free(ctx); 365 return ret; 366} 367 368#endif /* ! MBEDTLS_RIPEMD160_ALT */ 369 370/* 371 * output = RIPEMD-160( input buffer ) 372 */ 373int mbedtls_ripemd160(const unsigned char *input, 374 size_t ilen, 375 unsigned char output[20]) 376{ 377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 378 mbedtls_ripemd160_context ctx; 379 380 mbedtls_ripemd160_init(&ctx); 381 382 if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) { 383 goto exit; 384 } 385 386 if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) { 387 goto exit; 388 } 389 390 if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) { 391 goto exit; 392 } 393 394exit: 395 mbedtls_ripemd160_free(&ctx); 396 397 return ret; 398} 399 400#if defined(MBEDTLS_SELF_TEST) 401/* 402 * Test vectors from the RIPEMD-160 paper and 403 * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC 404 */ 405#define TESTS 8 406static const unsigned char ripemd160_test_str[TESTS][81] = 407{ 408 { "" }, 409 { "a" }, 410 { "abc" }, 411 { "message digest" }, 412 { "abcdefghijklmnopqrstuvwxyz" }, 413 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 414 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 415 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, 416}; 417 418static const size_t ripemd160_test_strlen[TESTS] = 419{ 420 0, 1, 3, 14, 26, 56, 62, 80 421}; 422 423static const unsigned char ripemd160_test_md[TESTS][20] = 424{ 425 { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, 426 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, 427 { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, 428 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, 429 { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, 430 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, 431 { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, 432 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, 433 { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, 434 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, 435 { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, 436 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, 437 { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, 438 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, 439 { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, 440 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, 441}; 442 443/* 444 * Checkup routine 445 */ 446int mbedtls_ripemd160_self_test(int verbose) 447{ 448 int i, ret = 0; 449 unsigned char output[20]; 450 451 memset(output, 0, sizeof(output)); 452 453 for (i = 0; i < TESTS; i++) { 454 if (verbose != 0) { 455 mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1); 456 } 457 458 ret = mbedtls_ripemd160(ripemd160_test_str[i], 459 ripemd160_test_strlen[i], output); 460 if (ret != 0) { 461 goto fail; 462 } 463 464 if (memcmp(output, ripemd160_test_md[i], 20) != 0) { 465 ret = 1; 466 goto fail; 467 } 468 469 if (verbose != 0) { 470 mbedtls_printf("passed\n"); 471 } 472 } 473 474 if (verbose != 0) { 475 mbedtls_printf("\n"); 476 } 477 478 return 0; 479 480fail: 481 if (verbose != 0) { 482 mbedtls_printf("failed\n"); 483 } 484 485 return ret; 486} 487 488#endif /* MBEDTLS_SELF_TEST */ 489 490#endif /* MBEDTLS_RIPEMD160_C */ 491