[ANNOUNCEMENT] New package: rng-tools-5-1

Corinna Vinschen corinna-cygwin@cygwin.com
Tue Aug 12 14:11:00 GMT 2014


Hi Peter,

On Aug 12 15:29, Peter Rosin wrote:
> On 2014-08-09 16:37, Corinna Vinschen wrote:
> > I just uploaded rng-tools-5-1.
> > 
> > The Cygwin release only comes with the rngtest tool for now.
> > 
> > The rngd daemon requires porting assembler code to COFF and the
> > Microsoft calling convention.  Any help porting this code would
> > be greatly appreciated.
> 
> Ok, I took a stab at it. The problems I identified in the assembly
> are ELF debug info, different register use for the x86-64 calls and
> a missing underscore prefix for the i686 symbols.
> 
> I'm unsure if used registers (and which) have to be saved in the
> MS x86-64 ABI, but that shouldn't be too hard to fix if that's the
> case.
> 
> I also moved up the AC_SEARCH_LIBS hunk in configure.ac since
> the existing AC_CHECK_LIB is buried inside some other construct
> (AC_CHECK_HEADER is possibly the culprit) which causes this:
> 
> checking for library containing argp_parse... /usr/src/rng-tools-5-1.src/rng-tools-5-1.i686/src/rng-tools-5/configure: line 4335: ac_fn_c_try_link: command not found
> /usr/src/rng-tools-5-1.src/rng-tools-5-1.i686/src/rng-tools-5/configure: line 4335: ac_fn_c_try_link: command not found
> no
> 
> Anyway, with the attached patch instead of the one included in the
> src package, it builds for both arches, but my cpu appears to lack
> the rdrand instruction, so I have a hard time taking this any
> further.   Bummer.

Thanks for your efforts!  Over the weekend I tried my own port.  I opted
for creating a new file, rdrand_win_asm.S (attached for reference) to
keep the code a bit cleaner.

I have a machine which supports the rdrand call, but you need at least
an Ivy Bridge CPU,  For rdseed you need at least Haswell.

Ultimately I gave up on rngd for now, for four reasons:

- rngd uses poll(2) on /dev/random to wait until /dev/random becomes
  writable.  /dev/random on Cygwin is always writable (we're not
  controlling the entropy pool, the OS does, and the RtlGenRandom call
  never blocks).  This results in 100% CPU usage.

- Even then, using rngd on /dev/random gave *worse* results when
  testing /dev/random with rngtest :-P   I'm not sure why.

- Cygwin does not support any of the other three hardware entropy
  sources /dev/hwrng or /dev/tpm0.  For Intel/AMD hwrng you'd need
  access to the PCI bus and certain chipsets.  For tpm0 you'd
  need a TPM chip and a description how to access the chip for
  producing random numbers.  The chip is supposedly available as
  cryptographic provider under Windows, but on the only machine 
  in our home with a TPM chip *and* a functional Windows driver,
  there was no matching cryptographic provider returned by the call
  to CryptEnumProviders.

- Given that, and given the hardware constraints for the rdrand and
  rdseed calls, I decided that it's not worth to follow through with
  this stuff.

Still, thanks a lot for working on that.  I appreciate it.  If you
have any idea how Cygwin could provide /dev/hwrng or /dev/tpm0 to
have at least two HW entropy sources, please feel free to discuss 
this on the cygwin-developer's list.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
/*
 * Copyright (c) 2011-2014, Intel Corporation
 * Authors: Fenghua Yu <fenghua.yu@intel.com>,
 *          H. Peter Anvin <hpa@linux.intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

/*
 * This is the Windows version of the file.  It's equivalent to the original
 * code from Intel, just replacing ELF with COFF pseudo code expressions
 * where necessary and using Windows ABI rather than System V ABI on x86_64.
 * Additionally it utilizes the fact that recent versions of gas know the
 * rdrand, rdseed, and aes opcodes to avoid opaque .byte expression.
 */

#if defined(__i386__) || defined(__x86_64__)

#ifdef __x86_64__
#define LBL(x)	x
#else
#define LBL(x)	_##x
#endif

#define ENTRY(x)	  \
	.align	8	; \
	.globl	LBL(x)	; \
	.def	LBL(x)	; \
	.scl	2	; \
	.type	32	; \
	.endef		; \
LBL(x):

#define ENDPROC(x)

#define RDRAND_RETRY_LIMIT	10

#ifdef __x86_64__

ENTRY(x86_rdrand_bytes)
	mov	%edx, %eax
1:
	mov	$RDRAND_RETRY_LIMIT, %r9d
2:
	rdrand	%r10
	jnc	3f
	mov	%r10, (%rcx)
	add	$8, %rcx
	sub	$8, %edx
	ja	1b
4:
	sub	%edx, %eax
	ret
3:
	dec	%r9d
	rep;nop
	jnz	2b
	jmp	4b
ENDPROC(x86_rdrand_bytes)

ENTRY(x86_rdseed_or_rdrand_bytes)
	push	%r12
	push	%r13
	mov	(%rdx), %r12d		/* RDSEED count */
	mov	(%r9), %r13d		/* RDRAND count */
1:
	mov	$RDRAND_RETRY_LIMIT, %r10d
2:
	rdrand	%rax
	jnc	3f
	mov	%rax, (%rcx)
	add	$8, %rcx
	sub	$8, %r12d
	ja	1b
4:
	sub	%r12d, (%rdx)
	sub	%r13d, (%r9)
	pop	%r13
	pop	%r12
	ret
3:
	rdrand	%rax
	jnc	5f
	mov	%rax, (%r8)
	add	$8, %r8
	sub	$8, %r13d
	ja	1b
	jmp	4b
5:
	dec	%r10d
	rep;nop
	jnz	2b
	jmp	4b
ENDPROC(x86_rdseed_or_rdrand_bytes)

#define SETPTR(var,ptr)	leaq var(%rip),ptr
#define PTR0	%rcx
#define PTR1	%rdx
#define PTR2	%r9
#define CTR3	%eax
#define NPTR2	1	/* %rcx = %r1, only 0-7 valid here */

#elif defined(__i386__)

ENTRY(x86_rdrand_bytes)
	push	%ebp
	mov	%esp, %ebp
	push	%edi
	push	%esi
	movl	8(%ebp), %edi
	movl	12(%ebp), %esi

	mov	%esi, %eax
1:
	mov	$RDRAND_RETRY_LIMIT, %ecx
2:
	rdrand	%edx
	jnc	3f
	mov	%edx, (%edi)
	add	$4, %edi
	sub	$4, %esi
	ja	1b
4:
	sub	%esi, %eax
	pop	%esi
	pop	%edi
	pop	%ebp
	ret
3:
	dec	%ecx
	rep;nop
	jnz	2b
	jmp	4b
ENDPROC(x86_rdrand_bytes)


ENTRY(x86_rdseed_or_rdrand_bytes)
	push	%ebp
	mov	%esp, %ebp
	push	%edi
	push	%esi
	push	%ebx

	mov	12(%ebp), %ebx
	mov	20(%ebp), %esi
	mov	8(%ebp), %edi		/* RDSEED pointer */
	mov	16(%ebp), %edx		/* RDRAND pointer */
	mov	(%ebx), %ebx		/* RDSEED count */
	mov	(%esi), %esi		/* RDRAND count */
1:
	mov	$RDRAND_RETRY_LIMIT, %ecx
2:
	rdseed	%eax
	jnc	3f
	mov	%eax, (%edi)
	add	$4, %edi
	sub	$4, %ebx
	ja	1b
4:
	mov	12(%ebp), %edx
	mov	20(%ebp), %eax
	sub	%ebx, (%edx)		/* RDSEED count */
	sub	%esi, (%eax)		/* RDRAND count */

	pop	%ebx
	pop	%esi
	pop	%edi
	pop	%ebp
	ret
3:
	rdrand	%eax
	jnc	5f
	mov	%eax, (%edx)
	add	$4, %edx
	sub	$4, %esi
	jnz	1b
	ja	4b
5:
	dec	%ecx
	rep;nop
	jnz	2b
	jmp	4b
ENDPROC(x86_rdseed_or_rdrand_bytes)

#define SETPTR(var,ptr)	movl $(var),ptr
#define PTR0	%eax
#define PTR1	%edx
#define PTR2	%ecx
#define CTR3	%esi
#define NPTR2	1	/* %rcx = %r1 */

#endif

ENTRY(x86_aes_mangle)
#ifdef __i386__
	push	%ebp
	mov	%esp, %ebp
	movl	8(%ebp), %eax
	movl	12(%ebp), %edx
	push	%esi
#endif
	movl	$512, CTR3	/* Number of rounds */
	
	movdqa	(0*16)(PTR1), %xmm0
	movdqa	(1*16)(PTR1), %xmm1
	movdqa	(2*16)(PTR1), %xmm2
	movdqa	(3*16)(PTR1), %xmm3
	movdqa	(4*16)(PTR1), %xmm4
	movdqa	(5*16)(PTR1), %xmm5
	movdqa	(6*16)(PTR1), %xmm6
	movdqa	(7*16)(PTR1), %xmm7

#ifdef __x86_64__
	SETPTR(aes_round_keys, PTR2)
1:
#else
1:
	SETPTR(aes_round_keys, PTR2)
#endif

	/* 8192 = 512 (rounds) * 16 (bytes) */
	pxor	(0*8192)(PTR0), %xmm0
	pxor	(1*8192)(PTR0), %xmm1
	pxor	(2*8192)(PTR0), %xmm2
	pxor	(3*8192)(PTR0), %xmm3
	pxor	(4*8192)(PTR0), %xmm4
	pxor	(5*8192)(PTR0), %xmm5
	pxor	(6*8192)(PTR0), %xmm6
	pxor	(7*8192)(PTR0), %xmm7
	add	$16, PTR0

offset = 0
	.rept 10
#ifdef __x86_64__
	movdqa	offset(PTR2), %xmm8
offset = offset + 16
	aesenc %xmm8, %xmm0
	aesenc %xmm8, %xmm1
	aesenc %xmm8, %xmm2
	aesenc %xmm8, %xmm3
	aesenc %xmm8, %xmm4
	aesenc %xmm8, %xmm5
	aesenc %xmm8, %xmm6
	aesenc %xmm8, %xmm7
#else
	aesenc (PTR2), %xmm0
	aesenc (PTR2), %xmm1
	aesenc (PTR2), %xmm2
	aesenc (PTR2), %xmm3
	aesenc (PTR2), %xmm4
	aesenc (PTR2), %xmm5
	aesenc (PTR2), %xmm6
	aesenc (PTR2), %xmm7
	add	$16, PTR2
#endif
	.endr

#ifdef __x86_64__
	movdqa	offset(PTR2), %xmm8
	aesenclast %xmm8, %xmm0
	aesenclast %xmm8, %xmm1
	aesenclast %xmm8, %xmm2
	aesenclast %xmm8, %xmm3
	aesenclast %xmm8, %xmm4
	aesenclast %xmm8, %xmm5
	aesenclast %xmm8, %xmm6
	aesenclast %xmm8, %xmm7
#else
	aesenclast (PTR2), %xmm0
	aesenclast (PTR2), %xmm1
	aesenclast (PTR2), %xmm2
	aesenclast (PTR2), %xmm3
	aesenclast (PTR2), %xmm4
	aesenclast (PTR2), %xmm5
	aesenclast (PTR2), %xmm6
	aesenclast (PTR2), %xmm7
#endif
	sub	$1, CTR3
	jnz	1b
	
	movdqa	%xmm0, (0*16)(PTR1)
	movdqa	%xmm1, (1*16)(PTR1)
	movdqa	%xmm2, (2*16)(PTR1)
	movdqa	%xmm3, (3*16)(PTR1)
	movdqa	%xmm4, (4*16)(PTR1)
	movdqa	%xmm5, (5*16)(PTR1)
	movdqa	%xmm6, (6*16)(PTR1)
	movdqa	%xmm7, (7*16)(PTR1)

#ifdef __i386__
	pop	%esi
	pop	%ebp
#endif
	ret
ENDPROC(x86_aes_mangle)

ENTRY(x86_aes_expand_key)
#ifdef __i386__
	push	%ebp
	mov	%esp, %ebp
	movl	8(%ebp), %eax
#endif

	SETPTR(aes_round_keys, PTR1)
	movdqu	(PTR0), %xmm0
	movdqa	%xmm0, (PTR1)	/* First slot = the plain key */
	add	$16, PTR1

	aeskeygenassist $0x01,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x02,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x04,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x08,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x10,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x20,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x40,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x80,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x1b,%xmm0,%xmm1
	call	1f
	aeskeygenassist $0x36,%xmm0,%xmm1
	call	1f

#ifdef __i386__
	pop	%ebp
#endif
	ret

1:
	pshufd	$0xff, %xmm1, %xmm1
	movdqa	%xmm0, %xmm2
	pslldq	$4, %xmm2
	pxor	%xmm2, %xmm0
	pslldq	$4, %xmm2
	pxor	%xmm2, %xmm0
	pslldq	$4, %xmm2
	pxor	%xmm2, %xmm0
	pxor	%xmm1, %xmm0
	movdqa	%xmm0, (PTR1)
	add	$16, PTR1
	ret

ENDPROC(x86_aes_expand_key)

	.bss
	.balign 64
aes_round_keys:
	.space	11*16

#endif /* i386 or x86_64 */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20140812/56cb30e2/attachment.sig>


More information about the Cygwin mailing list