aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/random.c29
-rw-r--r--include/linux/random.h1
2 files changed, 25 insertions, 5 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index f67ae3e473ba..eacd61479112 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1038,17 +1038,34 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
1038 1038
1039/* 1039/*
1040 * This function is the exported kernel interface. It returns some 1040 * This function is the exported kernel interface. It returns some
1041 * number of good random numbers, suitable for seeding TCP sequence 1041 * number of good random numbers, suitable for key generation, seeding
1042 * numbers, etc. 1042 * TCP sequence numbers, etc. It does not use the hw random number
1043 * generator, if available; use get_random_bytes_arch() for that.
1043 */ 1044 */
1044void get_random_bytes(void *buf, int nbytes) 1045void get_random_bytes(void *buf, int nbytes)
1045{ 1046{
1047 extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
1048}
1049EXPORT_SYMBOL(get_random_bytes);
1050
1051/*
1052 * This function will use the architecture-specific hardware random
1053 * number generator if it is available. The arch-specific hw RNG will
1054 * almost certainly be faster than what we can do in software, but it
1055 * is impossible to verify that it is implemented securely (as
1056 * opposed, to, say, the AES encryption of a sequence number using a
1057 * key known by the NSA). So it's useful if we need the speed, but
1058 * only if we're willing to trust the hardware manufacturer not to
1059 * have put in a back door.
1060 */
1061void get_random_bytes_arch(void *buf, int nbytes)
1062{
1046 char *p = buf; 1063 char *p = buf;
1047 1064
1048 while (nbytes) { 1065 while (nbytes) {
1049 unsigned long v; 1066 unsigned long v;
1050 int chunk = min(nbytes, (int)sizeof(unsigned long)); 1067 int chunk = min(nbytes, (int)sizeof(unsigned long));
1051 1068
1052 if (!arch_get_random_long(&v)) 1069 if (!arch_get_random_long(&v))
1053 break; 1070 break;
1054 1071
@@ -1057,9 +1074,11 @@ void get_random_bytes(void *buf, int nbytes)
1057 nbytes -= chunk; 1074 nbytes -= chunk;
1058 } 1075 }
1059 1076
1060 extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); 1077 if (nbytes)
1078 extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
1061} 1079}
1062EXPORT_SYMBOL(get_random_bytes); 1080EXPORT_SYMBOL(get_random_bytes_arch);
1081
1063 1082
1064/* 1083/*
1065 * init_std_data - initialize pool with system data 1084 * init_std_data - initialize pool with system data
diff --git a/include/linux/random.h b/include/linux/random.h
index e14b4387354a..29e217a7e6d0 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -56,6 +56,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
56extern void add_interrupt_randomness(int irq, int irq_flags); 56extern void add_interrupt_randomness(int irq, int irq_flags);
57 57
58extern void get_random_bytes(void *buf, int nbytes); 58extern void get_random_bytes(void *buf, int nbytes);
59extern void get_random_bytes_arch(void *buf, int nbytes);
59void generate_random_uuid(unsigned char uuid_out[16]); 60void generate_random_uuid(unsigned char uuid_out[16]);
60 61
61#ifndef MODULE 62#ifndef MODULE