Commit 99c9acfe authored by Łukasz Stelmach's avatar Łukasz Stelmach Committed by Herbert Xu

crypto: exynos - Reseed PRNG after generating 2^16 random bytes

Reseed PRNG after reading 65 kB of randomness. Although this may reduce
performance, in most cases the loss is not noticeable. Also the time
based threshold for reseeding is changed to one second. Reseeding is
performed whenever either limit is exceeded.

Reseeding of a PRNG does not increase entropy, but it helps preventing
backtracking the internal state of the device from its output sequence,
and hence, prevents potential attacker from predicting numbers to be
generated.
Signed-off-by: default avatarŁukasz Stelmach <l.stelmach@samsung.com>
Reviewed-by: default avatarStephan Mueller <smueller@chronox.de>
Reviewed-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 3a5a5e5c
...@@ -55,12 +55,14 @@ enum exynos_prng_type { ...@@ -55,12 +55,14 @@ enum exynos_prng_type {
}; };
/* /*
* Driver re-seeds itself with generated random numbers to increase * Driver re-seeds itself with generated random numbers to hinder
* the randomness. * backtracking of the original seed.
* *
* Time for next re-seed in ms. * Time for next re-seed in ms.
*/ */
#define EXYNOS_RNG_RESEED_TIME 100 #define EXYNOS_RNG_RESEED_TIME 1000
#define EXYNOS_RNG_RESEED_BYTES 65536
/* /*
* In polling mode, do not wait infinitely for the engine to finish the work. * In polling mode, do not wait infinitely for the engine to finish the work.
*/ */
...@@ -82,6 +84,8 @@ struct exynos_rng_dev { ...@@ -82,6 +84,8 @@ struct exynos_rng_dev {
unsigned int seed_save_len; unsigned int seed_save_len;
/* Time of last seeding in jiffies */ /* Time of last seeding in jiffies */
unsigned long last_seeding; unsigned long last_seeding;
/* Bytes generated since last seeding */
unsigned long bytes_seeding;
}; };
static struct exynos_rng_dev *exynos_rng_dev; static struct exynos_rng_dev *exynos_rng_dev;
...@@ -126,6 +130,7 @@ static int exynos_rng_set_seed(struct exynos_rng_dev *rng, ...@@ -126,6 +130,7 @@ static int exynos_rng_set_seed(struct exynos_rng_dev *rng,
} }
rng->last_seeding = jiffies; rng->last_seeding = jiffies;
rng->bytes_seeding = 0;
return 0; return 0;
} }
...@@ -164,6 +169,7 @@ static int exynos_rng_get_random(struct exynos_rng_dev *rng, ...@@ -164,6 +169,7 @@ static int exynos_rng_get_random(struct exynos_rng_dev *rng,
EXYNOS_RNG_STATUS); EXYNOS_RNG_STATUS);
*read = min_t(size_t, dlen, EXYNOS_RNG_SEED_SIZE); *read = min_t(size_t, dlen, EXYNOS_RNG_SEED_SIZE);
memcpy_fromio(dst, rng->mem + EXYNOS_RNG_OUT_BASE, *read); memcpy_fromio(dst, rng->mem + EXYNOS_RNG_OUT_BASE, *read);
rng->bytes_seeding += *read;
return 0; return 0;
} }
...@@ -177,7 +183,8 @@ static void exynos_rng_reseed(struct exynos_rng_dev *rng) ...@@ -177,7 +183,8 @@ static void exynos_rng_reseed(struct exynos_rng_dev *rng)
unsigned int read = 0; unsigned int read = 0;
u8 seed[EXYNOS_RNG_SEED_SIZE]; u8 seed[EXYNOS_RNG_SEED_SIZE];
if (time_before(now, next_seeding)) if (time_before(now, next_seeding) &&
rng->bytes_seeding < EXYNOS_RNG_RESEED_BYTES)
return; return;
if (exynos_rng_get_random(rng, seed, sizeof(seed), &read)) if (exynos_rng_get_random(rng, seed, sizeof(seed), &read))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment