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 #include "mbedtls/platform.h" 37817466cbSJens Wiklander 383d3b0591SJens Wiklander #if !defined(MBEDTLS_RIPEMD160_ALT) 393d3b0591SJens Wiklander 40817466cbSJens Wiklander void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx) 41817466cbSJens Wiklander { 42817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_ripemd160_context)); 43817466cbSJens Wiklander } 44817466cbSJens Wiklander 45817466cbSJens Wiklander void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx) 46817466cbSJens Wiklander { 47*32b31808SJens Wiklander if (ctx == NULL) { 48817466cbSJens Wiklander return; 49*32b31808SJens Wiklander } 50817466cbSJens Wiklander 513d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context)); 52817466cbSJens Wiklander } 53817466cbSJens Wiklander 54817466cbSJens Wiklander void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst, 55817466cbSJens Wiklander const mbedtls_ripemd160_context *src) 56817466cbSJens Wiklander { 57817466cbSJens Wiklander *dst = *src; 58817466cbSJens Wiklander } 59817466cbSJens Wiklander 60817466cbSJens Wiklander /* 61817466cbSJens Wiklander * RIPEMD-160 context setup 62817466cbSJens Wiklander */ 63*32b31808SJens Wiklander int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx) 64817466cbSJens Wiklander { 65817466cbSJens Wiklander ctx->total[0] = 0; 66817466cbSJens Wiklander ctx->total[1] = 0; 67817466cbSJens Wiklander 68817466cbSJens Wiklander ctx->state[0] = 0x67452301; 69817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89; 70817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE; 71817466cbSJens Wiklander ctx->state[3] = 0x10325476; 72817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0; 733d3b0591SJens Wiklander 74*32b31808SJens Wiklander return 0; 75817466cbSJens Wiklander } 76817466cbSJens Wiklander 77817466cbSJens Wiklander #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) 78817466cbSJens Wiklander /* 79817466cbSJens Wiklander * Process one block 80817466cbSJens Wiklander */ 813d3b0591SJens Wiklander int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx, 823d3b0591SJens Wiklander const unsigned char data[64]) 83817466cbSJens Wiklander { 84*32b31808SJens Wiklander struct { 85817466cbSJens Wiklander uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; 867901324dSJerome Forissier } local; 87817466cbSJens Wiklander 88039e02dfSJerome Forissier local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0); 89039e02dfSJerome Forissier local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4); 90039e02dfSJerome Forissier local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8); 91039e02dfSJerome Forissier local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12); 92039e02dfSJerome Forissier local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16); 93039e02dfSJerome Forissier local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20); 94039e02dfSJerome Forissier local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24); 95039e02dfSJerome Forissier local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28); 96039e02dfSJerome Forissier local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32); 97039e02dfSJerome Forissier local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36); 98039e02dfSJerome Forissier local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40); 99039e02dfSJerome Forissier local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44); 100039e02dfSJerome Forissier local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48); 101039e02dfSJerome Forissier local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52); 102039e02dfSJerome Forissier local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56); 103039e02dfSJerome Forissier local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60); 104817466cbSJens Wiklander 1057901324dSJerome Forissier local.A = local.Ap = ctx->state[0]; 1067901324dSJerome Forissier local.B = local.Bp = ctx->state[1]; 1077901324dSJerome Forissier local.C = local.Cp = ctx->state[2]; 1087901324dSJerome Forissier local.D = local.Dp = ctx->state[3]; 1097901324dSJerome Forissier local.E = local.Ep = ctx->state[4]; 110817466cbSJens Wiklander 1115b25c76aSJerome Forissier #define F1(x, y, z) ((x) ^ (y) ^ (z)) 1125b25c76aSJerome Forissier #define F2(x, y, z) (((x) & (y)) | (~(x) & (z))) 1135b25c76aSJerome Forissier #define F3(x, y, z) (((x) | ~(y)) ^ (z)) 1145b25c76aSJerome Forissier #define F4(x, y, z) (((x) & (z)) | ((y) & ~(z))) 1155b25c76aSJerome Forissier #define F5(x, y, z) ((x) ^ ((y) | ~(z))) 116817466cbSJens Wiklander 1175b25c76aSJerome Forissier #define S(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 118817466cbSJens Wiklander 119817466cbSJens Wiklander #define P(a, b, c, d, e, r, s, f, k) \ 1205b25c76aSJerome Forissier do \ 1215b25c76aSJerome Forissier { \ 1227901324dSJerome Forissier (a) += f((b), (c), (d)) + local.X[r] + (k); \ 1235b25c76aSJerome Forissier (a) = S((a), (s)) + (e); \ 1245b25c76aSJerome Forissier (c) = S((c), 10); \ 1255b25c76aSJerome Forissier } while (0) 126817466cbSJens Wiklander 127817466cbSJens Wiklander #define P2(a, b, c, d, e, r, s, rp, sp) \ 1285b25c76aSJerome Forissier do \ 1295b25c76aSJerome Forissier { \ 1305b25c76aSJerome Forissier P((a), (b), (c), (d), (e), (r), (s), F, K); \ 1315b25c76aSJerome Forissier P(a ## p, b ## p, c ## p, d ## p, e ## p, \ 1325b25c76aSJerome Forissier (rp), (sp), Fp, Kp); \ 1335b25c76aSJerome Forissier } while (0) 134817466cbSJens Wiklander 135817466cbSJens Wiklander #define F F1 136817466cbSJens Wiklander #define K 0x00000000 137817466cbSJens Wiklander #define Fp F5 138817466cbSJens Wiklander #define Kp 0x50A28BE6 1397901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8); 1407901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9); 1417901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9); 1427901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11); 1437901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13); 1447901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15); 1457901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15); 1467901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5); 1477901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7); 1487901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7); 1497901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8); 1507901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11); 1517901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14); 1527901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14); 1537901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12); 1547901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6); 155817466cbSJens Wiklander #undef F 156817466cbSJens Wiklander #undef K 157817466cbSJens Wiklander #undef Fp 158817466cbSJens Wiklander #undef Kp 159817466cbSJens Wiklander 160817466cbSJens Wiklander #define F F2 161817466cbSJens Wiklander #define K 0x5A827999 162817466cbSJens Wiklander #define Fp F4 163817466cbSJens Wiklander #define Kp 0x5C4DD124 1647901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9); 1657901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13); 1667901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15); 1677901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7); 1687901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12); 1697901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8); 1707901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9); 1717901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11); 1727901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7); 1737901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7); 1747901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12); 1757901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7); 1767901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6); 1777901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15); 1787901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13); 1797901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11); 180817466cbSJens Wiklander #undef F 181817466cbSJens Wiklander #undef K 182817466cbSJens Wiklander #undef Fp 183817466cbSJens Wiklander #undef Kp 184817466cbSJens Wiklander 185817466cbSJens Wiklander #define F F3 186817466cbSJens Wiklander #define K 0x6ED9EBA1 187817466cbSJens Wiklander #define Fp F3 188817466cbSJens Wiklander #define Kp 0x6D703EF3 1897901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9); 1907901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7); 1917901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15); 1927901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11); 1937901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8); 1947901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6); 1957901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6); 1967901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14); 1977901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12); 1987901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13); 1997901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5); 2007901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14); 2017901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13); 2027901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13); 2037901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7); 2047901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5); 205817466cbSJens Wiklander #undef F 206817466cbSJens Wiklander #undef K 207817466cbSJens Wiklander #undef Fp 208817466cbSJens Wiklander #undef Kp 209817466cbSJens Wiklander 210817466cbSJens Wiklander #define F F4 211817466cbSJens Wiklander #define K 0x8F1BBCDC 212817466cbSJens Wiklander #define Fp F2 213817466cbSJens Wiklander #define Kp 0x7A6D76E9 2147901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15); 2157901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5); 2167901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8); 2177901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11); 2187901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14); 2197901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14); 2207901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6); 2217901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14); 2227901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6); 2237901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9); 2247901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12); 2257901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9); 2267901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12); 2277901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5); 2287901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15); 2297901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8); 230817466cbSJens Wiklander #undef F 231817466cbSJens Wiklander #undef K 232817466cbSJens Wiklander #undef Fp 233817466cbSJens Wiklander #undef Kp 234817466cbSJens Wiklander 235817466cbSJens Wiklander #define F F5 236817466cbSJens Wiklander #define K 0xA953FD4E 237817466cbSJens Wiklander #define Fp F1 238817466cbSJens Wiklander #define Kp 0x00000000 2397901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8); 2407901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5); 2417901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12); 2427901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9); 2437901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12); 2447901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5); 2457901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14); 2467901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6); 2477901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8); 2487901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13); 2497901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6); 2507901324dSJerome Forissier P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5); 2517901324dSJerome Forissier P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15); 2527901324dSJerome Forissier P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13); 2537901324dSJerome Forissier P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11); 2547901324dSJerome Forissier P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11); 255817466cbSJens Wiklander #undef F 256817466cbSJens Wiklander #undef K 257817466cbSJens Wiklander #undef Fp 258817466cbSJens Wiklander #undef Kp 259817466cbSJens Wiklander 2607901324dSJerome Forissier local.C = ctx->state[1] + local.C + local.Dp; 2617901324dSJerome Forissier ctx->state[1] = ctx->state[2] + local.D + local.Ep; 2627901324dSJerome Forissier ctx->state[2] = ctx->state[3] + local.E + local.Ap; 2637901324dSJerome Forissier ctx->state[3] = ctx->state[4] + local.A + local.Bp; 2647901324dSJerome Forissier ctx->state[4] = ctx->state[0] + local.B + local.Cp; 2657901324dSJerome Forissier ctx->state[0] = local.C; 2667901324dSJerome Forissier 2677901324dSJerome Forissier /* Zeroise variables to clear sensitive data from memory. */ 2687901324dSJerome Forissier mbedtls_platform_zeroize(&local, sizeof(local)); 2693d3b0591SJens Wiklander 270*32b31808SJens Wiklander return 0; 271817466cbSJens Wiklander } 2723d3b0591SJens Wiklander 273817466cbSJens Wiklander #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ 274817466cbSJens Wiklander 275817466cbSJens Wiklander /* 276817466cbSJens Wiklander * RIPEMD-160 process buffer 277817466cbSJens Wiklander */ 278*32b31808SJens Wiklander int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, 2793d3b0591SJens Wiklander const unsigned char *input, 2803d3b0591SJens Wiklander size_t ilen) 281817466cbSJens Wiklander { 28211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 283817466cbSJens Wiklander size_t fill; 284817466cbSJens Wiklander uint32_t left; 285817466cbSJens Wiklander 286*32b31808SJens Wiklander if (ilen == 0) { 287*32b31808SJens Wiklander return 0; 288*32b31808SJens Wiklander } 289817466cbSJens Wiklander 290817466cbSJens Wiklander left = ctx->total[0] & 0x3F; 291817466cbSJens Wiklander fill = 64 - left; 292817466cbSJens Wiklander 293817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen; 294817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF; 295817466cbSJens Wiklander 296*32b31808SJens Wiklander if (ctx->total[0] < (uint32_t) ilen) { 297817466cbSJens Wiklander ctx->total[1]++; 298*32b31808SJens Wiklander } 299817466cbSJens Wiklander 300*32b31808SJens Wiklander if (left && ilen >= fill) { 301817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, fill); 3023d3b0591SJens Wiklander 303*32b31808SJens Wiklander if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) { 304*32b31808SJens Wiklander return ret; 305*32b31808SJens Wiklander } 3063d3b0591SJens Wiklander 307817466cbSJens Wiklander input += fill; 308817466cbSJens Wiklander ilen -= fill; 309817466cbSJens Wiklander left = 0; 310817466cbSJens Wiklander } 311817466cbSJens Wiklander 312*32b31808SJens Wiklander while (ilen >= 64) { 313*32b31808SJens Wiklander if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) { 314*32b31808SJens Wiklander return ret; 315*32b31808SJens Wiklander } 3163d3b0591SJens Wiklander 317817466cbSJens Wiklander input += 64; 318817466cbSJens Wiklander ilen -= 64; 319817466cbSJens Wiklander } 320817466cbSJens Wiklander 321*32b31808SJens Wiklander if (ilen > 0) { 322817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, ilen); 323817466cbSJens Wiklander } 3243d3b0591SJens Wiklander 325*32b31808SJens Wiklander return 0; 326817466cbSJens Wiklander } 327817466cbSJens Wiklander 328817466cbSJens Wiklander static const unsigned char ripemd160_padding[64] = 329817466cbSJens Wiklander { 330817466cbSJens Wiklander 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333817466cbSJens Wiklander 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 334817466cbSJens Wiklander }; 335817466cbSJens Wiklander 336817466cbSJens Wiklander /* 337817466cbSJens Wiklander * RIPEMD-160 final digest 338817466cbSJens Wiklander */ 339*32b31808SJens Wiklander int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx, 3403d3b0591SJens Wiklander unsigned char output[20]) 341817466cbSJens Wiklander { 34211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 343817466cbSJens Wiklander uint32_t last, padn; 344817466cbSJens Wiklander uint32_t high, low; 345817466cbSJens Wiklander unsigned char msglen[8]; 346817466cbSJens Wiklander 347817466cbSJens Wiklander high = (ctx->total[0] >> 29) 348817466cbSJens Wiklander | (ctx->total[1] << 3); 349817466cbSJens Wiklander low = (ctx->total[0] << 3); 350817466cbSJens Wiklander 351039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(low, msglen, 0); 352039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(high, msglen, 4); 353817466cbSJens Wiklander 354817466cbSJens Wiklander last = ctx->total[0] & 0x3F; 355817466cbSJens Wiklander padn = (last < 56) ? (56 - last) : (120 - last); 356817466cbSJens Wiklander 357*32b31808SJens Wiklander ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn); 358*32b31808SJens Wiklander if (ret != 0) { 359*32b31808SJens Wiklander return ret; 360*32b31808SJens Wiklander } 3613d3b0591SJens Wiklander 362*32b31808SJens Wiklander ret = mbedtls_ripemd160_update(ctx, msglen, 8); 363*32b31808SJens Wiklander if (ret != 0) { 364*32b31808SJens Wiklander return ret; 365*32b31808SJens Wiklander } 366817466cbSJens Wiklander 367039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0); 368039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4); 369039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8); 370039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12); 371039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16); 3723d3b0591SJens Wiklander 373*32b31808SJens Wiklander return 0; 374817466cbSJens Wiklander } 375817466cbSJens Wiklander 3763d3b0591SJens Wiklander #endif /* ! MBEDTLS_RIPEMD160_ALT */ 3773d3b0591SJens Wiklander 378817466cbSJens Wiklander /* 379817466cbSJens Wiklander * output = RIPEMD-160( input buffer ) 380817466cbSJens Wiklander */ 381*32b31808SJens Wiklander int mbedtls_ripemd160(const unsigned char *input, 3823d3b0591SJens Wiklander size_t ilen, 383817466cbSJens Wiklander unsigned char output[20]) 384817466cbSJens Wiklander { 38511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 386817466cbSJens Wiklander mbedtls_ripemd160_context ctx; 387817466cbSJens Wiklander 388817466cbSJens Wiklander mbedtls_ripemd160_init(&ctx); 3893d3b0591SJens Wiklander 390*32b31808SJens Wiklander if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) { 3913d3b0591SJens Wiklander goto exit; 392*32b31808SJens Wiklander } 3933d3b0591SJens Wiklander 394*32b31808SJens Wiklander if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) { 3953d3b0591SJens Wiklander goto exit; 396*32b31808SJens Wiklander } 3973d3b0591SJens Wiklander 398*32b31808SJens Wiklander if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) { 3993d3b0591SJens Wiklander goto exit; 400*32b31808SJens Wiklander } 4013d3b0591SJens Wiklander 4023d3b0591SJens Wiklander exit: 403817466cbSJens Wiklander mbedtls_ripemd160_free(&ctx); 4043d3b0591SJens Wiklander 405*32b31808SJens Wiklander return ret; 406817466cbSJens Wiklander } 407817466cbSJens Wiklander 408817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 409817466cbSJens Wiklander /* 410817466cbSJens Wiklander * Test vectors from the RIPEMD-160 paper and 411817466cbSJens Wiklander * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC 412817466cbSJens Wiklander */ 413817466cbSJens Wiklander #define TESTS 8 4143d3b0591SJens Wiklander static const unsigned char ripemd160_test_str[TESTS][81] = 415817466cbSJens Wiklander { 4163d3b0591SJens Wiklander { "" }, 4173d3b0591SJens Wiklander { "a" }, 4183d3b0591SJens Wiklander { "abc" }, 4193d3b0591SJens Wiklander { "message digest" }, 4203d3b0591SJens Wiklander { "abcdefghijklmnopqrstuvwxyz" }, 4213d3b0591SJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 4223d3b0591SJens Wiklander { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 42336905f94SGuido Vranken { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, 4243d3b0591SJens Wiklander }; 4253d3b0591SJens Wiklander 4263d3b0591SJens Wiklander static const size_t ripemd160_test_strlen[TESTS] = 4273d3b0591SJens Wiklander { 4283d3b0591SJens Wiklander 0, 1, 3, 14, 26, 56, 62, 80 429817466cbSJens Wiklander }; 430817466cbSJens Wiklander 431817466cbSJens Wiklander static const unsigned char ripemd160_test_md[TESTS][20] = 432817466cbSJens Wiklander { 433817466cbSJens Wiklander { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, 434817466cbSJens Wiklander 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, 435817466cbSJens Wiklander { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, 436817466cbSJens Wiklander 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, 437817466cbSJens Wiklander { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, 438817466cbSJens Wiklander 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, 439817466cbSJens Wiklander { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, 440817466cbSJens Wiklander 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, 441817466cbSJens Wiklander { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, 442817466cbSJens Wiklander 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, 443817466cbSJens Wiklander { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, 444817466cbSJens Wiklander 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, 445817466cbSJens Wiklander { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, 446817466cbSJens Wiklander 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, 447817466cbSJens Wiklander { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, 448817466cbSJens Wiklander 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, 449817466cbSJens Wiklander }; 450817466cbSJens Wiklander 451817466cbSJens Wiklander /* 452817466cbSJens Wiklander * Checkup routine 453817466cbSJens Wiklander */ 454817466cbSJens Wiklander int mbedtls_ripemd160_self_test(int verbose) 455817466cbSJens Wiklander { 4563d3b0591SJens Wiklander int i, ret = 0; 457817466cbSJens Wiklander unsigned char output[20]; 458817466cbSJens Wiklander 459*32b31808SJens Wiklander memset(output, 0, sizeof(output)); 460817466cbSJens Wiklander 461*32b31808SJens Wiklander for (i = 0; i < TESTS; i++) { 462*32b31808SJens Wiklander if (verbose != 0) { 463817466cbSJens Wiklander mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1); 464*32b31808SJens Wiklander } 465817466cbSJens Wiklander 466*32b31808SJens Wiklander ret = mbedtls_ripemd160(ripemd160_test_str[i], 4673d3b0591SJens Wiklander ripemd160_test_strlen[i], output); 468*32b31808SJens Wiklander if (ret != 0) { 4693d3b0591SJens Wiklander goto fail; 470*32b31808SJens Wiklander } 471817466cbSJens Wiklander 472*32b31808SJens Wiklander if (memcmp(output, ripemd160_test_md[i], 20) != 0) { 4733d3b0591SJens Wiklander ret = 1; 4743d3b0591SJens Wiklander goto fail; 475817466cbSJens Wiklander } 476817466cbSJens Wiklander 477*32b31808SJens Wiklander if (verbose != 0) { 478817466cbSJens Wiklander mbedtls_printf("passed\n"); 479817466cbSJens Wiklander } 480*32b31808SJens Wiklander } 481817466cbSJens Wiklander 482*32b31808SJens Wiklander if (verbose != 0) { 483817466cbSJens Wiklander mbedtls_printf("\n"); 484*32b31808SJens Wiklander } 485817466cbSJens Wiklander 486*32b31808SJens Wiklander return 0; 4873d3b0591SJens Wiklander 4883d3b0591SJens Wiklander fail: 489*32b31808SJens Wiklander if (verbose != 0) { 4903d3b0591SJens Wiklander mbedtls_printf("failed\n"); 491*32b31808SJens Wiklander } 4923d3b0591SJens Wiklander 493*32b31808SJens Wiklander return ret; 494817466cbSJens Wiklander } 495817466cbSJens Wiklander 496817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 497817466cbSJens Wiklander 498817466cbSJens Wiklander #endif /* MBEDTLS_RIPEMD160_C */ 499