]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Remove ambiguity in rand_pool_add[_end] return value
authorRichard Levitte <levitte@openssl.org>
Wed, 4 Apr 2018 16:31:50 +0000 (18:31 +0200)
committerRichard Levitte <levitte@openssl.org>
Wed, 4 Apr 2018 18:14:51 +0000 (20:14 +0200)
When these two functions returned zero, it could mean:

1. that an error occured.  In their case, the error is an overflow of
   the pool, i.e. the correct response from the caller would be to
   stop trying to fill the pool.
2. that there isn't enought entropy acquired yet, i.e. the correct
   response from the caller would be to try and add more entropy to
   the pool.

Because of this ambiguity, the returned zero turns out to be useless.
This change makes the returned value more consistent.  1 means the
addition of new entropy was successful, 0 means it wasn't.  To know if
the pool has been filled enough, the caller will have to call some
other function, such as rand_pool_entropy_available().

Fixes #5846

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/5876)

crypto/rand/rand_lib.c
crypto/rand/rand_unix.c
crypto/rand/rand_vms.c
crypto/rand/rand_win.c

index 143dfb0f1934e29cb03ef124f5612c4070ca66be..3589e75853e91b8d8bb9a72e75607f13ec3da31f 100644 (file)
@@ -130,26 +130,20 @@ size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool)
         buffer = rand_pool_add_begin(pool, bytes_needed);
 
         if (buffer != NULL) {
-
-            /* If RDSEED is available, use that. */
+            /* Whichever comes first, use RDSEED, RDRAND or nothing */
             if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
                 if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed)
-                    == bytes_needed)
-                    return rand_pool_add_end(pool,
-                                             bytes_needed,
-                                             8 * bytes_needed);
-            }
-
-            /* Second choice is RDRAND. */
-            if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
+                    == bytes_needed) {
+                    rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
+                }
+            } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
                 if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed)
-                    == bytes_needed)
-                    return rand_pool_add_end(pool,
-                                             bytes_needed,
-                                             8 * bytes_needed);
+                    == bytes_needed) {
+                    rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
+                }
+            } else {
+                rand_pool_add_end(pool, 0, 0);
             }
-
-            return rand_pool_add_end(pool, 0, 0);
         }
     }
 
@@ -222,7 +216,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
                 bytes = bytes_needed;
             rand_drbg_unlock(drbg->parent);
 
-            entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+            rand_pool_add_end(pool, bytes, 8 * bytes);
+            entropy_available = rand_pool_entropy_available(pool);
         }
 
     } else {
@@ -631,11 +626,10 @@ size_t rand_pool_bytes_remaining(RAND_POOL *pool)
  * random input which contains at least |entropy| bits of
  * randomness.
  *
- * Return available amount of entropy after this operation.
- * (see rand_pool_entropy_available(pool))
+ * Returns 1 if the added amount is adequate, otherwise 0
  */
-size_t rand_pool_add(RAND_POOL *pool,
-                     const unsigned char *buffer, size_t len, size_t entropy)
+int rand_pool_add(RAND_POOL *pool,
+                  const unsigned char *buffer, size_t len, size_t entropy)
 {
     if (len > pool->max_len - pool->len) {
         RANDerr(RAND_F_RAND_POOL_ADD, RAND_R_ENTROPY_INPUT_TOO_LONG);
@@ -648,7 +642,7 @@ size_t rand_pool_add(RAND_POOL *pool,
         pool->entropy += entropy;
     }
 
-    return rand_pool_entropy_available(pool);
+    return 1;
 }
 
 /*
@@ -685,7 +679,7 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
  * to the buffer which contain at least |entropy| bits of randomness.
  * It is allowed to add less bytes than originally reserved.
  */
-size_t rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
+int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
 {
     if (len > pool->max_len - pool->len) {
         RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
@@ -697,7 +691,7 @@ size_t rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
         pool->entropy += entropy;
     }
 
-    return rand_pool_entropy_available(pool);
+    return 1;
 }
 
 int RAND_set_rand_method(const RAND_METHOD *meth)
index b86f94ab7283ef7ef49008a698a3c537f27beb76..0f9407f3ffab363305cb11d0a4ddf78f52838f39 100644 (file)
@@ -174,7 +174,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
         if (getrandom(buffer, bytes_needed, 0) == (int)bytes_needed)
             bytes = bytes_needed;
 
-        entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+        rand_pool_add_end(pool, bytes, 8 * bytes);
+        entropy_available = rand_pool_entropy_available(pool);
     }
     if (entropy_available > 0)
         return entropy_available;
@@ -203,7 +204,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
                 if (fread(buffer, 1, bytes_needed, fp) == bytes_needed)
                     bytes = bytes_needed;
 
-                entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+                rand_pool_add_end(pool, bytes, 8 * bytes);
+                entropy_available = rand_pool_entropy_available(pool);
             }
             fclose(fp);
             if (entropy_available > 0)
@@ -241,7 +243,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
                 if (num == (int)bytes_needed)
                     bytes = bytes_needed;
 
-                entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+                rand_pool_add_end(pool, bytes, 8 * bytes);
+                entropy_available = rand_pool_entropy_available(pool);
             }
             if (entropy_available > 0)
                 return entropy_available;
index 7edec9ebd2282389c56c58dbe5fcaea8465bea91..1507c6ff7c3fd1e803d2ac8c5efe9b872fcfe7f0 100644 (file)
@@ -148,8 +148,9 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
     if (total_length > bytes_remaining)
         total_length = bytes_remaining;
 
-    return rand_pool_add(pool, (PTR_T)data_buffer, total_length,
-                         total_length * ENTROPY_BITS_PER_BYTE);
+    rand_pool_add(pool, (PTR_T)data_buffer, total_length,
+                  total_length * ENTROPY_BITS_PER_BYTE);
+    return rand_pool_entropy_available(pool);
 }
 
 #endif
index 7f341881078b14eb926613d3f779634b1a933b10..ad5e3d116b71559c6ad54e6feabed1cda44761db 100644 (file)
@@ -70,7 +70,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
             BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS)
             bytes = bytes_needed;
 
-        entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+        rand_pool_add_end(pool, bytes, 8 * bytes);
+        entropy_available = rand_pool_entropy_available(pool);
     }
     if (entropy_available > 0)
         return entropy_available;
@@ -88,7 +89,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
             CryptReleaseContext(hProvider, 0);
         }
 
-        entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+        rand_pool_add_end(pool, bytes, 8 * bytes);
+        entropy_available = rand_pool_entropy_available(pool);
     }
     if (entropy_available > 0)
         return entropy_available;
@@ -106,7 +108,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 
             CryptReleaseContext(hProvider, 0);
         }
-        entropy_available = rand_pool_add_end(pool, bytes, 8 * bytes);
+        rand_pool_add_end(pool, bytes, 8 * bytes);
+        entropy_available = rand_pool_entropy_available(pool);
     }
     if (entropy_available > 0)
         return entropy_available;