/* * Thread-safe wrapper for entropy_gather_internal() */ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) { int ret; #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif ret = entropy_gather_internal( ctx ); #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }
/* * Thread-safe wrapper for entropy_gather_internal() */ int entropy_gather( entropy_context *ctx ) { int ret; #if defined(POLARSSL_THREADING_C) if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif ret = entropy_gather_internal( ctx ); #if defined(POLARSSL_THREADING_C) if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) { int ret, count = 0, i, done; mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif /* * Always gather extra entropy before a call */ do { if( count++ > ENTROPY_MAX_LOOP ) { ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; goto exit; } if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) goto exit; done = 1; for( i = 0; i < ctx->source_count; i++ ) if( ctx->source[i].size < ctx->source[i].threshold ) done = 0; } while( ! done ); memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) mbedtls_sha512_finish( &ctx->accumulator, buf ); /* * Reset accumulator and counters and recycle existing entropy */ memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) ); mbedtls_sha512_starts( &ctx->accumulator, 0 ); mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); /* * Perform second SHA-512 on entropy */ mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ mbedtls_sha256_finish( &ctx->accumulator, buf ); /* * Reset accumulator and counters and recycle existing entropy */ memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) ); mbedtls_sha256_starts( &ctx->accumulator, 0 ); mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); /* * Perform second SHA-256 on entropy */ mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ for( i = 0; i < ctx->source_count; i++ ) ctx->source[i].size = 0; memcpy( output, buf, len ); ret = 0; exit: #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }
int entropy_func( void *data, unsigned char *output, size_t len ) { int ret, count = 0, i, reached; entropy_context *ctx = (entropy_context *) data; unsigned char buf[ENTROPY_BLOCK_SIZE]; if( len > ENTROPY_BLOCK_SIZE ) return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); #if defined(POLARSSL_THREADING_C) if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif /* * Always gather extra entropy before a call */ do { if( count++ > ENTROPY_MAX_LOOP ) { ret = POLARSSL_ERR_ENTROPY_SOURCE_FAILED; goto exit; } if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) goto exit; reached = 0; for( i = 0; i < ctx->source_count; i++ ) if( ctx->source[i].size >= ctx->source[i].threshold ) reached++; } while( reached != ctx->source_count ); memset( buf, 0, ENTROPY_BLOCK_SIZE ); #if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) sha512_finish( &ctx->accumulator, buf ); /* * Reset accumulator and counters and recycle existing entropy */ memset( &ctx->accumulator, 0, sizeof( sha512_context ) ); sha512_starts( &ctx->accumulator, 0 ); sha512_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); /* * Perform second SHA-512 on entropy */ sha512( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); #else /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ sha256_finish( &ctx->accumulator, buf ); /* * Reset accumulator and counters and recycle existing entropy */ memset( &ctx->accumulator, 0, sizeof( sha256_context ) ); sha256_starts( &ctx->accumulator, 0 ); sha256_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); /* * Perform second SHA-256 on entropy */ sha256( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); #endif /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ for( i = 0; i < ctx->source_count; i++ ) ctx->source[i].size = 0; memcpy( output, buf, len ); ret = 0; exit: #if defined(POLARSSL_THREADING_C) if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) { int ret, count = 0, i, done; mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); #if defined(MBEDTLS_ENTROPY_NV_SEED) /* Update the NV entropy seed before generating any entropy for outside * use. */ if( ctx->initial_entropy_run == 0 ) { ctx->initial_entropy_run = 1; if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) return( ret ); } #endif #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif /* * Always gather extra entropy before a call */ do { if( count++ > ENTROPY_MAX_LOOP ) { ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; goto exit; } if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) goto exit; done = 1; for( i = 0; i < ctx->source_count; i++ ) if( ctx->source[i].size < ctx->source[i].threshold ) done = 0; } while( ! done ); memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) /* * Note that at this stage it is assumed that the accumulator was started * in a previous call to entropy_update(). If this is not guaranteed, the * code below will fail. */ if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 ) goto exit; /* * Reset accumulator and counters and recycle existing entropy */ mbedtls_sha512_free( &ctx->accumulator ); mbedtls_sha512_init( &ctx->accumulator ); if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) goto exit; if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) goto exit; /* * Perform second SHA-512 on entropy */ if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ) ) != 0 ) goto exit; #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 ) goto exit; /* * Reset accumulator and counters and recycle existing entropy */ mbedtls_sha256_free( &ctx->accumulator ); mbedtls_sha256_init( &ctx->accumulator ); if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) goto exit; if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) goto exit; /* * Perform second SHA-256 on entropy */ if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ) ) != 0 ) goto exit; #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ for( i = 0; i < ctx->source_count; i++ ) ctx->source[i].size = 0; memcpy( output, buf, len ); ret = 0; exit: mbedtls_zeroize( buf, sizeof( buf ) ); #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif return( ret ); }