|
@@ -1038,17 +1038,34 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
|
|
|
|
|
|
/*
|
|
|
* This function is the exported kernel interface. It returns some
|
|
|
- * number of good random numbers, suitable for seeding TCP sequence
|
|
|
- * numbers, etc.
|
|
|
+ * number of good random numbers, suitable for key generation, seeding
|
|
|
+ * TCP sequence numbers, etc. It does not use the hw random number
|
|
|
+ * generator, if available; use get_random_bytes_arch() for that.
|
|
|
*/
|
|
|
void get_random_bytes(void *buf, int nbytes)
|
|
|
+{
|
|
|
+ extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(get_random_bytes);
|
|
|
+
|
|
|
+/*
|
|
|
+ * This function will use the architecture-specific hardware random
|
|
|
+ * number generator if it is available. The arch-specific hw RNG will
|
|
|
+ * almost certainly be faster than what we can do in software, but it
|
|
|
+ * is impossible to verify that it is implemented securely (as
|
|
|
+ * opposed, to, say, the AES encryption of a sequence number using a
|
|
|
+ * key known by the NSA). So it's useful if we need the speed, but
|
|
|
+ * only if we're willing to trust the hardware manufacturer not to
|
|
|
+ * have put in a back door.
|
|
|
+ */
|
|
|
+void get_random_bytes_arch(void *buf, int nbytes)
|
|
|
{
|
|
|
char *p = buf;
|
|
|
|
|
|
while (nbytes) {
|
|
|
unsigned long v;
|
|
|
int chunk = min(nbytes, (int)sizeof(unsigned long));
|
|
|
-
|
|
|
+
|
|
|
if (!arch_get_random_long(&v))
|
|
|
break;
|
|
|
|
|
@@ -1057,9 +1074,11 @@ void get_random_bytes(void *buf, int nbytes)
|
|
|
nbytes -= chunk;
|
|
|
}
|
|
|
|
|
|
- extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
|
|
|
+ if (nbytes)
|
|
|
+ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
|
|
|
}
|
|
|
-EXPORT_SYMBOL(get_random_bytes);
|
|
|
+EXPORT_SYMBOL(get_random_bytes_arch);
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
* init_std_data - initialize pool with system data
|