summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hw_random.h6
-rw-r--r--include/stdlib.h2
-rw-r--r--lib/random.c25
3 files changed, 19 insertions, 14 deletions
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
index 116afd9721..e541abfa17 100644
--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -36,12 +36,16 @@ struct hwrng {
/* Register a new Hardware Random Number Generator driver. */
int hwrng_register(struct device_d *dev, struct hwrng *rng);
-int hwrng_get_data(struct hwrng *rng, void *buffer, size_t size, int wait);
#ifdef CONFIG_HWRNG
struct hwrng *hwrng_get_first(void);
+int hwrng_get_data(struct hwrng *rng, void *buffer, size_t size, int wait);
#else
static inline struct hwrng *hwrng_get_first(void) { return ERR_PTR(-ENODEV); };
+static inline int hwrng_get_data(struct hwrng *rng, void *buffer, size_t size, int wait)
+{
+ return -ENODEV;
+}
#endif
void hwrng_unregister(struct hwrng *rng);
diff --git a/include/stdlib.h b/include/stdlib.h
index 8eb419e111..0305970557 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -15,6 +15,8 @@ void srand(unsigned int seed);
/* fill a buffer with pseudo-random data */
void get_random_bytes(void *buf, int len);
int get_crypto_bytes(void *buf, int len);
+struct hwrng;
+int hwrng_get_crypto_bytes(struct hwrng *rng, void *buf, int len);
static inline u32 random32(void)
{
diff --git a/lib/random.c b/lib/random.c
index fb3580f9c0..c6532df552 100644
--- a/lib/random.c
+++ b/lib/random.c
@@ -34,17 +34,8 @@ void get_random_bytes(void *_buf, int len)
*buf++ = rand() % 256;
}
-/**
- * get_crypto_bytes - get random numbers suitable for cryptographic needs.
- */
-static int _get_crypto_bytes(void *buf, int len)
+int hwrng_get_crypto_bytes(struct hwrng *rng, void *buf, int len)
{
- struct hwrng *rng;
-
- rng = hwrng_get_first();
- if (IS_ERR(rng))
- return PTR_ERR(rng);
-
while (len) {
int bytes = hwrng_get_data(rng, buf, len, true);
if (!bytes)
@@ -60,13 +51,21 @@ static int _get_crypto_bytes(void *buf, int len)
return 0;
}
+/**
+ * get_crypto_bytes - get random numbers suitable for cryptographic needs.
+ */
int get_crypto_bytes(void *buf, int len)
{
+ struct hwrng *rng;
int err;
- err = _get_crypto_bytes(buf, len);
- if (!err)
- return 0;
+ rng = hwrng_get_first();
+ err = PTR_ERR_OR_ZERO(rng);
+ if (!err) {
+ err = hwrng_get_crypto_bytes(rng, buf, len);
+ if (!err)
+ return 0;
+ }
if (!IS_ENABLED(CONFIG_ALLOW_PRNG_FALLBACK)) {
pr_err("error: no HWRNG available!\n");