summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2016-01-12 23:00:14 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2016-01-12 23:00:14 +0000
commitaf48f9b620501a0a7cabdf0624a93cf744aa3c45 (patch)
tree3e698fa83e7cf6dc141c43938ffd08d524fe6043 /sys/arch/i386
parente523ae58c252d4cf4a9eb4d38304005de713b3a2 (diff)
naddy observed the TSC fallback code could encounter (high word) %edx
being 0; after multiply there is no perturbance to the from-disk entropy buffer. Further investigation showed perturbance was biased towards the lower bytes of a word. Compensate for this with a hocus pocus bit-spreading operation which applies a result byte by byte. discussion with kettenis, tb, mlarkin, naddy ok naddy
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/stand/libsa/random_i386.S32
1 files changed, 27 insertions, 5 deletions
diff --git a/sys/arch/i386/stand/libsa/random_i386.S b/sys/arch/i386/stand/libsa/random_i386.S
index de1023d480f..56ad3864e13 100644
--- a/sys/arch/i386/stand/libsa/random_i386.S
+++ b/sys/arch/i386/stand/libsa/random_i386.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: random_i386.S,v 1.8 2016/01/10 22:30:23 naddy Exp $ */
+/* $OpenBSD: random_i386.S,v 1.9 2016/01/12 23:00:13 deraadt Exp $ */
/*
* Copyright (c) 2013 Joel Sing <jsing@openbsd.org>
@@ -23,7 +23,7 @@
/*
* Random data is xored into the buffer in 4 byte blocks. If the buffer size
- * is not a multiple of 4, the remaining bytes will be left untouched.
+ * is not a multiple of 4, the remaining bytes may be left untouched.
*/
ENTRY(mdrandom)
pushal
@@ -61,7 +61,6 @@ ENTRY(mdrandom)
movl 36(%esp), %ebx
movl 40(%esp), %edx
- shrl $2, %edx
xorl %edi, %edi
andl $CPUIDECX_RDRAND, %ecx // See if we have rdrand.
@@ -74,17 +73,40 @@ ENTRY(mdrandom)
jmp done
userand:
+ shrl $2, %edx // 4 bytes at a time
+1:
rdrand %eax
xorl %eax, (%ebx,%edi,4)
incl %edi
cmpl %edi, %edx
- jne userand
+ jne 1b
jmp done
usetsc:
rdtsc // Populates edx:eax.
+
+ /*
+ * Cope with high=0
+ * high = (high << 1) | 1;
+ * Spread bits
+ * bits = low * high;
+ * Accumulate spread bits into a byte
+ * bits = bits ^ (bits>>8) ^ (bits>>16) ^ (bits>>24);
+ * buf[i] ^= (u_char) bits;
+ */
+ shll $1, %edx
+ orl $1, %edx
mull %edx
- xorl %eax, (%ebx,%edi,4)
+ movl %eax, %edx
+ shrl $8, %edx
+ xorl %edx, %eax
+ shrl $8, %edx
+ xorl %edx, %eax
+ shrl $8, %edx
+ xorl %edx, %eax
+
+ xorb %al, (%ebx,%edi)
+
incl %edi
cmpl %edi, %ecx
jne usetsc