aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-07-31 16:59:29 -0400
committerH. Peter Anvin <hpa@zytor.com>2011-07-31 16:59:29 -0400
commit628c6246d47b85f5357298601df2444d7f4dd3fd (patch)
tree624f2b90cdfefcd5f7d1a8cd26c548cbfc289f8e /arch
parent63d77173266c1791f1553e9e8ccea65dc87c4485 (diff)
x86, random: Architectural inlines to get random integers with RDRAND
Architectural inlines to get random ints and longs using the RDRAND instruction. Intel has introduced a new RDRAND instruction, a Digital Random Number Generator (DRNG), which is functionally an high bandwidth entropy source, cryptographic whitener, and integrity monitor all built into hardware. This enables RDRAND to be used directly, bypassing the kernel random number pool. For technical documentation, see: http://software.intel.com/en-us/articles/download-the-latest-bull-mountain-software-implementation-guide/ In this patch, this is *only* used for the nonblocking random number pool. RDRAND is a nonblocking source, similar to our /dev/urandom, and is therefore not a direct replacement for /dev/random. The architectural hooks presented in the previous patch only feed the kernel internal users, which only use the nonblocking pool, and so this is not a problem. Since this instruction is available in userspace, there is no reason to have a /dev/hw_rng device driver for the purpose of feeding rngd. This is especially so since RDRAND is a nonblocking source, and needs additional whitening and reduction (see the above technical documentation for details) in order to be of "pure entropy source" quality. The CONFIG_EXPERT compile-time option can be used to disable this use of RDRAND. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Originally-by: Fenghua Yu <fenghua.yu@intel.com> Cc: Matt Mackall <mpm@selenic.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/Kconfig9
-rw-r--r--arch/x86/include/asm/archrandom.h73
2 files changed, 82 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 37357a599dca..a0e9bda72fda 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1451,6 +1451,15 @@ config ARCH_USES_PG_UNCACHED
1451 def_bool y 1451 def_bool y
1452 depends on X86_PAT 1452 depends on X86_PAT
1453 1453
1454config ARCH_RANDOM
1455 def_bool y
1456 prompt "x86 architectural random number generator" if EXPERT
1457 ---help---
1458 Enable the x86 architectural RDRAND instruction
1459 (Intel Bull Mountain technology) to generate random numbers.
1460 If supported, this is a high bandwidth, cryptographically
1461 secure hardware random number generator.
1462
1454config EFI 1463config EFI
1455 bool "EFI runtime service support" 1464 bool "EFI runtime service support"
1456 depends on ACPI 1465 depends on ACPI
diff --git a/arch/x86/include/asm/archrandom.h b/arch/x86/include/asm/archrandom.h
new file mode 100644
index 000000000000..b7b5bc02e361
--- /dev/null
+++ b/arch/x86/include/asm/archrandom.h
@@ -0,0 +1,73 @@
1/*
2 * This file is part of the Linux kernel.
3 *
4 * Copyright (c) 2011, Intel Corporation
5 * Authors: Fenghua Yu <fenghua.yu@intel.com>,
6 * H. Peter Anvin <hpa@linux.intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#ifndef ASM_X86_ARCHRANDOM_H
24#define ASM_X86_ARCHRANDOM_H
25
26#include <asm/processor.h>
27#include <asm/cpufeature.h>
28#include <asm/alternative.h>
29#include <asm/nops.h>
30
31#define RDRAND_RETRY_LOOPS 10
32
33#define RDRAND_INT ".byte 0x0f,0xc7,0xf0"
34#ifdef CONFIG_X86_64
35# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0"
36#else
37# define RDRAND_LONG RDRAND_INT
38#endif
39
40#ifdef CONFIG_ARCH_RANDOM
41
42#define GET_RANDOM(name, type, rdrand, nop) \
43static inline int name(type *v) \
44{ \
45 int ok; \
46 alternative_io("movl $0, %0\n\t" \
47 nop, \
48 "\n1: " rdrand "\n\t" \
49 "jc 2f\n\t" \
50 "decl %0\n\t" \
51 "jnz 1b\n\t" \
52 "2:", \
53 X86_FEATURE_RDRAND, \
54 ASM_OUTPUT2("=r" (ok), "=a" (*v)), \
55 "0" (RDRAND_RETRY_LOOPS)); \
56 return ok; \
57}
58
59#ifdef CONFIG_X86_64
60
61GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5);
62GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4);
63
64#else
65
66GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3);
67GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
68
69#endif /* CONFIG_X86_64 */
70
71#endif /* CONFIG_ARCH_RANDOM */
72
73#endif /* ASM_X86_ARCHRANDOM_H */