diff --git a/include/polarssl/config.h b/include/polarssl/config.h index ca0c1763f..56e6f393e 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -1558,6 +1558,17 @@ */ #define POLARSSL_PKCS12_C +/** + * \def POLARSSL_RMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/rmd160.c + * Caller: library/md.c + * + */ +#define POLARSSL_RMD160_C + /** * \def POLARSSL_RSA_C * diff --git a/include/polarssl/rmd160.h b/include/polarssl/rmd160.h new file mode 100644 index 000000000..5d6c6b7e9 --- /dev/null +++ b/include/polarssl/rmd160.h @@ -0,0 +1,117 @@ +/** + * \file rdm160.h + * + * \brief RIPE MD-160 message digest + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_RMD160_H +#define POLARSSL_RMD160_H + +#include "config.h" + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_RMD160_FILE_IO_ERROR -0x0074 /**< Read/write error in file. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief RMD160 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +rmd160_context; + +/** + * \brief RMD160 context setup + * + * \param ctx context to be initialized + */ +void rmd160_starts( rmd160_context *ctx ); + +/** + * \brief RMD160 process buffer + * + * \param ctx RMD160 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void rmd160_update( rmd160_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief RMD160 final digest + * + * \param ctx RMD160 context + * \param output RMD160 checksum result + */ +void rmd160_finish( rmd160_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = RMD160( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output RMD160 checksum result + */ +void rmd160( const unsigned char *input, size_t ilen, + unsigned char output[16] ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Output = RMD160( file contents ) + * + * \param path input file name + * \param output RMD160 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_RMD160_FILE_IO_ERROR + */ +int rmd160_file( const char *path, unsigned char output[16] ); +#endif /* POLARSSL_FS_IO */ + + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int rmd160_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* rmd160.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index fc62c3d2d..f967bf6c0 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -45,6 +45,7 @@ set(src pk_wrap.c pkparse.c pkwrite.c + rmd160.c rsa.c sha1.c sha256.c diff --git a/library/Makefile b/library/Makefile index 3f80162b5..99655853e 100644 --- a/library/Makefile +++ b/library/Makefile @@ -51,7 +51,7 @@ OBJS= aes.o aesni.o arc4.o \ padlock.o pbkdf2.o pem.o \ pkcs5.o pkcs11.o pkcs12.o \ pk.o pk_wrap.o pkparse.o \ - pkwrite.o \ + pkwrite.o rmd160.o \ rsa.o sha1.o sha256.o \ sha512.o ssl_cache.o ssl_cli.o \ ssl_srv.o ssl_ciphersuites.o \ diff --git a/library/rmd160.c b/library/rmd160.c new file mode 100644 index 000000000..cdf85dbd2 --- /dev/null +++ b/library/rmd160.c @@ -0,0 +1,466 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_RMD160_C) + +#include "polarssl/rmd160.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_SELF_TEST) +#include +#endif + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * RMD160 context setup + */ +void rmd160_starts( rmd160_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void rmd160_process( rmd160_context *ctx, const unsigned char data[64] ) +{ + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + ctx->state[0] = C; +} + +/* + * RMD160 process buffer + */ +void rmd160_update( rmd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + rmd160_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + rmd160_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char rmd160_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * RMD160 final digest + */ +void rmd160_finish( rmd160_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + rmd160_update( ctx, rmd160_padding, padn ); + rmd160_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); +} + +/* + * output = RMD160( input buffer ) + */ +void rmd160( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + rmd160_context ctx; + + rmd160_starts( &ctx ); + rmd160_update( &ctx, input, ilen ); + rmd160_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( rmd160_context ) ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = RMD160( file contents ) + */ +int rmd160_file( const char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + rmd160_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_RMD160_FILE_IO_ERROR ); + + rmd160_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + rmd160_update( &ctx, buf, n ); + + rmd160_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( rmd160_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_RMD160_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) +/* + * Test vectors from the RIPEMD-160 paper + */ +#define MD_TESTS 8 +static const char *rmd160_test_input[MD_TESTS] = +{ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", +}; + +static const unsigned char rmd160_test_output[MD_TESTS][20] = +{ + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, + { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, + 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, + { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, + 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, +}; + +/* + * Checkup routine + */ +int rmd160_self_test( int verbose ) +{ + int i; + unsigned char output[20]; + + memset( output, 0, sizeof output ); + + for( i = 0; i < MD_TESTS; i++ ) + { + if( verbose != 0 ) + printf( " RMD160 test #%d: ", i + 1 ); + + rmd160( (const unsigned char *)rmd160_test_input[i], + strlen( rmd160_test_input[i] ), + output ); + + if( memcmp( output, rmd160_test_output[i], 20 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/tests/suites/test_suite_mdx.data b/tests/suites/test_suite_mdx.data index 8ad609eb4..0e2114e08 100644 --- a/tests/suites/test_suite_mdx.data +++ b/tests/suites/test_suite_mdx.data @@ -82,6 +82,30 @@ md5 Test vector RFC1321 #7 depends_on:POLARSSL_MD5_C md5_text:"12345678901234567890123456789012345678901234567890123456789012345678901234567890":"57edf4a22be3c955ac49da2e2107b67a" +rmd160 Test vector from paper #1 +rmd160_text:"":"9c1185a5c5e9fc54612808977ee8f548b2258d31" + +rmd160 Test vector from paper #2 +rmd160_text:"a":"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" + +rmd160 Test vector from paper #3 +rmd160_text:"abc":"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" + +rmd160 Test vector from paper #4 +rmd160_text:"message digest":"5d0689ef49d2fae572b881b123a85ffa21595f36" + +rmd160 Test vector from paper #5 +rmd160_text:"abcdefghijklmnopqrstuvwxyz":"f71c27109c692c1b56bbdceb5b9d2865b3708dbc" + +rmd160 Test vector from paper #6 +rmd160_text:"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq":"12a053384a9c0c88e405a06c27dcf49ada62eb2b" + +rmd160 Test vector from paper #7 +rmd160_text:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789":"b0e20b6e3116640286ed3a87a5713079b21f5189" + +rmd160 Test vector from paper #8 +rmd160_text:"12345678901234567890123456789012345678901234567890123456789012345678901234567890":"9b752e45573d4b39f4dbd3323cab82bf63326bfb" + HMAC-MD2 Hash File OpenSSL test #1 depends_on:POLARSSL_MD2_C md2_hmac:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"d5732582f494f5ddf35efd166c85af9c" @@ -206,6 +230,21 @@ MD5 Hash file #4 depends_on:POLARSSL_MD5_C md5_file:"data_files/hash_file_4":"d41d8cd98f00b204e9800998ecf8427e" +RMD160 Hash file #0 (from paper) +rmd160_file:"data_files/hash_file_5":"52783243c1697bdbe16d37f97f68f08325dc1528" + +RMD160 Hash file #1 +rmd160_file:"data_files/hash_file_1":"82f1d072f0ec0c2b353703a7b575a04c113af1a6" + +RMD160 Hash file #2 +rmd160_file:"data_files/hash_file_2":"996fbc8b79206ba7393ebcd246584069b1c08f0f" + +RMD160 Hash file #3 +rmd160_file:"data_files/hash_file_3":"8653b46d65998fa8c8846efa17937e742533ae48" + +RMD160 Hash file #4 +rmd160_file:"data_files/hash_file_4":"9c1185a5c5e9fc54612808977ee8f548b2258d31" + MD2 Selftest depends_on:POLARSSL_MD2_C:POLARSSL_SELF_TEST md2_selftest: @@ -217,3 +256,7 @@ md4_selftest: MD5 Selftest depends_on:POLARSSL_MD5_C:POLARSSL_SELF_TEST md5_selftest: + +RMD160 Selftest +depends_on:POLARSSL_RMD160_C:POLARSSL_SELF_TEST +rmd160_selftest: diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function index e9a834740..b9db696f2 100644 --- a/tests/suites/test_suite_mdx.function +++ b/tests/suites/test_suite_mdx.function @@ -2,6 +2,7 @@ #include #include #include +#include /* END_HEADER */ /* BEGIN_CASE depends_on:POLARSSL_MD2_C */ @@ -64,6 +65,26 @@ void md5_text( char *text_src_string, char *hex_hash_string ) } /* END_CASE */ +/* BEGIN_CASE depends_on:POLARSSL_RMD160_C */ +void rmd160_text( char *text_src_string, char *hex_hash_string ) +{ + unsigned char src_str[1000]; + unsigned char hash_str[41]; + unsigned char output[20]; + + memset(src_str, 0x00, sizeof src_str); + memset(hash_str, 0x00, sizeof hash_str); + memset(output, 0x00, sizeof output); + + strcpy( (char *) src_str, text_src_string ); + + rmd160( src_str, strlen( (char *) src_str ), output ); + hexify( hash_str, output, sizeof output ); + + TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:POLARSSL_MD2_C */ void md2_hmac( int trunc_size, char *hex_key_string, char *hex_src_string, char *hex_hash_string ) @@ -187,6 +208,22 @@ void md5_file( char *filename, char *hex_hash_string ) } /* END_CASE */ +/* BEGIN_CASE depends_on:POLARSSL_RMD160_C:POLARSSL_FS_IO */ +void rmd160_file( char *filename, char *hex_hash_string ) +{ + unsigned char hash_str[41]; + unsigned char output[20]; + + memset(hash_str, 0x00, sizeof hash_str ); + memset(output, 0x00, sizeof output ); + + rmd160_file( filename, output); + hexify( hash_str, output, 20 ); + + TEST_ASSERT( strcmp( (char *) hash_str, hex_hash_string ) == 0 ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:POLARSSL_MD2_C:POLARSSL_SELF_TEST */ void md2_selftest() { @@ -207,3 +244,10 @@ void md5_selftest() TEST_ASSERT( md5_self_test( 0 ) == 0 ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:POLARSSL_RMD160_C:POLARSSL_SELF_TEST */ +void rmd160_selftest() +{ + TEST_ASSERT( rmd160_self_test( 0 ) == 0 ); +} +/* END_CASE */ diff --git a/visualc/VS2010/PolarSSL.vcxproj b/visualc/VS2010/PolarSSL.vcxproj index 4c067beda..8acfebeda 100644 --- a/visualc/VS2010/PolarSSL.vcxproj +++ b/visualc/VS2010/PolarSSL.vcxproj @@ -184,6 +184,7 @@ + @@ -245,6 +246,7 @@ + diff --git a/visualc/VS6/polarssl.dsp b/visualc/VS6/polarssl.dsp index b6a82c0b9..d48fe8f77 100644 --- a/visualc/VS6/polarssl.dsp +++ b/visualc/VS6/polarssl.dsp @@ -261,6 +261,10 @@ SOURCE=..\..\library\pkwrite.c # End Source File # Begin Source File +SOURCE=..\..\library\rmd160.c +# End Source File +# Begin Source File + SOURCE=..\..\library\rsa.c # End Source File # Begin Source File @@ -517,6 +521,10 @@ SOURCE=..\..\include\polarssl\pk.h # End Source File # Begin Source File +SOURCE=..\..\include\polarssl\rmd160.h +# End Source File +# Begin Source File + SOURCE=..\..\include\polarssl\rsa.h # End Source File # Begin Source File