mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ripemd160.c Source File

ripemd160.c

00001 /*
00002  *  RIPE MD-160 implementation
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 /*
00023  *  The RIPEMD-160 algorithm was designed by RIPE in 1996
00024  *  http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
00025  *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
00026  */
00027 
00028 #if !defined(MBEDTLS_CONFIG_FILE)
00029 #include "mbedtls/config.h"
00030 #else
00031 #include MBEDTLS_CONFIG_FILE
00032 #endif
00033 
00034 #if defined(MBEDTLS_RIPEMD160_C)
00035 
00036 #include "mbedtls/ripemd160.h"
00037 
00038 #include <string.h>
00039 
00040 #if defined(MBEDTLS_SELF_TEST)
00041 #if defined(MBEDTLS_PLATFORM_C)
00042 #include "mbedtls/platform.h"
00043 #else
00044 #include <stdio.h>
00045 #define mbedtls_printf printf
00046 #endif /* MBEDTLS_PLATFORM_C */
00047 #endif /* MBEDTLS_SELF_TEST */
00048 
00049 /*
00050  * 32-bit integer manipulation macros (little endian)
00051  */
00052 #ifndef GET_UINT32_LE
00053 #define GET_UINT32_LE(n,b,i)                            \
00054 {                                                       \
00055     (n) = ( (uint32_t) (b)[(i)    ]       )             \
00056         | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
00057         | ( (uint32_t) (b)[(i) + 2] << 16 )             \
00058         | ( (uint32_t) (b)[(i) + 3] << 24 );            \
00059 }
00060 #endif
00061 
00062 #ifndef PUT_UINT32_LE
00063 #define PUT_UINT32_LE(n,b,i)                                    \
00064 {                                                               \
00065     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
00066     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
00067     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
00068     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
00069 }
00070 #endif
00071 
00072 /* Implementation that should never be optimized out by the compiler */
00073 static void mbedtls_zeroize( void *v, size_t n ) {
00074     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00075 }
00076 
00077 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
00078 {
00079     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
00080 }
00081 
00082 void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
00083 {
00084     if( ctx == NULL )
00085         return;
00086 
00087     mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
00088 }
00089 
00090 void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
00091                         const mbedtls_ripemd160_context *src )
00092 {
00093     *dst = *src;
00094 }
00095 
00096 /*
00097  * RIPEMD-160 context setup
00098  */
00099 void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
00100 {
00101     ctx->total [0] = 0;
00102     ctx->total [1] = 0;
00103 
00104     ctx->state [0] = 0x67452301;
00105     ctx->state [1] = 0xEFCDAB89;
00106     ctx->state [2] = 0x98BADCFE;
00107     ctx->state [3] = 0x10325476;
00108     ctx->state [4] = 0xC3D2E1F0;
00109 }
00110 
00111 #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
00112 /*
00113  * Process one block
00114  */
00115 void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] )
00116 {
00117     uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
00118 
00119     GET_UINT32_LE( X[ 0], data,  0 );
00120     GET_UINT32_LE( X[ 1], data,  4 );
00121     GET_UINT32_LE( X[ 2], data,  8 );
00122     GET_UINT32_LE( X[ 3], data, 12 );
00123     GET_UINT32_LE( X[ 4], data, 16 );
00124     GET_UINT32_LE( X[ 5], data, 20 );
00125     GET_UINT32_LE( X[ 6], data, 24 );
00126     GET_UINT32_LE( X[ 7], data, 28 );
00127     GET_UINT32_LE( X[ 8], data, 32 );
00128     GET_UINT32_LE( X[ 9], data, 36 );
00129     GET_UINT32_LE( X[10], data, 40 );
00130     GET_UINT32_LE( X[11], data, 44 );
00131     GET_UINT32_LE( X[12], data, 48 );
00132     GET_UINT32_LE( X[13], data, 52 );
00133     GET_UINT32_LE( X[14], data, 56 );
00134     GET_UINT32_LE( X[15], data, 60 );
00135 
00136     A = Ap = ctx->state [0];
00137     B = Bp = ctx->state [1];
00138     C = Cp = ctx->state [2];
00139     D = Dp = ctx->state [3];
00140     E = Ep = ctx->state [4];
00141 
00142 #define F1( x, y, z )   ( x ^ y ^ z )
00143 #define F2( x, y, z )   ( ( x & y ) | ( ~x & z ) )
00144 #define F3( x, y, z )   ( ( x | ~y ) ^ z )
00145 #define F4( x, y, z )   ( ( x & z ) | ( y & ~z ) )
00146 #define F5( x, y, z )   ( x ^ ( y | ~z ) )
00147 
00148 #define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
00149 
00150 #define P( a, b, c, d, e, r, s, f, k )      \
00151     a += f( b, c, d ) + X[r] + k;           \
00152     a = S( a, s ) + e;                      \
00153     c = S( c, 10 );
00154 
00155 #define P2( a, b, c, d, e, r, s, rp, sp )   \
00156     P( a, b, c, d, e, r, s, F, K );         \
00157     P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
00158 
00159 #define F   F1
00160 #define K   0x00000000
00161 #define Fp  F5
00162 #define Kp  0x50A28BE6
00163     P2( A, B, C, D, E,  0, 11,  5,  8 );
00164     P2( E, A, B, C, D,  1, 14, 14,  9 );
00165     P2( D, E, A, B, C,  2, 15,  7,  9 );
00166     P2( C, D, E, A, B,  3, 12,  0, 11 );
00167     P2( B, C, D, E, A,  4,  5,  9, 13 );
00168     P2( A, B, C, D, E,  5,  8,  2, 15 );
00169     P2( E, A, B, C, D,  6,  7, 11, 15 );
00170     P2( D, E, A, B, C,  7,  9,  4,  5 );
00171     P2( C, D, E, A, B,  8, 11, 13,  7 );
00172     P2( B, C, D, E, A,  9, 13,  6,  7 );
00173     P2( A, B, C, D, E, 10, 14, 15,  8 );
00174     P2( E, A, B, C, D, 11, 15,  8, 11 );
00175     P2( D, E, A, B, C, 12,  6,  1, 14 );
00176     P2( C, D, E, A, B, 13,  7, 10, 14 );
00177     P2( B, C, D, E, A, 14,  9,  3, 12 );
00178     P2( A, B, C, D, E, 15,  8, 12,  6 );
00179 #undef F
00180 #undef K
00181 #undef Fp
00182 #undef Kp
00183 
00184 #define F   F2
00185 #define K   0x5A827999
00186 #define Fp  F4
00187 #define Kp  0x5C4DD124
00188     P2( E, A, B, C, D,  7,  7,  6,  9 );
00189     P2( D, E, A, B, C,  4,  6, 11, 13 );
00190     P2( C, D, E, A, B, 13,  8,  3, 15 );
00191     P2( B, C, D, E, A,  1, 13,  7,  7 );
00192     P2( A, B, C, D, E, 10, 11,  0, 12 );
00193     P2( E, A, B, C, D,  6,  9, 13,  8 );
00194     P2( D, E, A, B, C, 15,  7,  5,  9 );
00195     P2( C, D, E, A, B,  3, 15, 10, 11 );
00196     P2( B, C, D, E, A, 12,  7, 14,  7 );
00197     P2( A, B, C, D, E,  0, 12, 15,  7 );
00198     P2( E, A, B, C, D,  9, 15,  8, 12 );
00199     P2( D, E, A, B, C,  5,  9, 12,  7 );
00200     P2( C, D, E, A, B,  2, 11,  4,  6 );
00201     P2( B, C, D, E, A, 14,  7,  9, 15 );
00202     P2( A, B, C, D, E, 11, 13,  1, 13 );
00203     P2( E, A, B, C, D,  8, 12,  2, 11 );
00204 #undef F
00205 #undef K
00206 #undef Fp
00207 #undef Kp
00208 
00209 #define F   F3
00210 #define K   0x6ED9EBA1
00211 #define Fp  F3
00212 #define Kp  0x6D703EF3
00213     P2( D, E, A, B, C,  3, 11, 15,  9 );
00214     P2( C, D, E, A, B, 10, 13,  5,  7 );
00215     P2( B, C, D, E, A, 14,  6,  1, 15 );
00216     P2( A, B, C, D, E,  4,  7,  3, 11 );
00217     P2( E, A, B, C, D,  9, 14,  7,  8 );
00218     P2( D, E, A, B, C, 15,  9, 14,  6 );
00219     P2( C, D, E, A, B,  8, 13,  6,  6 );
00220     P2( B, C, D, E, A,  1, 15,  9, 14 );
00221     P2( A, B, C, D, E,  2, 14, 11, 12 );
00222     P2( E, A, B, C, D,  7,  8,  8, 13 );
00223     P2( D, E, A, B, C,  0, 13, 12,  5 );
00224     P2( C, D, E, A, B,  6,  6,  2, 14 );
00225     P2( B, C, D, E, A, 13,  5, 10, 13 );
00226     P2( A, B, C, D, E, 11, 12,  0, 13 );
00227     P2( E, A, B, C, D,  5,  7,  4,  7 );
00228     P2( D, E, A, B, C, 12,  5, 13,  5 );
00229 #undef F
00230 #undef K
00231 #undef Fp
00232 #undef Kp
00233 
00234 #define F   F4
00235 #define K   0x8F1BBCDC
00236 #define Fp  F2
00237 #define Kp  0x7A6D76E9
00238     P2( C, D, E, A, B,  1, 11,  8, 15 );
00239     P2( B, C, D, E, A,  9, 12,  6,  5 );
00240     P2( A, B, C, D, E, 11, 14,  4,  8 );
00241     P2( E, A, B, C, D, 10, 15,  1, 11 );
00242     P2( D, E, A, B, C,  0, 14,  3, 14 );
00243     P2( C, D, E, A, B,  8, 15, 11, 14 );
00244     P2( B, C, D, E, A, 12,  9, 15,  6 );
00245     P2( A, B, C, D, E,  4,  8,  0, 14 );
00246     P2( E, A, B, C, D, 13,  9,  5,  6 );
00247     P2( D, E, A, B, C,  3, 14, 12,  9 );
00248     P2( C, D, E, A, B,  7,  5,  2, 12 );
00249     P2( B, C, D, E, A, 15,  6, 13,  9 );
00250     P2( A, B, C, D, E, 14,  8,  9, 12 );
00251     P2( E, A, B, C, D,  5,  6,  7,  5 );
00252     P2( D, E, A, B, C,  6,  5, 10, 15 );
00253     P2( C, D, E, A, B,  2, 12, 14,  8 );
00254 #undef F
00255 #undef K
00256 #undef Fp
00257 #undef Kp
00258 
00259 #define F   F5
00260 #define K   0xA953FD4E
00261 #define Fp  F1
00262 #define Kp  0x00000000
00263     P2( B, C, D, E, A,  4,  9, 12,  8 );
00264     P2( A, B, C, D, E,  0, 15, 15,  5 );
00265     P2( E, A, B, C, D,  5,  5, 10, 12 );
00266     P2( D, E, A, B, C,  9, 11,  4,  9 );
00267     P2( C, D, E, A, B,  7,  6,  1, 12 );
00268     P2( B, C, D, E, A, 12,  8,  5,  5 );
00269     P2( A, B, C, D, E,  2, 13,  8, 14 );
00270     P2( E, A, B, C, D, 10, 12,  7,  6 );
00271     P2( D, E, A, B, C, 14,  5,  6,  8 );
00272     P2( C, D, E, A, B,  1, 12,  2, 13 );
00273     P2( B, C, D, E, A,  3, 13, 13,  6 );
00274     P2( A, B, C, D, E,  8, 14, 14,  5 );
00275     P2( E, A, B, C, D, 11, 11,  0, 15 );
00276     P2( D, E, A, B, C,  6,  8,  3, 13 );
00277     P2( C, D, E, A, B, 15,  5,  9, 11 );
00278     P2( B, C, D, E, A, 13,  6, 11, 11 );
00279 #undef F
00280 #undef K
00281 #undef Fp
00282 #undef Kp
00283 
00284     C             = ctx->state [1] + C + Dp;
00285     ctx->state [1] = ctx->state [2] + D + Ep;
00286     ctx->state [2] = ctx->state [3] + E + Ap;
00287     ctx->state [3] = ctx->state [4] + A + Bp;
00288     ctx->state [4] = ctx->state [0] + B + Cp;
00289     ctx->state [0] = C;
00290 }
00291 #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
00292 
00293 /*
00294  * RIPEMD-160 process buffer
00295  */
00296 void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
00297                        const unsigned char *input, size_t ilen )
00298 {
00299     size_t fill;
00300     uint32_t left;
00301 
00302     if( ilen == 0 )
00303         return;
00304 
00305     left = ctx->total [0] & 0x3F;
00306     fill = 64 - left;
00307 
00308     ctx->total [0] += (uint32_t) ilen;
00309     ctx->total [0] &= 0xFFFFFFFF;
00310 
00311     if( ctx->total [0] < (uint32_t) ilen )
00312         ctx->total [1]++;
00313 
00314     if( left && ilen >= fill )
00315     {
00316         memcpy( (void *) (ctx->buffer  + left), input, fill );
00317         mbedtls_ripemd160_process( ctx, ctx->buffer  );
00318         input += fill;
00319         ilen  -= fill;
00320         left = 0;
00321     }
00322 
00323     while( ilen >= 64 )
00324     {
00325         mbedtls_ripemd160_process( ctx, input );
00326         input += 64;
00327         ilen  -= 64;
00328     }
00329 
00330     if( ilen > 0 )
00331     {
00332         memcpy( (void *) (ctx->buffer  + left), input, ilen );
00333     }
00334 }
00335 
00336 static const unsigned char ripemd160_padding[64] =
00337 {
00338  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00339     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00340     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00341     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00342 };
00343 
00344 /*
00345  * RIPEMD-160 final digest
00346  */
00347 void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] )
00348 {
00349     uint32_t last, padn;
00350     uint32_t high, low;
00351     unsigned char msglen[8];
00352 
00353     high = ( ctx->total [0] >> 29 )
00354          | ( ctx->total [1] <<  3 );
00355     low  = ( ctx->total [0] <<  3 );
00356 
00357     PUT_UINT32_LE( low,  msglen, 0 );
00358     PUT_UINT32_LE( high, msglen, 4 );
00359 
00360     last = ctx->total [0] & 0x3F;
00361     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00362 
00363     mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
00364     mbedtls_ripemd160_update( ctx, msglen, 8 );
00365 
00366     PUT_UINT32_LE( ctx->state [0], output,  0 );
00367     PUT_UINT32_LE( ctx->state [1], output,  4 );
00368     PUT_UINT32_LE( ctx->state [2], output,  8 );
00369     PUT_UINT32_LE( ctx->state [3], output, 12 );
00370     PUT_UINT32_LE( ctx->state [4], output, 16 );
00371 }
00372 
00373 /*
00374  * output = RIPEMD-160( input buffer )
00375  */
00376 void mbedtls_ripemd160( const unsigned char *input, size_t ilen,
00377                 unsigned char output[20] )
00378 {
00379     mbedtls_ripemd160_context ctx;
00380 
00381     mbedtls_ripemd160_init( &ctx );
00382     mbedtls_ripemd160_starts( &ctx );
00383     mbedtls_ripemd160_update( &ctx, input, ilen );
00384     mbedtls_ripemd160_finish( &ctx, output );
00385     mbedtls_ripemd160_free( &ctx );
00386 }
00387 
00388 #if defined(MBEDTLS_SELF_TEST)
00389 /*
00390  * Test vectors from the RIPEMD-160 paper and
00391  * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
00392  */
00393 #define TESTS   8
00394 #define KEYS    2
00395 static const char *ripemd160_test_input[TESTS] =
00396 {
00397     "",
00398     "a",
00399     "abc",
00400     "message digest",
00401     "abcdefghijklmnopqrstuvwxyz",
00402     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
00403     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
00404     "1234567890123456789012345678901234567890"
00405         "1234567890123456789012345678901234567890",
00406 };
00407 
00408 static const unsigned char ripemd160_test_md[TESTS][20] =
00409 {
00410     { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
00411       0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
00412     { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
00413       0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
00414     { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
00415       0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
00416     { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
00417       0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
00418     { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
00419       0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
00420     { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
00421       0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
00422     { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
00423       0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
00424     { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
00425       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
00426 };
00427 
00428 /*
00429  * Checkup routine
00430  */
00431 int mbedtls_ripemd160_self_test( int verbose )
00432 {
00433     int i;
00434     unsigned char output[20];
00435 
00436     memset( output, 0, sizeof output );
00437 
00438     for( i = 0; i < TESTS; i++ )
00439     {
00440         if( verbose != 0 )
00441             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
00442 
00443         mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i],
00444                    strlen( ripemd160_test_input[i] ),
00445                    output );
00446 
00447         if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
00448         {
00449             if( verbose != 0 )
00450                 mbedtls_printf( "failed\n" );
00451 
00452             return( 1 );
00453         }
00454 
00455         if( verbose != 0 )
00456             mbedtls_printf( "passed\n" );
00457     }
00458 
00459     return( 0 );
00460 }
00461 
00462 #endif /* MBEDTLS_SELF_TEST */
00463 
00464 #endif /* MBEDTLS_RIPEMD160_C */