summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorOleksij Rempel <o.rempel@pengutronix.de>2017-03-22 10:14:34 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-03-30 08:23:20 +0200
commit07dc37dc9bbf0ddb2a4ef4e7baec07957492d42a (patch)
tree0c7f52db7442b5156be328b458ac98bc4cf21c35 /lib
parent8eac8a6c657274e4741518ba37ecde324ffe4186 (diff)
downloadbarebox-07dc37dc9bbf0ddb2a4ef4e7baec07957492d42a.tar.gz
barebox-07dc37dc9bbf0ddb2a4ef4e7baec07957492d42a.tar.xz
lib: random: add get_crypto_bytes interface and use HWRNG if posssible
For crypto applications we need to use some thing else as PRNG. So provide get_crypto_bytes() and use HWRNG as main source. PRNG is allowed as fallback if user decided to configure it so. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig9
-rw-r--r--lib/random.c52
2 files changed, 61 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 8a94ce09fb..9562b1b8c2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -90,6 +90,15 @@ config RATP
transferring packets over serial links described in RFC916. This implementation
is used for controlling barebox over serial ports.
+config ALLOW_PRNG_FALLBACK
+ bool "Allow fallback to PRNG if HWRNG not available."
+ help
+ WARNING: it is not secure!!
+
+ get_crypto_bytes() users like cmd_password relay on HWRNG. If HWRNG is not
+ available and this option is disabled, cmd_password will fail.
+ Enable it on your own risk.
+
source lib/gui/Kconfig
source lib/fonts/Kconfig
diff --git a/lib/random.c b/lib/random.c
index 210fea9946..759271f0c8 100644
--- a/lib/random.c
+++ b/lib/random.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <stdlib.h>
+#include <linux/hw_random.h>
static unsigned int random_seed;
@@ -18,6 +19,11 @@ void srand(unsigned int seed)
random_seed = seed;
}
+/**
+ * get_random_bytes - get pseudo random numbers.
+ * This interface can be good enough to generate MAC address
+ * or use for NAND test.
+ */
void get_random_bytes(void *_buf, int len)
{
char *buf = _buf;
@@ -25,3 +31,49 @@ void get_random_bytes(void *_buf, int len)
while (len--)
*buf++ = rand() % 256;
}
+
+/**
+ * get_crypto_bytes - get random numbers suitable for cryptographic needs.
+ */
+static int _get_crypto_bytes(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)
+ return -ENOMEDIUM;
+
+ if (bytes < 0)
+ return bytes;
+
+ len -= bytes;
+ buf = buf + bytes;
+ }
+
+ return 0;
+}
+
+int get_crypto_bytes(void *buf, int len)
+{
+ int err;
+
+ err = _get_crypto_bytes(buf, len);
+ if (!err)
+ return 0;
+
+ if (!IS_ENABLED(CONFIG_ALLOW_PRNG_FALLBACK)) {
+ pr_err("error: no HWRNG available!\n");
+ return err;
+ }
+
+ pr_warn("warning: falling back to Pseudo RNG source!\n");
+
+ get_random_bytes(buf, len);
+
+ return 0;
+}