[coreboot-gerrit] Patch set updated for coreboot: arch/x86: add library function for coreboot to generate random number using x86 RDRAND instruction.

Robbie Zhang (robbie.zhang@intel.com) gerrit at coreboot.org
Tue Feb 14 04:10:09 CET 2017


Robbie Zhang (robbie.zhang at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18362

-gerrit

commit 7b8aea595a32a2a26322224f7c3004bb37db96d3
Author: Robbie Zhang <robbie.zhang at intel.com>
Date:   Mon Feb 13 13:44:14 2017 -0800

    arch/x86: add library function for coreboot to generate random number
    using x86 RDRAND instruction.
    
    Two functions are supplied to generate 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 at intel.com>
---
 src/arch/x86/Makefile.inc          |  1 +
 src/arch/x86/include/arch/rdrand.h | 27 ++++++++++++++
 src/arch/x86/rdrand.c              | 76 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)

diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index c4bb1cc..332e8ec 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -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
diff --git a/src/arch/x86/include/arch/rdrand.h b/src/arch/x86/include/arch/rdrand.h
new file mode 100644
index 0000000..74166d9
--- /dev/null
+++ b/src/arch/x86/include/arch/rdrand.h
@@ -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 ARCH_RDRAND_H
+#define ARCH_RDRAND_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 /* ARCH_RDRAND_H */
diff --git a/src/arch/x86/rdrand.c b/src/arch/x86/rdrand.c
new file mode 100644
index 0000000..9f7ed81
--- /dev/null
+++ b/src/arch/x86/rdrand.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <arch/rdrand.h>
+
+#define RDRAND_RETRY_LOOPS 10
+
+/* Generate a 32-bit random number through RDRAND instruction. */
+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;
+}
+
+#ifdef __x86_64__
+/* Generate a 64-bit random number through RDRAND instruction. */
+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;
+}
+#endif
+
+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;
+#ifndef __x86_64__
+	uint32_t rand_high, rand_low;
+#endif
+
+	/* Perform a loop call until RDRAND succeeds or returns failure. */
+	for (i = 0; i < RDRAND_RETRY_LOOPS; i++) {
+#ifdef __x86_64__
+		if (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;
+		}
+#endif
+	}
+	return -1;
+}



More information about the coreboot-gerrit mailing list