Add entropy_self_test()
diff --git a/library/entropy.c b/library/entropy.c
index b500491..c01acf3 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -372,4 +372,97 @@
}
#endif /* POLARSSL_FS_IO */
+#if defined(POLARSSL_SELF_TEST)
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "polarssl/platform.h"
+#else
+#define polarssl_printf printf
+#endif
+
+/*
+ * Dummy source function
+ */
+static int entropy_dummy_source( void *data, unsigned char *output,
+ size_t len, size_t *olen )
+{
+ ((void) data);
+
+ memset( output, 0x2a, len );
+ *olen = len;
+
+ return( 0 );
+}
+
+/*
+ * The actual entropy quality is hard to test, but we can at least
+ * test that the functions don't cause errors and write the correct
+ * amount of data to buffers.
+ */
+int entropy_self_test( int verbose )
+{
+ int ret = 0;
+ entropy_context ctx;
+ unsigned char buf[ENTROPY_BLOCK_SIZE] = { 0 };
+ unsigned char acc[ENTROPY_BLOCK_SIZE] = { 0 };
+ size_t i, j;
+
+ if( verbose != 0 )
+ polarssl_printf( " ENTROPY test: " );
+
+ entropy_init( &ctx );
+
+ ret = entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 );
+ if( ret != 0 )
+ goto cleanup;
+
+ if( ( ret = entropy_gather( &ctx ) ) != 0 )
+ goto cleanup;
+
+ if( ( ret = entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
+ goto cleanup;
+
+ /*
+ * To test that entropy_func writes correct number of bytes:
+ * - use the whole buffer and rely on ASan to detect overruns
+ * - collect entropy 8 times and OR the result in an accumulator:
+ * any byte should then be 0 with probably 2^(-64), so requiring
+ * each of the 32 or 64 bytes to be non-zero has a false failure rate
+ * of at most 2^(-58) which is acceptable.
+ */
+ for( i = 0; i < 8; i++ )
+ {
+ if( ( ret = entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
+ goto cleanup;
+
+ for( j = 0; j < sizeof( buf ); j++ )
+ acc[j] |= buf[j];
+ }
+
+ for( j = 0; j < sizeof( buf ); j++ )
+ {
+ if( acc[j] == 0 )
+ {
+ ret = 1;
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ entropy_free( &ctx );
+
+ if( verbose != 0 )
+ {
+ if( ret != 0 )
+ polarssl_printf( "failed\n" );
+ else
+ polarssl_printf( "passed\n" );
+
+ polarssl_printf( "\n" );
+ }
+
+ return( ret != 0 );
+}
+#endif /* POLARSSL_SELF_TEST */
+
#endif /* POLARSSL_ENTROPY_C */