diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-01-12 23:00:14 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-01-12 23:00:14 +0000 |
commit | af48f9b620501a0a7cabdf0624a93cf744aa3c45 (patch) | |
tree | 3e698fa83e7cf6dc141c43938ffd08d524fe6043 /sys/arch/i386 | |
parent | e523ae58c252d4cf4a9eb4d38304005de713b3a2 (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.S | 32 |
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 |