1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * RIPE MD-160 implementation 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander 20817466cbSJens Wiklander /* 21817466cbSJens Wiklander * The RIPEMD-160 algorithm was designed by RIPE in 1996 22817466cbSJens Wiklander * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html 23817466cbSJens Wiklander * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 24817466cbSJens Wiklander */ 25817466cbSJens Wiklander 267901324dSJerome Forissier #include "common.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 29817466cbSJens Wiklander 30817466cbSJens Wiklander #include "mbedtls/ripemd160.h" 313d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 3211fa71b9SJerome Forissier #include "mbedtls/error.h" 33817466cbSJens Wiklander 34817466cbSJens Wiklander #include <string.h> 35817466cbSJens Wiklander 36817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 37817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 38817466cbSJens Wiklander #include "mbedtls/platform.h" 39817466cbSJens Wiklander #else 40817466cbSJens Wiklander #include <stdio.h> 41817466cbSJens Wiklander #define mbedtls_printf printf 42817466cbSJens Wiklander #endif /* MBEDTLS_PLATFORM_C */ 43817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 44817466cbSJens Wiklander 453d3b0591SJens Wiklander #if !defined(MBEDTLS_RIPEMD160_ALT) 463d3b0591SJens Wiklander 47817466cbSJens Wiklander void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) 48817466cbSJens Wiklander { 49817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); 50817466cbSJens Wiklander } 51817466cbSJens Wiklander 52817466cbSJens Wiklander void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) 53817466cbSJens Wiklander { 54817466cbSJens Wiklander if( ctx == NULL ) 55817466cbSJens Wiklander return; 56817466cbSJens Wiklander 573d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); 58817466cbSJens Wiklander } 59817466cbSJens Wiklander 60817466cbSJens Wiklander void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, 61817466cbSJens Wiklander const mbedtls_ripemd160_context *src ) 62817466cbSJens Wiklander { 63817466cbSJens Wiklander *dst = *src; 64817466cbSJens Wiklander } 65817466cbSJens Wiklander 66817466cbSJens Wiklander /* 67817466cbSJens Wiklander * RIPEMD-160 context setup 68817466cbSJens Wiklander */ 693d3b0591SJens Wiklander int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ) 70817466cbSJens Wiklander { 71817466cbSJens Wiklander ctx->total[0] = 0; 72817466cbSJens Wiklander ctx->total[1] = 0; 73817466cbSJens Wiklander 74817466cbSJens Wiklander ctx->state[0] = 0x67452301; 75817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89; 76817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE; 77817466cbSJens Wiklander ctx->state[3] = 0x10325476; 78817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0; 793d3b0591SJens Wiklander 803d3b0591SJens Wiklander return( 0 ); 81817466cbSJens Wiklander } 82817466cbSJens Wiklander 833d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 843d3b0591SJens Wiklander void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) 853d3b0591SJens Wiklander { 863d3b0591SJens Wiklander mbedtls_ripemd160_starts_ret( ctx ); 873d3b0591SJens Wiklander } 883d3b0591SJens Wiklander #endif 893d3b0591SJens Wiklander 90817466cbSJens Wiklander #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) 91817466cbSJens Wiklander /* 92817466cbSJens Wiklander * Process one block 93817466cbSJens Wiklander */ 943d3b0591SJens Wiklander int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, 953d3b0591SJens Wiklander const unsigned char data[64] ) 96817466cbSJens Wiklander { 977901324dSJerome Forissier struct 987901324dSJerome Forissier { 99817466cbSJens Wiklander uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; 1007901324dSJerome Forissier } local; 101817466cbSJens Wiklander 102*039e02dfSJerome Forissier local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 ); 103*039e02dfSJerome Forissier local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 ); 104*039e02dfSJerome Forissier local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 ); 105*039e02dfSJerome Forissier local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 ); 106*039e02dfSJerome Forissier local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 ); 107*039e02dfSJerome Forissier local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 ); 108*039e02dfSJerome Forissier local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 ); 109*039e02dfSJerome Forissier local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 ); 110*039e02dfSJerome Forissier local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 ); 111*039e02dfSJerome Forissier local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 ); 112*039e02dfSJerome Forissier local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 ); 113*039e02dfSJerome Forissier local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 ); 114*039e02dfSJerome Forissier local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 ); 115*039e02dfSJerome Forissier local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 ); 116*039e02dfSJerome Forissier local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 ); 117*039e02dfSJerome Forissier local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 ); 118817466cbSJens Wiklander 1197901324dSJerome Forissier local.A = local.Ap = ctx->state[0]; 1207901324dSJerome Forissier local.B = local.Bp = ctx->state[1]; 1217901324dSJerome Forissier local.C = local.Cp = ctx->state[2]; 1227901324dSJerome Forissier local.D = local.Dp = ctx->state[3]; 1237901324dSJerome Forissier local.E = local.Ep = ctx->state[4]; 124817466cbSJens Wiklander 1255b25c76aSJerome Forissier #define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) 1265b25c76aSJerome Forissier #define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) 1275b25c76aSJerome Forissier #define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) ) 1285b25c76aSJerome Forissier #define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) ) 1295b25c76aSJerome Forissier #define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) ) 130817466cbSJens Wiklander 1315b25c76aSJerome Forissier #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) 132817466cbSJens Wiklander 133817466cbSJens Wiklander #define P( a, b, c, d, e, r, s, f, k ) \ 1345b25c76aSJerome Forissier do \ 1355b25c76aSJerome Forissier { \ 1367901324dSJerome Forissier (a) += f( (b), (c), (d) ) + local.X[r] + (k); \ 1375b25c76aSJerome Forissier (a) = S( (a), (s) ) + (e); \ 1385b25c76aSJerome Forissier (c) = S( (c), 10 ); \ 1395b25c76aSJerome Forissier } while( 0 ) 140817466cbSJens Wiklander 141817466cbSJens Wiklander #define P2( a, b, c, d, e, r, s, rp, sp ) \ 1425b25c76aSJerome Forissier do \ 1435b25c76aSJerome Forissier { \ 1445b25c76aSJerome Forissier P( (a), (b), (c), (d), (e), (r), (s), F, K ); \ 1455b25c76aSJerome Forissier P( a ## p, b ## p, c ## p, d ## p, e ## p, \ 1465b25c76aSJerome Forissier (rp), (sp), Fp, Kp ); \ 1475b25c76aSJerome Forissier } while( 0 ) 148817466cbSJens Wiklander 149817466cbSJens Wiklander #define F F1 150817466cbSJens Wiklander #define K 0x00000000 151817466cbSJens Wiklander #define Fp F5 152817466cbSJens Wiklander #define Kp 0x50A28BE6 1537901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 ); 1547901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 ); 1557901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 ); 1567901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 ); 1577901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 ); 1587901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 ); 1597901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 ); 1607901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 ); 1617901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 ); 1627901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 ); 1637901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 ); 1647901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 ); 1657901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 ); 1667901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 ); 1677901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 ); 1687901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 ); 169817466cbSJens Wiklander #undef F 170817466cbSJens Wiklander #undef K 171817466cbSJens Wiklander #undef Fp 172817466cbSJens Wiklander #undef Kp 173817466cbSJens Wiklander 174817466cbSJens Wiklander #define F F2 175817466cbSJens Wiklander #define K 0x5A827999 176817466cbSJens Wiklander #define Fp F4 177817466cbSJens Wiklander #define Kp 0x5C4DD124 1787901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 ); 1797901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 ); 1807901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 ); 1817901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 ); 1827901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 ); 1837901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 ); 1847901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 ); 1857901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 ); 1867901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 ); 1877901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 ); 1887901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 ); 1897901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 ); 1907901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 ); 1917901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 ); 1927901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 ); 1937901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 ); 194817466cbSJens Wiklander #undef F 195817466cbSJens Wiklander #undef K 196817466cbSJens Wiklander #undef Fp 197817466cbSJens Wiklander #undef Kp 198817466cbSJens Wiklander 199817466cbSJens Wiklander #define F F3 200817466cbSJens Wiklander #define K 0x6ED9EBA1 201817466cbSJens Wiklander #define Fp F3 202817466cbSJens Wiklander #define Kp 0x6D703EF3 2037901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 ); 2047901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 ); 2057901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 ); 2067901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 ); 2077901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 ); 2087901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 ); 2097901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 ); 2107901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 ); 2117901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 ); 2127901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 ); 2137901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 ); 2147901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 ); 2157901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 ); 2167901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 ); 2177901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 ); 2187901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 ); 219817466cbSJens Wiklander #undef F 220817466cbSJens Wiklander #undef K 221817466cbSJens Wiklander #undef Fp 222817466cbSJens Wiklander #undef Kp 223817466cbSJens Wiklander 224817466cbSJens Wiklander #define F F4 225817466cbSJens Wiklander #define K 0x8F1BBCDC 226817466cbSJens Wiklander #define Fp F2 227817466cbSJens Wiklander #define Kp 0x7A6D76E9 2287901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 ); 2297901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 ); 2307901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 ); 2317901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 ); 2327901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 ); 2337901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 ); 2347901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 ); 2357901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 ); 2367901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 ); 2377901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 ); 2387901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 ); 2397901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 ); 2407901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 ); 2417901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 ); 2427901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 ); 2437901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 ); 244817466cbSJens Wiklander #undef F 245817466cbSJens Wiklander #undef K 246817466cbSJens Wiklander #undef Fp 247817466cbSJens Wiklander #undef Kp 248817466cbSJens Wiklander 249817466cbSJens Wiklander #define F F5 250817466cbSJens Wiklander #define K 0xA953FD4E 251817466cbSJens Wiklander #define Fp F1 252817466cbSJens Wiklander #define Kp 0x00000000 2537901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 ); 2547901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 ); 2557901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 ); 2567901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 ); 2577901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 ); 2587901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 ); 2597901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 ); 2607901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 ); 2617901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 ); 2627901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 ); 2637901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 ); 2647901324dSJerome Forissier P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 ); 2657901324dSJerome Forissier P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 ); 2667901324dSJerome Forissier P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 ); 2677901324dSJerome Forissier P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 ); 2687901324dSJerome Forissier P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 ); 269817466cbSJens Wiklander #undef F 270817466cbSJens Wiklander #undef K 271817466cbSJens Wiklander #undef Fp 272817466cbSJens Wiklander #undef Kp 273817466cbSJens Wiklander 2747901324dSJerome Forissier local.C = ctx->state[1] + local.C + local.Dp; 2757901324dSJerome Forissier ctx->state[1] = ctx->state[2] + local.D + local.Ep; 2767901324dSJerome Forissier ctx->state[2] = ctx->state[3] + local.E + local.Ap; 2777901324dSJerome Forissier ctx->state[3] = ctx->state[4] + local.A + local.Bp; 2787901324dSJerome Forissier ctx->state[4] = ctx->state[0] + local.B + local.Cp; 2797901324dSJerome Forissier ctx->state[0] = local.C; 2807901324dSJerome Forissier 2817901324dSJerome Forissier /* Zeroise variables to clear sensitive data from memory. */ 2827901324dSJerome Forissier mbedtls_platform_zeroize( &local, sizeof( local ) ); 2833d3b0591SJens Wiklander 2843d3b0591SJens Wiklander return( 0 ); 285817466cbSJens Wiklander } 2863d3b0591SJens Wiklander 2873d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 2883d3b0591SJens Wiklander void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, 2893d3b0591SJens Wiklander const unsigned char data[64] ) 2903d3b0591SJens Wiklander { 2913d3b0591SJens Wiklander mbedtls_internal_ripemd160_process( ctx, data ); 2923d3b0591SJens Wiklander } 2933d3b0591SJens Wiklander #endif 294817466cbSJens Wiklander #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ 295817466cbSJens Wiklander 296817466cbSJens Wiklander /* 297817466cbSJens Wiklander * RIPEMD-160 process buffer 298817466cbSJens Wiklander */ 2993d3b0591SJens Wiklander int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, 3003d3b0591SJens Wiklander const unsigned char *input, 3013d3b0591SJens Wiklander size_t ilen ) 302817466cbSJens Wiklander { 30311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 304817466cbSJens Wiklander size_t fill; 305817466cbSJens Wiklander uint32_t left; 306817466cbSJens Wiklander 307817466cbSJens Wiklander if( ilen == 0 ) 3083d3b0591SJens Wiklander return( 0 ); 309817466cbSJens Wiklander 310817466cbSJens Wiklander left = ctx->total[0] & 0x3F; 311817466cbSJens Wiklander fill = 64 - left; 312817466cbSJens Wiklander 313817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen; 314817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF; 315817466cbSJens Wiklander 316817466cbSJens Wiklander if( ctx->total[0] < (uint32_t) ilen ) 317817466cbSJens Wiklander ctx->total[1]++; 318817466cbSJens Wiklander 319817466cbSJens Wiklander if( left && ilen >= fill ) 320817466cbSJens Wiklander { 321817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, fill ); 3223d3b0591SJens Wiklander 3233d3b0591SJens Wiklander if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 ) 3243d3b0591SJens Wiklander return( ret ); 3253d3b0591SJens Wiklander 326817466cbSJens Wiklander input += fill; 327817466cbSJens Wiklander ilen -= fill; 328817466cbSJens Wiklander left = 0; 329817466cbSJens Wiklander } 330817466cbSJens Wiklander 331817466cbSJens Wiklander while( ilen >= 64 ) 332817466cbSJens Wiklander { 3333d3b0591SJens Wiklander if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 ) 3343d3b0591SJens Wiklander return( ret ); 3353d3b0591SJens Wiklander 336817466cbSJens Wiklander input += 64; 337817466cbSJens Wiklander ilen -= 64; 338817466cbSJens Wiklander } 339817466cbSJens Wiklander 340817466cbSJens Wiklander if( ilen > 0 ) 341817466cbSJens Wiklander { 342817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, ilen ); 343817466cbSJens Wiklander } 3443d3b0591SJens Wiklander 3453d3b0591SJens Wiklander return( 0 ); 346817466cbSJens Wiklander } 347817466cbSJens Wiklander 3483d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 3493d3b0591SJens Wiklander void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, 3503d3b0591SJens Wiklander const unsigned char *input, 3513d3b0591SJens Wiklander size_t ilen ) 3523d3b0591SJens Wiklander { 3533d3b0591SJens Wiklander mbedtls_ripemd160_update_ret( ctx, input, ilen ); 3543d3b0591SJens Wiklander } 3553d3b0591SJens Wiklander #endif 3563d3b0591SJens Wiklander 357817466cbSJens Wiklander static const unsigned char ripemd160_padding[64] = 358817466cbSJens Wiklander { 359817466cbSJens Wiklander 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 363817466cbSJens Wiklander }; 364817466cbSJens Wiklander 365817466cbSJens Wiklander /* 366817466cbSJens Wiklander * RIPEMD-160 final digest 367817466cbSJens Wiklander */ 3683d3b0591SJens Wiklander int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, 3693d3b0591SJens Wiklander unsigned char output[20] ) 370817466cbSJens Wiklander { 37111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 372817466cbSJens Wiklander uint32_t last, padn; 373817466cbSJens Wiklander uint32_t high, low; 374817466cbSJens Wiklander unsigned char msglen[8]; 375817466cbSJens Wiklander 376817466cbSJens Wiklander high = ( ctx->total[0] >> 29 ) 377817466cbSJens Wiklander | ( ctx->total[1] << 3 ); 378817466cbSJens Wiklander low = ( ctx->total[0] << 3 ); 379817466cbSJens Wiklander 380*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( low, msglen, 0 ); 381*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( high, msglen, 4 ); 382817466cbSJens Wiklander 383817466cbSJens Wiklander last = ctx->total[0] & 0x3F; 384817466cbSJens Wiklander padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 385817466cbSJens Wiklander 3863d3b0591SJens Wiklander ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn ); 3873d3b0591SJens Wiklander if( ret != 0 ) 3883d3b0591SJens Wiklander return( ret ); 3893d3b0591SJens Wiklander 3903d3b0591SJens Wiklander ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 ); 3913d3b0591SJens Wiklander if( ret != 0 ) 3923d3b0591SJens Wiklander return( ret ); 393817466cbSJens Wiklander 394*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 ); 395*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 ); 396*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 ); 397*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 ); 398*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 ); 3993d3b0591SJens Wiklander 4003d3b0591SJens Wiklander return( 0 ); 401817466cbSJens Wiklander } 402817466cbSJens Wiklander 4033d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 4043d3b0591SJens Wiklander void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, 4053d3b0591SJens Wiklander unsigned char output[20] ) 4063d3b0591SJens Wiklander { 4073d3b0591SJens Wiklander mbedtls_ripemd160_finish_ret( ctx, output ); 4083d3b0591SJens Wiklander } 4093d3b0591SJens Wiklander #endif 4103d3b0591SJens Wiklander 4113d3b0591SJens Wiklander #endif /* ! MBEDTLS_RIPEMD160_ALT */ 4123d3b0591SJens Wiklander 413817466cbSJens Wiklander /* 414817466cbSJens Wiklander * output = RIPEMD-160( input buffer ) 415817466cbSJens Wiklander */ 4163d3b0591SJens Wiklander int mbedtls_ripemd160_ret( const unsigned char *input, 4173d3b0591SJens Wiklander size_t ilen, 418817466cbSJens Wiklander unsigned char output[20] ) 419817466cbSJens Wiklander { 42011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 421817466cbSJens Wiklander mbedtls_ripemd160_context ctx; 422817466cbSJens Wiklander 423817466cbSJens Wiklander mbedtls_ripemd160_init( &ctx ); 4243d3b0591SJens Wiklander 4253d3b0591SJens Wiklander if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 ) 4263d3b0591SJens Wiklander goto exit; 4273d3b0591SJens Wiklander 4283d3b0591SJens Wiklander if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 ) 4293d3b0591SJens Wiklander goto exit; 4303d3b0591SJens Wiklander 4313d3b0591SJens Wiklander if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 ) 4323d3b0591SJens Wiklander goto exit; 4333d3b0591SJens Wiklander 4343d3b0591SJens Wiklander exit: 435817466cbSJens Wiklander mbedtls_ripemd160_free( &ctx ); 4363d3b0591SJens Wiklander 4373d3b0591SJens Wiklander return( ret ); 438817466cbSJens Wiklander } 439817466cbSJens Wiklander 4403d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 4413d3b0591SJens Wiklander void mbedtls_ripemd160( const unsigned char *input, 4423d3b0591SJens Wiklander size_t ilen, 4433d3b0591SJens Wiklander unsigned char output[20] ) 4443d3b0591SJens Wiklander { 4453d3b0591SJens Wiklander mbedtls_ripemd160_ret( input, ilen, output ); 4463d3b0591SJens Wiklander } 4473d3b0591SJens Wiklander #endif 4483d3b0591SJens Wiklander 449817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 450817466cbSJens Wiklander /* 451817466cbSJens Wiklander * Test vectors from the RIPEMD-160 paper and 452817466cbSJens Wiklander * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC 453817466cbSJens Wiklander */ 454817466cbSJens Wiklander #define TESTS 8 4553d3b0591SJens Wiklander static const unsigned char ripemd160_test_str[TESTS][81] = 456817466cbSJens Wiklander { 4573d3b0591SJens Wiklander { "" }, 4583d3b0591SJens Wiklander { "a" }, 4593d3b0591SJens Wiklander { "abc" }, 4603d3b0591SJens Wiklander { "message digest" }, 4613d3b0591SJens Wiklander { "abcdefghijklmnopqrstuvwxyz" }, 4623d3b0591SJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 4633d3b0591SJens Wiklander { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 46436905f94SGuido Vranken { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, 4653d3b0591SJens Wiklander }; 4663d3b0591SJens Wiklander 4673d3b0591SJens Wiklander static const size_t ripemd160_test_strlen[TESTS] = 4683d3b0591SJens Wiklander { 4693d3b0591SJens Wiklander 0, 1, 3, 14, 26, 56, 62, 80 470817466cbSJens Wiklander }; 471817466cbSJens Wiklander 472817466cbSJens Wiklander static const unsigned char ripemd160_test_md[TESTS][20] = 473817466cbSJens Wiklander { 474817466cbSJens Wiklander { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, 475817466cbSJens Wiklander 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, 476817466cbSJens Wiklander { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, 477817466cbSJens Wiklander 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, 478817466cbSJens Wiklander { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, 479817466cbSJens Wiklander 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, 480817466cbSJens Wiklander { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, 481817466cbSJens Wiklander 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, 482817466cbSJens Wiklander { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, 483817466cbSJens Wiklander 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, 484817466cbSJens Wiklander { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, 485817466cbSJens Wiklander 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, 486817466cbSJens Wiklander { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, 487817466cbSJens Wiklander 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, 488817466cbSJens Wiklander { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, 489817466cbSJens Wiklander 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, 490817466cbSJens Wiklander }; 491817466cbSJens Wiklander 492817466cbSJens Wiklander /* 493817466cbSJens Wiklander * Checkup routine 494817466cbSJens Wiklander */ 495817466cbSJens Wiklander int mbedtls_ripemd160_self_test( int verbose ) 496817466cbSJens Wiklander { 4973d3b0591SJens Wiklander int i, ret = 0; 498817466cbSJens Wiklander unsigned char output[20]; 499817466cbSJens Wiklander 500817466cbSJens Wiklander memset( output, 0, sizeof output ); 501817466cbSJens Wiklander 502817466cbSJens Wiklander for( i = 0; i < TESTS; i++ ) 503817466cbSJens Wiklander { 504817466cbSJens Wiklander if( verbose != 0 ) 505817466cbSJens Wiklander mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); 506817466cbSJens Wiklander 5073d3b0591SJens Wiklander ret = mbedtls_ripemd160_ret( ripemd160_test_str[i], 5083d3b0591SJens Wiklander ripemd160_test_strlen[i], output ); 5093d3b0591SJens Wiklander if( ret != 0 ) 5103d3b0591SJens Wiklander goto fail; 511817466cbSJens Wiklander 512817466cbSJens Wiklander if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) 513817466cbSJens Wiklander { 5143d3b0591SJens Wiklander ret = 1; 5153d3b0591SJens Wiklander goto fail; 516817466cbSJens Wiklander } 517817466cbSJens Wiklander 518817466cbSJens Wiklander if( verbose != 0 ) 519817466cbSJens Wiklander mbedtls_printf( "passed\n" ); 520817466cbSJens Wiklander } 521817466cbSJens Wiklander 522817466cbSJens Wiklander if( verbose != 0 ) 523817466cbSJens Wiklander mbedtls_printf( "\n" ); 524817466cbSJens Wiklander 525817466cbSJens Wiklander return( 0 ); 5263d3b0591SJens Wiklander 5273d3b0591SJens Wiklander fail: 5283d3b0591SJens Wiklander if( verbose != 0 ) 5293d3b0591SJens Wiklander mbedtls_printf( "failed\n" ); 5303d3b0591SJens Wiklander 5313d3b0591SJens Wiklander return( ret ); 532817466cbSJens Wiklander } 533817466cbSJens Wiklander 534817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 535817466cbSJens Wiklander 536817466cbSJens Wiklander #endif /* MBEDTLS_RIPEMD160_C */ 537