- Changed the used random function pointer to more flexible format. Renamed havege_rand() to havege_random() to prevent mistakes. Lots of changes as a consequence in library code and programs

diff --git a/library/bignum.c b/library/bignum.c
index 36e78e1..6591b5b 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1608,18 +1608,16 @@
     return( ret );
 }
 
-int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
+int mpi_fill_random( mpi *X, size_t size,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
 {
     int ret;
-    size_t k;
-    unsigned char *p;
 
     MPI_CHK( mpi_grow( X, size ) );
     MPI_CHK( mpi_lset( X, 0 ) );
 
-    p = (unsigned char *) X->p;
-    for( k = 0; k < X->n * ciL; k++ )
-        *p++ = (unsigned char) f_rng( p_rng );
+    MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, X->n * ciL ) );
 
 cleanup:
     return( ret );
@@ -1750,7 +1748,9 @@
 /*
  * Miller-Rabin primality test  (HAC 4.24)
  */
-int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
+int mpi_is_prime( mpi *X,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng )
 {
     int ret, xs;
     size_t i, j, n, s;
@@ -1809,7 +1809,7 @@
         /*
          * pick a random A, 1 < A < |X| - 1
          */
-        mpi_fill_random( &A, X->n, f_rng, p_rng );
+        MPI_CHK( mpi_fill_random( &A, X->n, f_rng, p_rng ) );
 
         if( mpi_cmp_mpi( &A, &W ) >= 0 )
         {
@@ -1867,7 +1867,8 @@
  * Prime number generation
  */
 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
-                   int (*f_rng)(void *), void *p_rng )
+                   int (*f_rng)(void *, unsigned char *, size_t),
+                   void *p_rng )
 {
     int ret;
     size_t k, n;
@@ -1880,7 +1881,7 @@
 
     n = BITS_TO_LIMBS( nbits );
 
-    mpi_fill_random( X, n, f_rng, p_rng );
+    MPI_CHK( mpi_fill_random( X, n, f_rng, p_rng ) );
 
     k = mpi_msb( X );
     if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
diff --git a/library/dhm.c b/library/dhm.c
index 07d722e..bddd076 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -127,7 +127,8 @@
  */
 int dhm_make_params( dhm_context *ctx, int x_size,
                      unsigned char *output, size_t *olen,
-                     int (*f_rng)(void *), void *p_rng )
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
 {
     int ret, n;
     size_t n1, n2, n3;
@@ -203,7 +204,8 @@
  */
 int dhm_make_public( dhm_context *ctx, int x_size,
                      unsigned char *output, size_t olen,
-                     int (*f_rng)(void *), void *p_rng )
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
 {
     int ret, n;
 
diff --git a/library/havege.c b/library/havege.c
index 11c3d28..ff302c5 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -200,18 +200,32 @@
 /*
  * HAVEGE rand function
  */
-int havege_rand( void *p_rng )
+int havege_random( void *p_rng, unsigned char *buf, size_t len )
 {
-    int ret;
+    int val;
+    size_t use_len;
     havege_state *hs = (havege_state *) p_rng;
+    unsigned char *p = buf;
 
-    if( hs->offset[1] >= COLLECT_SIZE )
-        havege_fill( hs );
+    while( len > 0 )
+    {
+        use_len = len;
+        if( use_len > sizeof(int) )
+            use_len = sizeof(int);
 
-    ret  = hs->pool[hs->offset[0]++];
-    ret ^= hs->pool[hs->offset[1]++];
+        if( hs->offset[1] >= COLLECT_SIZE )
+            havege_fill( hs );
 
-    return( ret );
+        val  = hs->pool[hs->offset[0]++];
+        val ^= hs->pool[hs->offset[1]++];
+
+        memcpy( p, &val, use_len );
+        
+        len -= use_len;
+        p += use_len;
+    }
+
+    return( 0 );
 }
 
 #endif
diff --git a/library/rsa.c b/library/rsa.c
index 8cadcad..3133b2f 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -58,9 +58,9 @@
  * Generate an RSA keypair
  */
 int rsa_gen_key( rsa_context *ctx,
-        int (*f_rng)(void *),
-        void *p_rng,
-        unsigned int nbits, int exponent )
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 unsigned int nbits, int exponent )
 {
     int ret;
     mpi P1, Q1, H, G;
@@ -356,16 +356,16 @@
  * Add the message padding, then do an RSA operation
  */
 int rsa_pkcs1_encrypt( rsa_context *ctx,
-                       int (*f_rng)(void *),
+                       int (*f_rng)(void *, unsigned char *, size_t),
                        void *p_rng,
                        int mode, size_t ilen,
                        const unsigned char *input,
                        unsigned char *output )
 {
-    size_t nb_pad, olen;
+    size_t nb_pad, olen, ret;
     unsigned char *p = output;
 #if defined(POLARSSL_PKCS1_V21)
-    unsigned int i, hlen;
+    unsigned int hlen;
     const md_info_t *md_info;
     md_context_t md_ctx;
 #endif
@@ -392,13 +392,13 @@
                 int rng_dl = 100;
 
                 do {
-                    *p = (unsigned char) f_rng( p_rng );
-                } while( *p == 0 && --rng_dl );
+                    ret = f_rng( p_rng, p, 1 );
+                } while( *p == 0 && --rng_dl && ret == 0 );
 
                 // Check if RNG failed to generate data
                 //
-                if( rng_dl == 0 )
-                    return POLARSSL_ERR_RSA_RNG_FAILED;
+                if( rng_dl == 0 || ret != 0)
+                    return POLARSSL_ERR_RSA_RNG_FAILED + ret;
 
                 p++;
             }
@@ -427,8 +427,10 @@
 
             // Generate a random octet string seed
             //
-            for( i = 0; i < hlen; ++i )
-                *p++ = (unsigned char) f_rng( p_rng ); 
+            if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
+                return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
+
+            p += hlen;
 
             // Construct DB
             //
@@ -578,7 +580,7 @@
  * Do an RSA operation to sign the message digest
  */
 int rsa_pkcs1_sign( rsa_context *ctx,
-                    int (*f_rng)(void *),
+                    int (*f_rng)(void *, unsigned char *, size_t),
                     void *p_rng,
                     int mode,
                     int hash_id,
@@ -590,7 +592,7 @@
     unsigned char *p = sig;
 #if defined(POLARSSL_PKCS1_V21)
     unsigned char salt[POLARSSL_MD_MAX_SIZE];
-    unsigned int i, slen, hlen, offset = 0;
+    unsigned int slen, hlen, offset = 0, ret;
     size_t msb;
     const md_info_t *md_info;
     md_context_t md_ctx;
@@ -757,8 +759,8 @@
 
             // Generate salt of length slen
             //
-            for( i = 0; i < slen; ++i )
-                salt[i] = (unsigned char) f_rng( p_rng ); 
+            if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+                return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
 
             // Note: EMSA-PSS encoding is over the length of N - 1 bits
             //
@@ -1080,12 +1082,17 @@
 #define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
                 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
 
-static int myrand( void *rng_state )
+static int myrand( void *rng_state, unsigned char *output, size_t len )
 {
+    size_t i;
+
     if( rng_state != NULL )
         rng_state  = NULL;
 
-    return( rand() );
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    
+    return( 0 );
 }
 
 /*
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 8644151..a7900e4 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -81,8 +81,10 @@
 
     SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
 
-    for( i = 28; i > 0; i-- )
-        *p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
+    if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
+        return( ret );
+
+    p += 28;
 
     memcpy( ssl->randbytes, buf + 6, 32 );
 
@@ -583,8 +585,9 @@
         ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
         ssl->pmslen = 48;
 
-        for( i = 2; i < ssl->pmslen; i++ )
-            ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
+        ret = ssl->f_rng( ssl->p_rng, ssl->premaster + 2, ssl->pmslen - 2 );
+        if( ret != 0 )
+            return( ret );
 
         i = 4;
         n = ssl->peer_cert->rsa.len;
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 2175523..57de3b1 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -359,7 +359,7 @@
 static int ssl_write_server_hello( ssl_context *ssl )
 {
     time_t t;
-    int ret, i, n;
+    int ret, n;
     unsigned char *buf, *p;
 
     SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
@@ -388,8 +388,10 @@
 
     SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
 
-    for( i = 28; i > 0; i-- )
-        *p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
+    if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
+        return( ret );
+
+    p += 28;
 
     memcpy( ssl->randbytes + 32, buf + 6, 32 );
 
@@ -413,9 +415,8 @@
         ssl->resume = 0;
         ssl->state++;
 
-        for( i = 0; i < n; i++ )
-            ssl->session->id[i] =
-                (unsigned char) ssl->f_rng( ssl->p_rng );
+        if( ( ret = ssl->f_rng( ssl->p_rng, ssl->session->id, n ) ) != 0 )
+            return( ret );
     }
     else
     {
@@ -823,8 +824,9 @@
              */
             ssl->pmslen = 48;
 
-            for( i = 0; i < ssl->pmslen; i++ )
-                ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
+            ret = ssl->f_rng( ssl->p_rng, ssl->premaster, ssl->pmslen );
+            if( ret != 0 )
+                return( ret );
         }
     }
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index c3644ad..a865a75 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -578,8 +578,9 @@
             /*
              * Generate IV
              */
-            for( i = 0; i < ssl->ivlen; i++ )
-                ssl->iv_enc[i] = ssl->f_rng( ssl->p_rng );
+            int ret = ssl->f_rng( ssl->p_rng, ssl->iv_enc, ssl->ivlen );
+            if( ret != 0 )
+                return( ret );
 
             /*
              * Shift message for ivlen bytes and prepend IV
@@ -1796,7 +1797,7 @@
 }
 
 void ssl_set_rng( ssl_context *ssl,
-                  int (*f_rng)(void *),
+                  int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng )
 {
     ssl->f_rng      = f_rng;