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/amd64/stand | |
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/amd64/stand')
-rw-r--r-- | sys/arch/amd64/stand/libsa/random_amd64.S | 34 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/random_i386.S | 32 |
2 files changed, 55 insertions, 11 deletions
diff --git a/sys/arch/amd64/stand/libsa/random_amd64.S b/sys/arch/amd64/stand/libsa/random_amd64.S index e347981da41..412a7e0b2b4 100644 --- a/sys/arch/amd64/stand/libsa/random_amd64.S +++ b/sys/arch/amd64/stand/libsa/random_amd64.S @@ -1,4 +1,4 @@ -/* $OpenBSD: random_amd64.S,v 1.3 2016/01/10 22:30:23 naddy Exp $ */ +/* $OpenBSD: random_amd64.S,v 1.4 2016/01/12 23:00:10 deraadt Exp $ */ /* * Copyright (c) 2013 Joel Sing <jsing@openbsd.org> @@ -23,7 +23,7 @@ /* * Random data is xored into the buffer in 8-byte blocks. If the buffer size - * is not a multiple of 8, the remaining bytes will be left untouched. + * is not a multiple of 8, the remaining bytes may be left untouched. */ ENTRY(mdrandom) pushq %rbx @@ -61,7 +61,6 @@ ENTRY(mdrandom) movq %rdi, %rbx movq %rsi, %rdx - shrq $3, %rdx xorq %rdi, %rdi and $CPUIDECX_RDRAND, %ecx // See if we have rdrand. @@ -74,17 +73,40 @@ ENTRY(mdrandom) jmp done userand: + shrq $3, %rdx // 8 bytes at a time +1: rdrand %rax xorq %rax, (%rbx, %rdi, 8) incq %rdi cmpq %rdi, %rdx - jne userand + jne 1b jmp done usetsc: rdtsc // Populates edx:eax. - mulq %rdx - xorq %rax, (%rbx, %rdi, 8) + + /* + * 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; + */ + shlq $1, %rdx + orq $1, %rdx + mull %edx + movq %rax, %rdx + shrq $8, %rdx + xorq %rdx, %rax + shrq $8, %rdx + xorq %rdx, %rax + shrq $8, %rdx + xorq %rdx, %rax + + xorb %al, (%rbx,%rdi) + incq %rdi cmpq %rdi, %rcx jne usetsc diff --git a/sys/arch/amd64/stand/libsa/random_i386.S b/sys/arch/amd64/stand/libsa/random_i386.S index de1023d480f..0dadbcc2107 100644 --- a/sys/arch/amd64/stand/libsa/random_i386.S +++ b/sys/arch/amd64/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:10 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 |