arch/x86: add functions to generate random numbers
Using x86 RDRAND instruction, two functions are supplied to generate a 32bit or 64bit number. One potential usage is the sealing key generation for SGX. BUG=chrome-os-partner:62438 BRANCH=NONE TEST=Tested on Eve to generate a 64bit random number. Change-Id: I50cbeda4de17ccf2fc5efc1fe04f6b1a31ec268c Signed-off-by: Robbie Zhang <robbie.zhang@intel.com> Reviewed-on: https://review.coreboot.org/18362 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
f296ce91b9
commit
18792314d7
|
@ -334,6 +334,7 @@ ramstage-$(CONFIG_GENERATE_MP_TABLE) += mpspec.c
|
|||
ramstage-y += pci_ops_conf1.c
|
||||
ramstage-$(CONFIG_MMCONF_SUPPORT) += pci_ops_mmconf.c
|
||||
ramstage-$(CONFIG_GENERATE_PIRQ_TABLE) += pirq_routing.c
|
||||
ramstage-y += rdrand.c
|
||||
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
|
||||
ramstage-y += tables.c
|
||||
ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2017 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that 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.
|
||||
*/
|
||||
|
||||
#include <random.h>
|
||||
#include <rules.h>
|
||||
|
||||
/*
|
||||
* Intel recommends that applications attempt 10 retries in a tight loop
|
||||
* in the unlikely event that the RDRAND instruction does not successfully
|
||||
* return a random number. The odds of ten failures in a row would in fact
|
||||
* be an indication of a larger CPU issue.
|
||||
*/
|
||||
#define RDRAND_RETRY_LOOPS 10
|
||||
|
||||
/*
|
||||
* Generate a 32-bit random number through RDRAND instruction.
|
||||
* Carry flag is set on RDRAND success and 0 on failure.
|
||||
*/
|
||||
static inline uint8_t rdrand_32(uint32_t *rand)
|
||||
{
|
||||
uint8_t carry;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
|
||||
: "=a" (*rand), "=qm" (carry));
|
||||
return carry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a 64-bit random number through RDRAND instruction.
|
||||
* Carry flag is set on RDRAND success and 0 on failure.
|
||||
*/
|
||||
static inline uint8_t rdrand_64(uint64_t *rand)
|
||||
{
|
||||
uint8_t carry;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".byte 0x48; .byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
|
||||
: "=a" (*rand), "=qm" (carry));
|
||||
return carry;
|
||||
}
|
||||
|
||||
int get_random_number_32(uint32_t *rand)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Perform a loop call until RDRAND succeeds or returns failure. */
|
||||
for (i = 0; i < RDRAND_RETRY_LOOPS; i++) {
|
||||
if (rdrand_32(rand))
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_random_number_64(uint64_t *rand)
|
||||
{
|
||||
int i;
|
||||
uint32_t rand_high, rand_low;
|
||||
|
||||
/* Perform a loop call until RDRAND succeeds or returns failure. */
|
||||
for (i = 0; i < RDRAND_RETRY_LOOPS; i++) {
|
||||
if (ENV_X86_64 && rdrand_64(rand))
|
||||
return 0;
|
||||
else if (rdrand_32(&rand_high) && rdrand_32(&rand_low)) {
|
||||
*rand = ((uint64_t)rand_high << 32) |
|
||||
(uint64_t)rand_low;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2017 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that 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.
|
||||
*/
|
||||
#ifndef _RANDOM_H_
|
||||
#define _RANDOM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Generates a 32/64 bit random number respectively.
|
||||
* return 0 on success and -1 on error.
|
||||
*/
|
||||
int get_random_number_32(uint32_t *rand);
|
||||
int get_random_number_64(uint64_t *rand);
|
||||
|
||||
#endif /* _RANDOM_H_ */
|
Loading…
Reference in New Issue