Calls to `MASM_RDSEED_GenerateBlock` would hang for an unknown reasons on Windows 10 and VS2017/VS2019 toolchains. Similar calls to `MASM_RDRAND_GenerateBlock` worked as expected. They were effectively the same code. The only differences were the function names and the opcodes (they were literally copy/paste). Splitting `rdrand.asm` (with both `RDRAND` and `RDSEED`) into `rdrand.asm` (with `RDRAND`) and `rdseed.asm` (with `RDSEED`) resolved the issue. We don't know why.pull/877/head
parent
e5ab7919f9
commit
b1c691b53a
|
|
@ -118,7 +118,7 @@ LIB_OBJS = \
|
||||||
zdeflate.obj zinflate.obj zlib.obj
|
zdeflate.obj zinflate.obj zlib.obj
|
||||||
|
|
||||||
ASM_OBJS = \
|
ASM_OBJS = \
|
||||||
rdrand-x86.obj rdrand-x64.obj x64masm.obj x64dll.obj
|
rdrand-x86.obj rdrand-x64.obj rdseed-x86.obj rdseed-x64.obj x64masm.obj x64dll.obj
|
||||||
|
|
||||||
TEST_SRCS = \
|
TEST_SRCS = \
|
||||||
test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \
|
test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \
|
||||||
|
|
@ -196,10 +196,12 @@ PLATFORM = x64
|
||||||
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||||
AS = ml.exe
|
AS = ml.exe
|
||||||
ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh
|
ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh
|
||||||
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm
|
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
|
||||||
LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj
|
LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj rdseed-x86.obj
|
||||||
LDFLAGS = $(LDFLAGS) /MACHINE:X86
|
LDFLAGS = $(LDFLAGS) /MACHINE:X86
|
||||||
LDLIBS = $(LDLIBS) kernel32.lib
|
LDLIBS = $(LDLIBS) kernel32.lib
|
||||||
|
RDRAND_OBJ = rdrand-x86.obj
|
||||||
|
RDSEED_OBJ = rdseed-x86.obj
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# May need $(VCINSTALLDIR)\bin\amd64\ml64.exe
|
# May need $(VCINSTALLDIR)\bin\amd64\ml64.exe
|
||||||
|
|
@ -209,10 +211,12 @@ LDLIBS = $(LDLIBS) kernel32.lib
|
||||||
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
|
||||||
AS = ml64.exe
|
AS = ml64.exe
|
||||||
ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi
|
ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi
|
||||||
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm
|
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
|
||||||
LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj x64masm.obj x64dll.obj
|
LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj rdseed-x64.obj x64masm.obj x64dll.obj
|
||||||
LDFLAGS = $(LDFLAGS) /MACHINE:X64
|
LDFLAGS = $(LDFLAGS) /MACHINE:X64
|
||||||
LDLIBS = $(LDLIBS) kernel32.lib
|
LDLIBS = $(LDLIBS) kernel32.lib
|
||||||
|
RDRAND_OBJ = rdrand-x64.obj
|
||||||
|
RDSEED_OBJ = rdseed-x64.obj
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64"
|
!IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64"
|
||||||
|
|
@ -283,21 +287,25 @@ pch.pch: pch.h pch.cpp
|
||||||
$(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp
|
$(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp
|
||||||
|
|
||||||
# No precompiled headers
|
# No precompiled headers
|
||||||
iterhash.obj:
|
iterhash.obj: iterhash.h iterhash.cpp
|
||||||
$(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp
|
$(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp
|
||||||
dll.obj:
|
dll.obj: dll.h dll.cpp
|
||||||
$(CXX) $(CXXFLAGS) /Y- /c dll.cpp
|
$(CXX) $(CXXFLAGS) /Y- /c dll.cpp
|
||||||
rdrand.obj:
|
rdrand.obj: rdrand.h rdrand.cpp
|
||||||
$(CXX) $(CXXFLAGS) /c rdrand.cpp
|
$(CXX) $(CXXFLAGS) /c rdrand.cpp
|
||||||
|
|
||||||
# Built for x86/x64
|
# Built for x86/x64
|
||||||
rdrand-x86.obj:
|
rdrand-x86.obj: rdrand.asm
|
||||||
$(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm
|
$(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm
|
||||||
rdrand-x64.obj:
|
rdrand-x64.obj: rdrand.asm
|
||||||
$(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm
|
$(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm
|
||||||
x64masm.obj:
|
rdseed-x86.obj: rdseed.asm
|
||||||
|
$(AS) $(ASFLAGS) /Fo rdseed-x86.obj /c rdseed.asm
|
||||||
|
rdseed-x64.obj: rdseed.asm
|
||||||
|
$(AS) $(ASFLAGS) /Fo rdseed-x64.obj /c rdseed.asm
|
||||||
|
x64masm.obj: x64masm.asm
|
||||||
$(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm
|
$(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm
|
||||||
x64dll.obj:
|
x64dll.obj: x64dll.asm
|
||||||
$(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm
|
$(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm
|
||||||
|
|
||||||
# You may need to delete this on early versions of Visual Studio.
|
# You may need to delete this on early versions of Visual Studio.
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,16 @@
|
||||||
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdrand-x64.obj" "%(FullPath)"</Command>
|
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdrand-x64.obj" "%(FullPath)"</Command>
|
||||||
<Outputs>$(IntDir)\rdrand-x64.obj;%(Outputs)</Outputs>
|
<Outputs>$(IntDir)\rdrand-x64.obj;%(Outputs)</Outputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Condition="'$(Platform)'=='Win32'" Include="rdseed.asm">
|
||||||
|
<Message>Building and assembling rdseed.asm</Message>
|
||||||
|
<Command>ml.exe /c /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo"$(IntDir)rdseed-x86.obj" "%(FullPath)"</Command>
|
||||||
|
<Outputs>$(IntDir)\rdseed-x86.obj;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Condition="'$(Platform)'=='x64'" Include="rdseed.asm">
|
||||||
|
<Message>Building and assembling rdseed.asm</Message>
|
||||||
|
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdseed-x64.obj" "%(FullPath)"</Command>
|
||||||
|
<Outputs>$(IntDir)\rdseed-x64.obj;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
<CustomBuild Condition="'$(Platform)'=='x64' AND ('$(Configuration)'=='Debug' Or '$(Configuration)'=='Release')" Include="x64dll.asm">
|
<CustomBuild Condition="'$(Platform)'=='x64' AND ('$(Configuration)'=='Debug' Or '$(Configuration)'=='Release')" Include="x64dll.asm">
|
||||||
<Message>Building and assembling x64dll.asm</Message>
|
<Message>Building and assembling x64dll.asm</Message>
|
||||||
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Zi /Fo"$(IntDir)x64dll.obj" "%(FullPath)"</Command>
|
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Zi /Fo"$(IntDir)x64dll.obj" "%(FullPath)"</Command>
|
||||||
|
|
|
||||||
|
|
@ -1064,6 +1064,9 @@
|
||||||
<CustomBuild Include="rdrand.asm">
|
<CustomBuild Include="rdrand.asm">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rdseed.asm">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
<CustomBuild Include="x64dll.asm">
|
<CustomBuild Include="x64dll.asm">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
|
|
||||||
208
rdrand.asm
208
rdrand.asm
|
|
@ -1,9 +1,9 @@
|
||||||
;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
|
;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
|
||||||
;; Copyright assigned to the Crypto++ project.
|
;; Copyright assigned to the Crypto++ project.
|
||||||
|
|
||||||
;; This ASM file provides RDRAND and RDSEED to downlevel Microsoft tool chains.
|
;; This ASM file provides RDRAND to downlevel Microsoft tool chains.
|
||||||
;; Everything "just works" under Visual Studio. Other platforms will have to
|
;; Everything "just works" under Visual Studio. Other platforms will
|
||||||
;; run MASM/MASM-64 and then link to the object files.
|
;; have to run MASM/MASM-64 and then link to the object files.
|
||||||
|
|
||||||
;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh
|
;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh
|
||||||
;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi
|
;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi
|
||||||
|
|
@ -13,11 +13,10 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
TITLE MASM_RDRAND_GenerateBlock and MASM_RDSEED_GenerateBlock
|
TITLE MASM_RDRAND_GenerateBlock source file
|
||||||
SUBTITLE Microsoft specific ASM code to utilize RDRAND and RDSEED for down level Microsoft toolchains
|
SUBTITLE Microsoft specific ASM code to utilize RDRAND for down level Microsoft toolchains
|
||||||
|
|
||||||
PUBLIC MASM_RDRAND_GenerateBlock
|
PUBLIC MASM_RDRAND_GenerateBlock
|
||||||
PUBLIC MASM_RDSEED_GenerateBlock
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
@ -38,7 +37,6 @@ IFDEF _M_X86 ;; Set via the command line
|
||||||
|
|
||||||
;; Fastcall calling conventions exports
|
;; Fastcall calling conventions exports
|
||||||
ALIAS <@MASM_RDRAND_GenerateBlock@8> = <MASM_RDRAND_GenerateBlock>
|
ALIAS <@MASM_RDRAND_GenerateBlock@8> = <MASM_RDRAND_GenerateBlock>
|
||||||
ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock>
|
|
||||||
|
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
|
|
@ -125,10 +123,10 @@ RDRAND_GenerateBlock_Return:
|
||||||
|
|
||||||
MASM_RDRAND_GenerateBlock ENDP
|
MASM_RDRAND_GenerateBlock ENDP
|
||||||
|
|
||||||
ENDIF ;; _M_X86
|
;; OPTION PROLOGUE:PrologueDef
|
||||||
|
;; OPTION EPILOGUE:EpilogueDef
|
||||||
|
|
||||||
OPTION PROLOGUE:PrologueDef
|
ENDIF ;; _M_X86
|
||||||
OPTION EPILOGUE:EpilogueDef
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
@ -223,197 +221,11 @@ RDRAND_GenerateBlock_Return:
|
||||||
|
|
||||||
MASM_RDRAND_GenerateBlock ENDP
|
MASM_RDRAND_GenerateBlock ENDP
|
||||||
|
|
||||||
ENDIF ;; _M_X64
|
;; OPTION PROLOGUE:PrologueDef
|
||||||
|
;; OPTION EPILOGUE:EpilogueDef
|
||||||
OPTION PROLOGUE:PrologueDef
|
|
||||||
OPTION EPILOGUE:EpilogueDef
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
IFDEF _M_X86 ;; Set via the command line
|
|
||||||
|
|
||||||
.CODE
|
|
||||||
ALIGN 8
|
|
||||||
OPTION PROLOGUE:NONE
|
|
||||||
OPTION EPILOGUE:NONE
|
|
||||||
|
|
||||||
;; No need for Load_Arguments due to fastcall
|
|
||||||
;; ECX (in): arg1, byte* buffer
|
|
||||||
;; EDX (in): arg2, size_t bsize
|
|
||||||
|
|
||||||
MASM_RDSEED_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD
|
|
||||||
|
|
||||||
MWSIZE EQU 04h ;; machine word size
|
|
||||||
buffer EQU ecx
|
|
||||||
bsize EQU edx
|
|
||||||
|
|
||||||
;; Top of While loop
|
|
||||||
RDSEED_GenerateBlock_Top:
|
|
||||||
|
|
||||||
;; Check remaining size
|
|
||||||
cmp bsize, 0
|
|
||||||
je RDSEED_GenerateBlock_Return
|
|
||||||
|
|
||||||
RDSEED_Call_EAX:
|
|
||||||
;; RDSEED is not available prior to VS2012. Just emit
|
|
||||||
;; the byte codes using DB. This is `rdseed eax`.
|
|
||||||
DB 0Fh, 0C7h, 0F8h
|
|
||||||
|
|
||||||
;; If CF=1, the number returned by RDSEED is valid.
|
|
||||||
;; If CF=0, a random number was not available.
|
|
||||||
|
|
||||||
;; Retry immediately
|
|
||||||
jnc RDSEED_Call_EAX
|
|
||||||
|
|
||||||
RDSEED_succeeded:
|
|
||||||
|
|
||||||
cmp bsize, MWSIZE
|
|
||||||
jb RDSEED_Partial_Machine_Word
|
|
||||||
|
|
||||||
RDSEED_Full_Machine_Word:
|
|
||||||
|
|
||||||
mov DWORD PTR [buffer], eax
|
|
||||||
add buffer, MWSIZE ;; No need for Intel Core 2 slow workarounds, like
|
|
||||||
sub bsize, MWSIZE ;; `lea buffer,[buffer+MWSIZE]` for faster adds
|
|
||||||
|
|
||||||
;; Continue
|
|
||||||
jmp RDSEED_GenerateBlock_Top
|
|
||||||
|
|
||||||
;; 1,2,3 bytes remain
|
|
||||||
RDSEED_Partial_Machine_Word:
|
|
||||||
|
|
||||||
;; Test bit 1 to see if size is at least 2
|
|
||||||
test bsize, 2
|
|
||||||
jz RDSEED_Bit_1_Not_Set
|
|
||||||
|
|
||||||
mov WORD PTR [buffer], ax
|
|
||||||
shr eax, 16
|
|
||||||
add buffer, 2
|
|
||||||
|
|
||||||
RDSEED_Bit_1_Not_Set:
|
|
||||||
|
|
||||||
;; Test bit 0 to see if size is at least 1
|
|
||||||
test bsize, 1
|
|
||||||
jz RDSEED_Bit_0_Not_Set
|
|
||||||
|
|
||||||
mov BYTE PTR [buffer], al
|
|
||||||
|
|
||||||
RDSEED_Bit_0_Not_Set:
|
|
||||||
|
|
||||||
;; We've hit all the bits
|
|
||||||
|
|
||||||
RDSEED_GenerateBlock_Return:
|
|
||||||
|
|
||||||
;; Clear artifacts
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
MASM_RDSEED_GenerateBlock ENDP
|
|
||||||
|
|
||||||
ENDIF ;; _M_X86
|
|
||||||
|
|
||||||
OPTION PROLOGUE:PrologueDef
|
|
||||||
OPTION EPILOGUE:EpilogueDef
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
IFDEF _M_X64 ;; Set via the command line
|
|
||||||
|
|
||||||
.CODE
|
|
||||||
ALIGN 16
|
|
||||||
OPTION PROLOGUE:NONE
|
|
||||||
OPTION EPILOGUE:NONE
|
|
||||||
|
|
||||||
;; No need for Load_Arguments due to fastcall
|
|
||||||
;; RCX (in): arg1, byte* buffer
|
|
||||||
;; RDX (in): arg2, size_t bsize
|
|
||||||
|
|
||||||
MASM_RDSEED_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD
|
|
||||||
|
|
||||||
MWSIZE EQU 08h ;; machine word size
|
|
||||||
buffer EQU rcx
|
|
||||||
bsize EQU rdx
|
|
||||||
|
|
||||||
;; Top of While loop
|
|
||||||
RDSEED_GenerateBlock_Top:
|
|
||||||
|
|
||||||
;; Check remaining size
|
|
||||||
cmp bsize, 0
|
|
||||||
je RDSEED_GenerateBlock_Return
|
|
||||||
|
|
||||||
RDSEED_Call_RAX:
|
|
||||||
;; RDSEED is not available prior to VS2012. Just emit
|
|
||||||
;; the byte codes using DB. This is `rdseed rax`.
|
|
||||||
DB 048h, 0Fh, 0C7h, 0F8h
|
|
||||||
|
|
||||||
;; If CF=1, the number returned by RDSEED is valid.
|
|
||||||
;; If CF=0, a random number was not available.
|
|
||||||
|
|
||||||
;; Retry immediately
|
|
||||||
jnc RDSEED_Call_RAX
|
|
||||||
|
|
||||||
RDSEED_succeeded:
|
|
||||||
|
|
||||||
cmp bsize, MWSIZE
|
|
||||||
jb RDSEED_Partial_Machine_Word
|
|
||||||
|
|
||||||
RDSEED_Full_Machine_Word:
|
|
||||||
|
|
||||||
mov QWORD PTR [buffer], rax
|
|
||||||
add buffer, MWSIZE
|
|
||||||
sub bsize, MWSIZE
|
|
||||||
|
|
||||||
;; Continue
|
|
||||||
jmp RDSEED_GenerateBlock_Top
|
|
||||||
|
|
||||||
;; 1,2,3,4,5,6,7 bytes remain
|
|
||||||
RDSEED_Partial_Machine_Word:
|
|
||||||
|
|
||||||
;; Test bit 2 to see if size is at least 4
|
|
||||||
test bsize, 4
|
|
||||||
jz RDSEED_Bit_2_Not_Set
|
|
||||||
|
|
||||||
mov DWORD PTR [buffer], eax
|
|
||||||
shr rax, 32
|
|
||||||
add buffer, 4
|
|
||||||
|
|
||||||
RDSEED_Bit_2_Not_Set:
|
|
||||||
|
|
||||||
;; Test bit 1 to see if size is at least 2
|
|
||||||
test bsize, 2
|
|
||||||
jz RDSEED_Bit_1_Not_Set
|
|
||||||
|
|
||||||
mov WORD PTR [buffer], ax
|
|
||||||
shr eax, 16
|
|
||||||
add buffer, 2
|
|
||||||
|
|
||||||
RDSEED_Bit_1_Not_Set:
|
|
||||||
|
|
||||||
;; Test bit 0 to see if size is at least 1
|
|
||||||
test bsize, 1
|
|
||||||
jz RDSEED_Bit_0_Not_Set
|
|
||||||
|
|
||||||
mov BYTE PTR [buffer], al
|
|
||||||
|
|
||||||
RDSEED_Bit_0_Not_Set:
|
|
||||||
|
|
||||||
;; We've hit all the bits
|
|
||||||
|
|
||||||
RDSEED_GenerateBlock_Return:
|
|
||||||
|
|
||||||
;; Clear artifacts
|
|
||||||
xor rax, rax
|
|
||||||
ret
|
|
||||||
|
|
||||||
MASM_RDSEED_GenerateBlock ENDP
|
|
||||||
|
|
||||||
ENDIF ;; _M_X64
|
ENDIF ;; _M_X64
|
||||||
|
|
||||||
OPTION PROLOGUE:PrologueDef
|
|
||||||
OPTION EPILOGUE:EpilogueDef
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
|
||||||
|
;; Copyright assigned to the Crypto++ project.
|
||||||
|
|
||||||
|
;; This ASM file provides RDSEED to downlevel Microsoft tool chains.
|
||||||
|
;; Everything "just works" under Visual Studio. Other platforms will
|
||||||
|
;; have to run MASM/MASM-64 and then link to the object files.
|
||||||
|
|
||||||
|
;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh
|
||||||
|
;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi
|
||||||
|
;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\ml.exe" %ASFLAGS% /Fo rdrand-x86.obj /c rdrand.asm
|
||||||
|
;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\ml64.exe" %ASFLAGS64% /Fo rdrand-x64.obj /c rdrand.asm
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
TITLE MASM_RDSEED_GenerateBlock source file
|
||||||
|
SUBTITLE Microsoft specific ASM code to utilize RDSEED for down level Microsoft toolchains
|
||||||
|
|
||||||
|
PUBLIC MASM_RDSEED_GenerateBlock
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; C/C++ Function prototypes (both are fastcall)
|
||||||
|
;; X86:
|
||||||
|
;; extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size);
|
||||||
|
;; X64:
|
||||||
|
;; extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size);
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
IFDEF _M_X86 ;; Set via the command line
|
||||||
|
|
||||||
|
.486
|
||||||
|
.MODEL FLAT
|
||||||
|
|
||||||
|
;; Fastcall calling conventions exports
|
||||||
|
ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock>
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
IFDEF _M_X86 ;; Set via the command line
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
ALIGN 8
|
||||||
|
OPTION PROLOGUE:NONE
|
||||||
|
OPTION EPILOGUE:NONE
|
||||||
|
|
||||||
|
;; No need for Load_Arguments due to fastcall
|
||||||
|
;; ECX (in): arg1, byte* buffer
|
||||||
|
;; EDX (in): arg2, size_t bsize
|
||||||
|
|
||||||
|
MASM_RDSEED_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD
|
||||||
|
|
||||||
|
MWSIZE EQU 04h ;; machine word size
|
||||||
|
buffer EQU ecx
|
||||||
|
bsize EQU edx
|
||||||
|
|
||||||
|
;; Top of While loop
|
||||||
|
RDSEED_GenerateBlock_Top:
|
||||||
|
|
||||||
|
;; Check remaining size
|
||||||
|
cmp bsize, 0
|
||||||
|
je RDSEED_GenerateBlock_Return
|
||||||
|
|
||||||
|
RDSEED_Call_EAX:
|
||||||
|
;; RDSEED is not available prior to VS2012. Just emit
|
||||||
|
;; the byte codes using DB. This is `rdseed eax`.
|
||||||
|
DB 0Fh, 0C7h, 0F8h
|
||||||
|
|
||||||
|
;; If CF=1, the number returned by RDSEED is valid.
|
||||||
|
;; If CF=0, a random number was not available.
|
||||||
|
|
||||||
|
;; Retry immediately
|
||||||
|
jnc RDSEED_Call_EAX
|
||||||
|
|
||||||
|
RDSEED_succeeded:
|
||||||
|
|
||||||
|
cmp bsize, MWSIZE
|
||||||
|
jb RDSEED_Partial_Machine_Word
|
||||||
|
|
||||||
|
RDSEED_Full_Machine_Word:
|
||||||
|
|
||||||
|
mov DWORD PTR [buffer], eax
|
||||||
|
add buffer, MWSIZE ;; No need for Intel Core 2 slow workarounds, like
|
||||||
|
sub bsize, MWSIZE ;; `lea buffer,[buffer+MWSIZE]` for faster adds
|
||||||
|
|
||||||
|
;; Continue
|
||||||
|
jmp RDSEED_GenerateBlock_Top
|
||||||
|
|
||||||
|
;; 1,2,3 bytes remain
|
||||||
|
RDSEED_Partial_Machine_Word:
|
||||||
|
|
||||||
|
;; Test bit 1 to see if size is at least 2
|
||||||
|
test bsize, 2
|
||||||
|
jz RDSEED_Bit_1_Not_Set
|
||||||
|
|
||||||
|
mov WORD PTR [buffer], ax
|
||||||
|
shr eax, 16
|
||||||
|
add buffer, 2
|
||||||
|
|
||||||
|
RDSEED_Bit_1_Not_Set:
|
||||||
|
|
||||||
|
;; Test bit 0 to see if size is at least 1
|
||||||
|
test bsize, 1
|
||||||
|
jz RDSEED_Bit_0_Not_Set
|
||||||
|
|
||||||
|
mov BYTE PTR [buffer], al
|
||||||
|
|
||||||
|
RDSEED_Bit_0_Not_Set:
|
||||||
|
|
||||||
|
;; We've hit all the bits
|
||||||
|
|
||||||
|
RDSEED_GenerateBlock_Return:
|
||||||
|
|
||||||
|
;; Clear artifacts
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
MASM_RDSEED_GenerateBlock ENDP
|
||||||
|
|
||||||
|
;; OPTION PROLOGUE:PrologueDef
|
||||||
|
;; OPTION EPILOGUE:EpilogueDef
|
||||||
|
|
||||||
|
ENDIF ;; _M_X86
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
IFDEF _M_X64 ;; Set via the command line
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
ALIGN 16
|
||||||
|
OPTION PROLOGUE:NONE
|
||||||
|
OPTION EPILOGUE:NONE
|
||||||
|
|
||||||
|
;; No need for Load_Arguments due to fastcall
|
||||||
|
;; RCX (in): arg1, byte* buffer
|
||||||
|
;; RDX (in): arg2, size_t bsize
|
||||||
|
|
||||||
|
MASM_RDSEED_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD
|
||||||
|
|
||||||
|
MWSIZE EQU 08h ;; machine word size
|
||||||
|
buffer EQU rcx
|
||||||
|
bsize EQU rdx
|
||||||
|
|
||||||
|
;; Top of While loop
|
||||||
|
RDSEED_GenerateBlock_Top:
|
||||||
|
|
||||||
|
;; Check remaining size
|
||||||
|
cmp bsize, 0
|
||||||
|
je RDSEED_GenerateBlock_Return
|
||||||
|
|
||||||
|
RDSEED_Call_RAX:
|
||||||
|
;; RDSEED is not available prior to VS2012. Just emit
|
||||||
|
;; the byte codes using DB. This is `rdseed rax`.
|
||||||
|
DB 048h, 0Fh, 0C7h, 0F8h
|
||||||
|
|
||||||
|
;; If CF=1, the number returned by RDSEED is valid.
|
||||||
|
;; If CF=0, a random number was not available.
|
||||||
|
|
||||||
|
;; Retry immediately
|
||||||
|
jnc RDSEED_Call_RAX
|
||||||
|
|
||||||
|
RDSEED_succeeded:
|
||||||
|
|
||||||
|
cmp bsize, MWSIZE
|
||||||
|
jb RDSEED_Partial_Machine_Word
|
||||||
|
|
||||||
|
RDSEED_Full_Machine_Word:
|
||||||
|
|
||||||
|
mov QWORD PTR [buffer], rax
|
||||||
|
add buffer, MWSIZE
|
||||||
|
sub bsize, MWSIZE
|
||||||
|
|
||||||
|
;; Continue
|
||||||
|
jmp RDSEED_GenerateBlock_Top
|
||||||
|
|
||||||
|
;; 1,2,3,4,5,6,7 bytes remain
|
||||||
|
RDSEED_Partial_Machine_Word:
|
||||||
|
|
||||||
|
;; Test bit 2 to see if size is at least 4
|
||||||
|
test bsize, 4
|
||||||
|
jz RDSEED_Bit_2_Not_Set
|
||||||
|
|
||||||
|
mov DWORD PTR [buffer], eax
|
||||||
|
shr rax, 32
|
||||||
|
add buffer, 4
|
||||||
|
|
||||||
|
RDSEED_Bit_2_Not_Set:
|
||||||
|
|
||||||
|
;; Test bit 1 to see if size is at least 2
|
||||||
|
test bsize, 2
|
||||||
|
jz RDSEED_Bit_1_Not_Set
|
||||||
|
|
||||||
|
mov WORD PTR [buffer], ax
|
||||||
|
shr eax, 16
|
||||||
|
add buffer, 2
|
||||||
|
|
||||||
|
RDSEED_Bit_1_Not_Set:
|
||||||
|
|
||||||
|
;; Test bit 0 to see if size is at least 1
|
||||||
|
test bsize, 1
|
||||||
|
jz RDSEED_Bit_0_Not_Set
|
||||||
|
|
||||||
|
mov BYTE PTR [buffer], al
|
||||||
|
|
||||||
|
RDSEED_Bit_0_Not_Set:
|
||||||
|
|
||||||
|
;; We've hit all the bits
|
||||||
|
|
||||||
|
RDSEED_GenerateBlock_Return:
|
||||||
|
|
||||||
|
;; Clear artifacts
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
MASM_RDSEED_GenerateBlock ENDP
|
||||||
|
|
||||||
|
;; OPTION PROLOGUE:PrologueDef
|
||||||
|
;; OPTION EPILOGUE:EpilogueDef
|
||||||
|
|
||||||
|
ENDIF ;; _M_X64
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
END
|
||||||
5
test.cpp
5
test.cpp
|
|
@ -176,9 +176,8 @@ int scoped_main(int argc, char *argv[])
|
||||||
// A hint to help locate TestData/ and TestVectors/ after install.
|
// A hint to help locate TestData/ and TestVectors/ after install.
|
||||||
SetArgvPathHint(argv[0], g_argvPathHint);
|
SetArgvPathHint(argv[0], g_argvPathHint);
|
||||||
|
|
||||||
// Set a seed for reproducible results. It can be set on the command line.
|
// Set a seed for reproducible results. If the seed is too short then
|
||||||
// If the seed is short then it is padded with spaces. If the seed is
|
// it is padded with spaces. If the seed is missing then time() is used.
|
||||||
// missing then time() is used.
|
|
||||||
// For example:
|
// For example:
|
||||||
// ./cryptest.exe v seed=abcdefg
|
// ./cryptest.exe v seed=abcdefg
|
||||||
SetGlobalSeed(argc, argv, s_globalSeed);
|
SetGlobalSeed(argc, argv, s_globalSeed);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue