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