diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-09-21 13:58:22 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-10-10 14:30:53 -0400 |
commit | 61875f30daf60305712e25b209ef41ced2635bad (patch) | |
tree | 176cda3ae729c520bff1b0f6a19806c18c0a7523 | |
parent | 47d06e532e95b71c0db3839ebdef3fe8812fca2c (diff) |
random: allow architectures to optionally define random_get_entropy()
Allow architectures which have a disabled get_cycles() function to
provide a random_get_entropy() function which provides a fine-grained,
rapidly changing counter that can be used by the /dev/random driver.
For example, an architecture might have a rapidly changing register
used to control random TLB cache eviction, or DRAM refresh that
doesn't meet the requirements of get_cycles(), but which is good
enough for the needs of the random driver.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/char/random.c | 8 | ||||
-rw-r--r-- | include/linux/timex.h | 14 |
2 files changed, 18 insertions, 4 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 92e6c67e1ae6..2d5daf9b58e9 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -643,7 +643,7 @@ struct timer_rand_state { | |||
643 | */ | 643 | */ |
644 | void add_device_randomness(const void *buf, unsigned int size) | 644 | void add_device_randomness(const void *buf, unsigned int size) |
645 | { | 645 | { |
646 | unsigned long time = get_cycles() ^ jiffies; | 646 | unsigned long time = random_get_entropy() ^ jiffies; |
647 | 647 | ||
648 | mix_pool_bytes(&input_pool, buf, size, NULL); | 648 | mix_pool_bytes(&input_pool, buf, size, NULL); |
649 | mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); | 649 | mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); |
@@ -680,7 +680,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) | |||
680 | goto out; | 680 | goto out; |
681 | 681 | ||
682 | sample.jiffies = jiffies; | 682 | sample.jiffies = jiffies; |
683 | sample.cycles = get_cycles(); | 683 | sample.cycles = random_get_entropy(); |
684 | sample.num = num; | 684 | sample.num = num; |
685 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); | 685 | mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); |
686 | 686 | ||
@@ -747,7 +747,7 @@ void add_interrupt_randomness(int irq, int irq_flags) | |||
747 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); | 747 | struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); |
748 | struct pt_regs *regs = get_irq_regs(); | 748 | struct pt_regs *regs = get_irq_regs(); |
749 | unsigned long now = jiffies; | 749 | unsigned long now = jiffies; |
750 | __u32 input[4], cycles = get_cycles(); | 750 | __u32 input[4], cycles = random_get_entropy(); |
751 | 751 | ||
752 | input[0] = cycles ^ jiffies; | 752 | input[0] = cycles ^ jiffies; |
753 | input[1] = irq; | 753 | input[1] = irq; |
@@ -1485,7 +1485,7 @@ unsigned int get_random_int(void) | |||
1485 | 1485 | ||
1486 | hash = get_cpu_var(get_random_int_hash); | 1486 | hash = get_cpu_var(get_random_int_hash); |
1487 | 1487 | ||
1488 | hash[0] += current->pid + jiffies + get_cycles(); | 1488 | hash[0] += current->pid + jiffies + random_get_entropy(); |
1489 | md5_transform(hash, random_int_secret); | 1489 | md5_transform(hash, random_int_secret); |
1490 | ret = hash[0]; | 1490 | ret = hash[0]; |
1491 | put_cpu_var(get_random_int_hash); | 1491 | put_cpu_var(get_random_int_hash); |
diff --git a/include/linux/timex.h b/include/linux/timex.h index b3726e61368e..da4c32dbb2aa 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -64,6 +64,20 @@ | |||
64 | 64 | ||
65 | #include <asm/timex.h> | 65 | #include <asm/timex.h> |
66 | 66 | ||
67 | #ifndef random_get_entropy | ||
68 | /* | ||
69 | * The random_get_entropy() function is used by the /dev/random driver | ||
70 | * in order to extract entropy via the relative unpredictability of | ||
71 | * when an interrupt takes places versus a high speed, fine-grained | ||
72 | * timing source or cycle counter. Since it will be occurred on every | ||
73 | * single interrupt, it must have a very low cost/overhead. | ||
74 | * | ||
75 | * By default we use get_cycles() for this purpose, but individual | ||
76 | * architectures may override this in their asm/timex.h header file. | ||
77 | */ | ||
78 | #define random_get_entropy() get_cycles() | ||
79 | #endif | ||
80 | |||
67 | /* | 81 | /* |
68 | * SHIFT_PLL is used as a dampening factor to define how much we | 82 | * SHIFT_PLL is used as a dampening factor to define how much we |
69 | * adjust the frequency correction for a given offset in PLL mode. | 83 | * adjust the frequency correction for a given offset in PLL mode. |