diff --git a/tests/include/test/random.h b/tests/include/test/random.h index 11a353176..c60803597 100644 --- a/tests/include/test/random.h +++ b/tests/include/test/random.h @@ -32,4 +32,67 @@ #include MBEDTLS_CONFIG_FILE #endif +#include +#include + +typedef struct +{ + unsigned char *buf; + size_t length; +} rnd_buf_info; + +/** + * Info structure for the pseudo random function + * + * Key should be set at the start to a test-unique value. + * Do not forget endianness! + * State( v0, v1 ) should be set to zero. + */ +typedef struct +{ + uint32_t key[16]; + uint32_t v0, v1; +} rnd_pseudo_info; + +/** + * This function just returns data from rand(). + * Although predictable and often similar on multiple + * runs, this does not result in identical random on + * each run. So do not use this if the results of a + * test depend on the random data that is generated. + * + * rng_state shall be NULL. + */ +int rnd_std_rand( void *rng_state, unsigned char *output, size_t len ); + +/** + * This function only returns zeros + * + * rng_state shall be NULL. + */ +int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ); + +/** + * This function returns random based on a buffer it receives. + * + * rng_state shall be a pointer to a rnd_buf_info structure. + * + * The number of bytes released from the buffer on each call to + * the random function is specified by per_call. (Can be between + * 1 and 4) + * + * After the buffer is empty it will return rand(); + */ +int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ); + +/** + * This function returns random based on a pseudo random function. + * This means the results should be identical on all systems. + * Pseudo random is based on the XTEA encryption algorithm to + * generate pseudorandom. + * + * rng_state shall be a pointer to a rnd_pseudo_info structure. + */ +int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ); + #endif /* TEST_RANDOM_H */ diff --git a/tests/src/random.c b/tests/src/random.c index f80a1c471..bb0df7a71 100644 --- a/tests/src/random.c +++ b/tests/src/random.c @@ -23,4 +23,95 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ +#include #include +#include + +int rnd_std_rand( void *rng_state, unsigned char *output, size_t len ) +{ +#if !defined(__OpenBSD__) + size_t i; + + if( rng_state != NULL ) + rng_state = NULL; + + for( i = 0; i < len; ++i ) + output[i] = rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ + + return( 0 ); +} + +int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ) +{ + if( rng_state != NULL ) + rng_state = NULL; + + memset( output, 0, len ); + + return( 0 ); +} + +int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ) +{ + rnd_buf_info *info = (rnd_buf_info *) rng_state; + size_t use_len; + + if( rng_state == NULL ) + return( rnd_std_rand( NULL, output, len ) ); + + use_len = len; + if( len > info->length ) + use_len = info->length; + + if( use_len ) + { + memcpy( output, info->buf, use_len ); + info->buf += use_len; + info->length -= use_len; + } + + if( len - use_len > 0 ) + return( rnd_std_rand( NULL, output + use_len, len - use_len ) ); + + return( 0 ); +} + +int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ) +{ + rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state; + uint32_t i, *k, sum, delta=0x9E3779B9; + unsigned char result[4], *out = output; + + if( rng_state == NULL ) + return( rnd_std_rand( NULL, output, len ) ); + + k = info->key; + + while( len > 0 ) + { + size_t use_len = ( len > 4 ) ? 4 : len; + sum = 0; + + for( i = 0; i < 32; i++ ) + { + info->v0 += ( ( ( info->v1 << 4 ) ^ ( info->v1 >> 5 ) ) + + info->v1 ) ^ ( sum + k[sum & 3] ); + sum += delta; + info->v1 += ( ( ( info->v0 << 4 ) ^ ( info->v0 >> 5 ) ) + + info->v0 ) ^ ( sum + k[( sum>>11 ) & 3] ); + } + + PUT_UINT32_BE( info->v0, result, 0 ); + memcpy( out, result, use_len ); + len -= use_len; + out += 4; + } + + return( 0 ); +} diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index 926658216..a5285a3a6 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -487,144 +487,3 @@ static void close_output( FILE* out_stream ) fclose( out_stream ); } #endif /* __unix__ || __APPLE__ __MACH__ */ - -/** - * This function just returns data from rand(). - * Although predictable and often similar on multiple - * runs, this does not result in identical random on - * each run. So do not use this if the results of a - * test depend on the random data that is generated. - * - * rng_state shall be NULL. - */ -int rnd_std_rand( void *rng_state, unsigned char *output, size_t len ) -{ -#if !defined(__OpenBSD__) - size_t i; - - if( rng_state != NULL ) - rng_state = NULL; - - for( i = 0; i < len; ++i ) - output[i] = rand(); -#else - if( rng_state != NULL ) - rng_state = NULL; - - arc4random_buf( output, len ); -#endif /* !OpenBSD */ - - return( 0 ); -} - -/** - * This function only returns zeros - * - * rng_state shall be NULL. - */ -int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ) -{ - if( rng_state != NULL ) - rng_state = NULL; - - memset( output, 0, len ); - - return( 0 ); -} - -typedef struct -{ - unsigned char *buf; - size_t length; -} rnd_buf_info; - -/** - * This function returns random based on a buffer it receives. - * - * rng_state shall be a pointer to a rnd_buf_info structure. - * - * The number of bytes released from the buffer on each call to - * the random function is specified by per_call. (Can be between - * 1 and 4) - * - * After the buffer is empty it will return rand(); - */ -int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ) -{ - rnd_buf_info *info = (rnd_buf_info *) rng_state; - size_t use_len; - - if( rng_state == NULL ) - return( rnd_std_rand( NULL, output, len ) ); - - use_len = len; - if( len > info->length ) - use_len = info->length; - - if( use_len ) - { - memcpy( output, info->buf, use_len ); - info->buf += use_len; - info->length -= use_len; - } - - if( len - use_len > 0 ) - return( rnd_std_rand( NULL, output + use_len, len - use_len ) ); - - return( 0 ); -} - -/** - * Info structure for the pseudo random function - * - * Key should be set at the start to a test-unique value. - * Do not forget endianness! - * State( v0, v1 ) should be set to zero. - */ -typedef struct -{ - uint32_t key[16]; - uint32_t v0, v1; -} rnd_pseudo_info; - -/** - * This function returns random based on a pseudo random function. - * This means the results should be identical on all systems. - * Pseudo random is based on the XTEA encryption algorithm to - * generate pseudorandom. - * - * rng_state shall be a pointer to a rnd_pseudo_info structure. - */ -int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ) -{ - rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state; - uint32_t i, *k, sum, delta=0x9E3779B9; - unsigned char result[4], *out = output; - - if( rng_state == NULL ) - return( rnd_std_rand( NULL, output, len ) ); - - k = info->key; - - while( len > 0 ) - { - size_t use_len = ( len > 4 ) ? 4 : len; - sum = 0; - - for( i = 0; i < 32; i++ ) - { - info->v0 += ( ( ( info->v1 << 4 ) ^ ( info->v1 >> 5 ) ) - + info->v1 ) ^ ( sum + k[sum & 3] ); - sum += delta; - info->v1 += ( ( ( info->v0 << 4 ) ^ ( info->v0 >> 5 ) ) - + info->v0 ) ^ ( sum + k[( sum>>11 ) & 3] ); - } - - PUT_UINT32_BE( info->v0, result, 0 ); - memcpy( out, result, use_len ); - len -= use_len; - out += 4; - } - - return( 0 ); -}