Blob Blame History Raw
From c9b15ea2afa25e34ec1a280cff3ad62862eba432 Mon Sep 17 00:00:00 2001
From: "Lee, Chun-Yi" <jlee@suse.com>
Date: Tue, 7 Jul 2015 10:11:39 +0800
Subject: [PATCH v2 03/16] x86/boot: Public getting random boot function

Patch-mainline: Not yet, reviewing on linux-efi
References: fate#316350

This patch moves the getting random boot function from aslr to misc
for later used by EFI stub to generate the first entropy of hmac key
for signing hibernate snapshot image.

Reviewed-by: Jiri Kosina <jkosina@suse.com>
Tested-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 arch/x86/boot/compressed/aslr.c |   13 ---------
 arch/x86/boot/compressed/misc.c |   54 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/boot/compressed/misc.h |    5 +++
 3 files changed, 60 insertions(+), 12 deletions(-)

--- a/arch/x86/boot/compressed/aslr.c
+++ b/arch/x86/boot/compressed/aslr.c
@@ -49,17 +49,6 @@ static unsigned long rotate_xor(unsigned
 	return hash;
 }
 
-/* Attempt to create a simple but unpredictable starting entropy. */
-static unsigned long get_random_boot(void)
-{
-	unsigned long hash = 0;
-
-	hash = rotate_xor(hash, build_str, sizeof(build_str));
-	hash = rotate_xor(hash, real_mode, sizeof(*real_mode));
-
-	return hash;
-}
-
 static unsigned long get_random_long(void)
 {
 #ifdef CONFIG_X86_64
@@ -67,7 +56,7 @@ static unsigned long get_random_long(voi
 #else
 	const unsigned long mix_const = 0x3f39e593UL;
 #endif
-	unsigned long raw, random = get_random_boot();
+	unsigned long raw, random = get_random_boot(real_mode);
 	bool use_i8254 = true;
 
 	debug_putstr("KASLR using");
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -12,6 +12,9 @@
 #include "misc.h"
 #include "../string.h"
 
+#include <generated/compile.h>
+#include <generated/utsrelease.h>
+
 /* WARNING!!
  * This code is compiled with -fPIC and it is relocated dynamically
  * at run time, but no relocation processing is performed.
@@ -460,3 +463,54 @@ asmlinkage __visible void *decompress_ke
 	debug_putstr("done.\nBooting the kernel.\n");
 	return output;
 }
+
+#if CONFIG_RANDOMIZE_BASE
+#define I8254_PORT_CONTROL     0x43
+#define I8254_PORT_COUNTER0    0x40
+#define I8254_CMD_READBACK     0xC0
+#define I8254_SELECT_COUNTER0  0x02
+#define I8254_STATUS_NOTREADY  0x40
+u16 read_i8254(void)
+{
+	u16 status, timer;
+
+	do {
+		outb(I8254_PORT_CONTROL,
+		     I8254_CMD_READBACK | I8254_SELECT_COUNTER0);
+		status = inb(I8254_PORT_COUNTER0);
+		timer  = inb(I8254_PORT_COUNTER0);
+		timer |= inb(I8254_PORT_COUNTER0) << 8;
+	} while (status & I8254_STATUS_NOTREADY);
+
+	return timer;
+}
+
+static unsigned long rotate_xor(unsigned long hash, const void *area,
+				size_t size)
+{
+	size_t i;
+	unsigned long *ptr = (unsigned long *)area;
+
+	for (i = 0; i < size / sizeof(hash); i++) {
+		/* Rotate by odd number of bits and XOR. */
+		hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7);
+		hash ^= ptr[i];
+	}
+
+	return hash;
+}
+
+static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
+		LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
+
+/* Attempt to create a simple but unpredictable starting entropy. */
+unsigned long get_random_boot(struct boot_params *boot_params)
+{
+	unsigned long hash = 0;
+
+	hash = rotate_xor(hash, build_str, sizeof(build_str));
+	hash = rotate_xor(hash, boot_params, sizeof(*boot_params));
+
+	return hash;
+}
+#endif /* CONFIG_RANDOMIZE_BASE */
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -96,4 +96,9 @@ static inline void console_init(void)
 { }
 #endif
 
+#if CONFIG_RANDOMIZE_BASE
+extern u16 read_i8254(void);
+extern unsigned long get_random_boot(struct boot_params *boot_params);
+#endif
+
 #endif