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>
2011-07-31 20:59:29 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the Linux kernel.
|
|
|
|
*
|
2014-03-17 23:36:27 +00:00
|
|
|
* Copyright (c) 2011-2014, Intel Corporation
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
* Authors: Fenghua Yu <fenghua.yu@intel.com>,
|
|
|
|
* H. Peter Anvin <hpa@linux.intel.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef ASM_X86_ARCHRANDOM_H
|
|
|
|
#define ASM_X86_ARCHRANDOM_H
|
|
|
|
|
|
|
|
#include <asm/processor.h>
|
|
|
|
#include <asm/cpufeature.h>
|
|
|
|
|
|
|
|
#define RDRAND_RETRY_LOOPS 10
|
|
|
|
|
|
|
|
#define RDRAND_INT ".byte 0x0f,0xc7,0xf0"
|
2014-03-17 23:36:27 +00:00
|
|
|
#define RDSEED_INT ".byte 0x0f,0xc7,0xf8"
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0"
|
2014-03-17 23:36:27 +00:00
|
|
|
# define RDSEED_LONG ".byte 0x48,0x0f,0xc7,0xf8"
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
#else
|
|
|
|
# define RDRAND_LONG RDRAND_INT
|
2014-03-17 23:36:27 +00:00
|
|
|
# define RDSEED_LONG RDSEED_INT
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
#endif
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
/* Unconditional execution of RDRAND and RDSEED */
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
|
2016-06-08 19:38:38 +00:00
|
|
|
static inline bool rdrand_long(unsigned long *v)
|
2013-10-11 00:18:15 +00:00
|
|
|
{
|
2016-06-08 19:38:46 +00:00
|
|
|
bool ok;
|
|
|
|
unsigned int retry = RDRAND_RETRY_LOOPS;
|
|
|
|
do {
|
2017-09-06 15:18:08 +00:00
|
|
|
asm volatile(RDRAND_LONG
|
2016-06-08 19:38:46 +00:00
|
|
|
CC_SET(c)
|
|
|
|
: CC_OUT(c) (ok), "=a" (*v));
|
|
|
|
if (ok)
|
|
|
|
return true;
|
|
|
|
} while (--retry);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool rdrand_int(unsigned int *v)
|
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
unsigned int retry = RDRAND_RETRY_LOOPS;
|
|
|
|
do {
|
2017-09-06 15:18:08 +00:00
|
|
|
asm volatile(RDRAND_INT
|
2016-06-08 19:38:46 +00:00
|
|
|
CC_SET(c)
|
|
|
|
: CC_OUT(c) (ok), "=a" (*v));
|
|
|
|
if (ok)
|
|
|
|
return true;
|
|
|
|
} while (--retry);
|
|
|
|
return false;
|
2013-10-11 00:18:15 +00:00
|
|
|
}
|
|
|
|
|
2014-03-17 23:36:27 +00:00
|
|
|
static inline bool rdseed_long(unsigned long *v)
|
|
|
|
{
|
2016-06-08 19:38:38 +00:00
|
|
|
bool ok;
|
2017-09-06 15:18:08 +00:00
|
|
|
asm volatile(RDSEED_LONG
|
2016-06-08 19:38:46 +00:00
|
|
|
CC_SET(c)
|
|
|
|
: CC_OUT(c) (ok), "=a" (*v));
|
2014-03-17 23:36:27 +00:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
static inline bool rdseed_int(unsigned int *v)
|
|
|
|
{
|
|
|
|
bool ok;
|
2017-09-06 15:18:08 +00:00
|
|
|
asm volatile(RDSEED_INT
|
2016-06-08 19:38:46 +00:00
|
|
|
CC_SET(c)
|
|
|
|
: CC_OUT(c) (ok), "=a" (*v));
|
|
|
|
return ok;
|
2014-03-17 23:36:27 +00:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
/* Conditional execution based on CPU type */
|
2014-03-17 23:36:30 +00:00
|
|
|
#define arch_has_random() static_cpu_has(X86_FEATURE_RDRAND)
|
|
|
|
#define arch_has_random_seed() static_cpu_has(X86_FEATURE_RDSEED)
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
/*
|
|
|
|
* These are the generic interfaces; they must not be declared if the
|
|
|
|
* stubs in <linux/random.h> are to be invoked,
|
|
|
|
* i.e. CONFIG_ARCH_RANDOM is not defined.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_ARCH_RANDOM
|
2013-10-11 00:18:15 +00:00
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
static inline bool arch_get_random_long(unsigned long *v)
|
2013-10-11 00:18:15 +00:00
|
|
|
{
|
2016-06-08 19:38:46 +00:00
|
|
|
return arch_has_random() ? rdrand_long(v) : false;
|
2013-10-11 00:18:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
static inline bool arch_get_random_int(unsigned int *v)
|
2014-03-17 23:36:27 +00:00
|
|
|
{
|
2016-06-08 19:38:46 +00:00
|
|
|
return arch_has_random() ? rdrand_int(v) : false;
|
2014-03-17 23:36:27 +00:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
static inline bool arch_get_random_seed_long(unsigned long *v)
|
|
|
|
{
|
|
|
|
return arch_has_random_seed() ? rdseed_long(v) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool arch_get_random_seed_int(unsigned int *v)
|
|
|
|
{
|
|
|
|
return arch_has_random_seed() ? rdseed_int(v) : false;
|
|
|
|
}
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
|
2011-07-31 21:02:19 +00:00
|
|
|
extern void x86_init_rdrand(struct cpuinfo_x86 *c);
|
|
|
|
|
2016-06-08 19:38:46 +00:00
|
|
|
#else /* !CONFIG_ARCH_RANDOM */
|
|
|
|
|
|
|
|
static inline void x86_init_rdrand(struct cpuinfo_x86 *c) { }
|
|
|
|
|
|
|
|
#endif /* !CONFIG_ARCH_RANDOM */
|
|
|
|
|
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>
2011-07-31 20:59:29 +00:00
|
|
|
#endif /* ASM_X86_ARCHRANDOM_H */
|