diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-10-30 00:15:28 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-10-30 08:52:55 +0100 |
commit | 7a35ecb154fc979d46dea8d97d0ad97fd4ae4140 (patch) | |
tree | 185a5ed69b1fd7cdde2d3b0e68841e76e1c13d8b /src/Crypto/rdrand_ml.asm | |
parent | 3b5d4771a0af5b4fc89ec77f43826b9ae2544949 (diff) | |
download | VeraCrypt-7a35ecb154fc979d46dea8d97d0ad97fd4ae4140.tar.gz VeraCrypt-7a35ecb154fc979d46dea8d97d0ad97fd4ae4140.zip |
Windows: use separate assembly files for RDRAND and RDSEED in order to fix a mysterious crash when MASM_RDSEED_GenerateBlock is called after MASM_RDRAND_GenerateBlock.
Diffstat (limited to 'src/Crypto/rdrand_ml.asm')
-rw-r--r-- | src/Crypto/rdrand_ml.asm | 266 |
1 files changed, 38 insertions, 228 deletions
diff --git a/src/Crypto/rdrand_ml.asm b/src/Crypto/rdrand_ml.asm index 1579a155..4b85f7fc 100644 --- a/src/Crypto/rdrand_ml.asm +++ b/src/Crypto/rdrand_ml.asm @@ -1,9 +1,9 @@ ;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. ;; Copyright assigned to the Crypto++ project. -;; This ASM file provides RDRAND and 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. +;; This ASM file provides RDRAND 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 @@ -13,11 +13,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -TITLE MASM_RDRAND_GenerateBlock and MASM_RDSEED_GenerateBlock -SUBTITLE Microsoft specific ASM code to utilize RDRAND and RDSEED for down level Microsoft toolchains +TITLE MASM_RDRAND_GenerateBlock source file +SUBTITLE Microsoft specific ASM code to utilize RDRAND for down level Microsoft toolchains PUBLIC MASM_RDRAND_GenerateBlock -PUBLIC MASM_RDSEED_GenerateBlock ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -38,7 +37,6 @@ IFDEF _M_X86 ;; Set via the command line ;; Fastcall calling conventions exports ALIAS <@MASM_RDRAND_GenerateBlock@8> = <MASM_RDRAND_GenerateBlock> -ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock> ENDIF @@ -63,13 +61,13 @@ MASM_RDRAND_GenerateBlock PROC ;; arg1:DWORD, arg2:DWORD bsize EQU edx ;; Top of While loop -GenerateBlock_Top: +RDRAND_GenerateBlock_Top: ;; Check remaining size cmp bsize, 0 - je GenerateBlock_Return + je RDRAND_GenerateBlock_Return -Call_RDRAND_EAX: +RDRAND_Call_EAX: ;; RDRAND is not available prior to VS2012. Just emit ;; the byte codes using DB. This is `rdrand eax`. DB 0Fh, 0C7h, 0F0h @@ -78,46 +76,48 @@ Call_RDRAND_EAX: ;; If CF=0, a random number was not available. ;; Retry immediately - jnc Call_RDRAND_EAX + jnc RDRAND_Call_EAX RDRAND_succeeded: cmp bsize, MWSIZE - jb Partial_Machine_Word + jb RDRAND_Partial_Machine_Word -Full_Machine_Word: +RDRAND_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 GenerateBlock_Top + jmp RDRAND_GenerateBlock_Top ;; 1,2,3 bytes remain -Partial_Machine_Word: +RDRAND_Partial_Machine_Word: ;; Test bit 1 to see if size is at least 2 test bsize, 2 - jz Bit_1_Not_Set + jz RDRAND_Bit_1_Not_Set mov WORD PTR [buffer], ax shr eax, 16 add buffer, 2 -Bit_1_Not_Set: +RDRAND_Bit_1_Not_Set: ;; Test bit 0 to see if size is at least 1 test bsize, 1 - jz Bit_0_Not_Set + jz RDRAND_Bit_0_Not_Set mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 -Bit_0_Not_Set: +RDRAND_Bit_0_Not_Set: ;; We've hit all the bits -GenerateBlock_Return: +RDRAND_GenerateBlock_Return: ;; Clear artifacts xor eax, eax @@ -127,9 +127,6 @@ MASM_RDRAND_GenerateBlock ENDP ENDIF ;; _M_X86 -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -151,13 +148,13 @@ MASM_RDRAND_GenerateBlock PROC ;; arg1:QWORD, arg2:QWORD bsize EQU rdx ;; Top of While loop -GenerateBlock_Top: +RDRAND_GenerateBlock_Top: ;; Check remaining size cmp bsize, 0 - je GenerateBlock_Return + je RDRAND_GenerateBlock_Return -Call_RDRAND_RAX: +RDRAND_Call_RAX: ;; RDRAND is not available prior to VS2012. Just emit ;; the byte codes using DB. This is `rdrand rax`. DB 048h, 0Fh, 0C7h, 0F0h @@ -166,254 +163,67 @@ Call_RDRAND_RAX: ;; If CF=0, a random number was not available. ;; Retry immediately - jnc Call_RDRAND_RAX + jnc RDRAND_Call_RAX RDRAND_succeeded: cmp bsize, MWSIZE - jb Partial_Machine_Word - -Full_Machine_Word: - - mov QWORD PTR [buffer], rax - add buffer, MWSIZE - sub bsize, MWSIZE - - ;; Continue - jmp GenerateBlock_Top - - ;; 1,2,3,4,5,6,7 bytes remain -Partial_Machine_Word: - - ;; Test bit 2 to see if size is at least 4 - test bsize, 4 - jz Bit_2_Not_Set - - mov DWORD PTR [buffer], eax - shr rax, 32 - add buffer, 4 - -Bit_2_Not_Set: - - ;; Test bit 1 to see if size is at least 2 - test bsize, 2 - jz Bit_1_Not_Set - - mov WORD PTR [buffer], ax - shr eax, 16 - add buffer, 2 - -Bit_1_Not_Set: - - ;; Test bit 0 to see if size is at least 1 - test bsize, 1 - jz Bit_0_Not_Set - - mov BYTE PTR [buffer], al - -Bit_0_Not_Set: - - ;; We've hit all the bits - -GenerateBlock_Return: - - ;; Clear artifacts - xor rax, rax - ret - -MASM_RDRAND_GenerateBlock ENDP - -ENDIF ;; _M_X64 - -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 -GenerateBlock_Top: - - ;; Check remaining size - cmp bsize, 0 - je GenerateBlock_Return - -Call_RDSEED_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 Call_RDSEED_EAX - -RDSEED_succeeded: - - cmp bsize, MWSIZE - jb Partial_Machine_Word - -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 GenerateBlock_Top - - ;; 1,2,3 bytes remain -Partial_Machine_Word: - - ;; Test bit 1 to see if size is at least 2 - test bsize, 2 - jz Bit_1_Not_Set - - mov WORD PTR [buffer], ax - shr eax, 16 - add buffer, 2 - -Bit_1_Not_Set: - - ;; Test bit 0 to see if size is at least 1 - test bsize, 1 - jz Bit_0_Not_Set - - mov BYTE PTR [buffer], al - -Bit_0_Not_Set: - - ;; We've hit all the bits - -GenerateBlock_Return: - - ;; Clear artifacts - xor eax, eax - ret - -MASM_RDSEED_GenerateBlock ENDP - -ENDIF ;; _M_X86 + jb RDRAND_Partial_Machine_Word -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 -GenerateBlock_Top: - - ;; Check remaining size - cmp bsize, 0 - je GenerateBlock_Return - -Call_RDSEED_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 Call_RDSEED_RAX - -RDSEED_succeeded: - - cmp bsize, MWSIZE - jb Partial_Machine_Word - -Full_Machine_Word: +RDRAND_Full_Machine_Word: mov QWORD PTR [buffer], rax add buffer, MWSIZE sub bsize, MWSIZE ;; Continue - jmp GenerateBlock_Top + jmp RDRAND_GenerateBlock_Top ;; 1,2,3,4,5,6,7 bytes remain -Partial_Machine_Word: +RDRAND_Partial_Machine_Word: ;; Test bit 2 to see if size is at least 4 test bsize, 4 - jz Bit_2_Not_Set + jz RDRAND_Bit_2_Not_Set mov DWORD PTR [buffer], eax shr rax, 32 add buffer, 4 -Bit_2_Not_Set: +RDRAND_Bit_2_Not_Set: ;; Test bit 1 to see if size is at least 2 test bsize, 2 - jz Bit_1_Not_Set + jz RDRAND_Bit_1_Not_Set mov WORD PTR [buffer], ax shr eax, 16 add buffer, 2 -Bit_1_Not_Set: +RDRAND_Bit_1_Not_Set: ;; Test bit 0 to see if size is at least 1 test bsize, 1 - jz Bit_0_Not_Set + jz RDRAND_Bit_0_Not_Set mov BYTE PTR [buffer], al + ;; shr ax, 8 + ;; add buffer, 1 -Bit_0_Not_Set: +RDRAND_Bit_0_Not_Set: ;; We've hit all the bits -GenerateBlock_Return: +RDRAND_GenerateBlock_Return: ;; Clear artifacts xor rax, rax ret -MASM_RDSEED_GenerateBlock ENDP +MASM_RDRAND_GenerateBlock ENDP ENDIF ;; _M_X64 -OPTION PROLOGUE:PrologueDef -OPTION EPILOGUE:EpilogueDef - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |