mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows: use CPU RDRAND or RDSEED as an additional entropy source for our random generator when available
This commit is contained in:
@@ -14,6 +14,8 @@
|
|||||||
#include "Tcdefs.h"
|
#include "Tcdefs.h"
|
||||||
#include "Crc.h"
|
#include "Crc.h"
|
||||||
#include "Random.h"
|
#include "Random.h"
|
||||||
|
#include "Crypto\cpu.h"
|
||||||
|
#include "Crypto\rdrand.h"
|
||||||
#include <Strsafe.h>
|
#include <Strsafe.h>
|
||||||
|
|
||||||
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
||||||
@@ -766,10 +768,6 @@ BOOL SlowPoll (void)
|
|||||||
if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||||
{
|
{
|
||||||
RandaddBuf (buffer, sizeof (buffer));
|
RandaddBuf (buffer, sizeof (buffer));
|
||||||
|
|
||||||
burn(buffer, sizeof (buffer));
|
|
||||||
Randmix();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -777,6 +775,19 @@ BOOL SlowPoll (void)
|
|||||||
CryptoAPILastError = GetLastError ();
|
CryptoAPILastError = GetLastError ();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use RDSEED or RDRAND from CPU as source of entropy if present
|
||||||
|
if ( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
||||||
|
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RandaddBuf (buffer, sizeof (buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
burn(buffer, sizeof (buffer));
|
||||||
|
Randmix();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -888,7 +899,6 @@ BOOL FastPoll (void)
|
|||||||
if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||||
{
|
{
|
||||||
RandaddBuf (buffer, sizeof (buffer));
|
RandaddBuf (buffer, sizeof (buffer));
|
||||||
burn (buffer, sizeof(buffer));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -897,6 +907,16 @@ BOOL FastPoll (void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use RDSEED or RDRAND from CPU as source of entropy if present
|
||||||
|
if ( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|
||||||
|
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RandaddBuf (buffer, sizeof (buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
burn (buffer, sizeof(buffer));
|
||||||
|
|
||||||
/* Apply the pool mixing function */
|
/* Apply the pool mixing function */
|
||||||
Randmix();
|
Randmix();
|
||||||
|
|
||||||
|
|||||||
@@ -219,6 +219,7 @@
|
|||||||
<ClCompile Include="GostCipher.c" />
|
<ClCompile Include="GostCipher.c" />
|
||||||
<ClCompile Include="kuznyechik.c" />
|
<ClCompile Include="kuznyechik.c" />
|
||||||
<ClCompile Include="kuznyechik_simd.c" />
|
<ClCompile Include="kuznyechik_simd.c" />
|
||||||
|
<ClCompile Include="rdrand.c" />
|
||||||
<ClCompile Include="Rmd160.c" />
|
<ClCompile Include="Rmd160.c" />
|
||||||
<ClCompile Include="SerpentFast.c" />
|
<ClCompile Include="SerpentFast.c" />
|
||||||
<ClCompile Include="SerpentFast_simd.cpp" />
|
<ClCompile Include="SerpentFast_simd.cpp" />
|
||||||
@@ -238,6 +239,7 @@
|
|||||||
<ClInclude Include="GostCipher.h" />
|
<ClInclude Include="GostCipher.h" />
|
||||||
<ClInclude Include="kuznyechik.h" />
|
<ClInclude Include="kuznyechik.h" />
|
||||||
<ClInclude Include="misc.h" />
|
<ClInclude Include="misc.h" />
|
||||||
|
<ClInclude Include="rdrand.h" />
|
||||||
<ClInclude Include="Rmd160.h" />
|
<ClInclude Include="Rmd160.h" />
|
||||||
<ClInclude Include="SerpentFast.h" />
|
<ClInclude Include="SerpentFast.h" />
|
||||||
<ClInclude Include="SerpentFast_sbox.h" />
|
<ClInclude Include="SerpentFast_sbox.h" />
|
||||||
@@ -366,6 +368,23 @@
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CustomBuild Include="rdrand_ml.asm">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)"
|
||||||
|
</Command>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo %(Filename)%(Extension) & ml64.exe /nologo /D_M_X64 /W3 /Cx /Zi /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)"
|
||||||
|
</Command>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)"
|
||||||
|
</Command>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo %(Filename)%(Extension) & ml.exe /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo "$(TargetDir)\%(Filename).obj" /c "%(FullPath)"
|
||||||
|
</Command>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(TargetDir)\%(Filename).obj;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -57,6 +57,9 @@
|
|||||||
<ClCompile Include="kuznyechik_simd.c">
|
<ClCompile Include="kuznyechik_simd.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="rdrand.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Aes.h">
|
<ClInclude Include="Aes.h">
|
||||||
@@ -110,6 +113,9 @@
|
|||||||
<ClInclude Include="SerpentFast_sbox.h">
|
<ClInclude Include="SerpentFast_sbox.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="rdrand.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="Aes_hw_cpu.asm">
|
<CustomBuild Include="Aes_hw_cpu.asm">
|
||||||
@@ -160,5 +166,8 @@
|
|||||||
<CustomBuild Include="sha512_sse4_x64.asm">
|
<CustomBuild Include="sha512_sse4_x64.asm">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rdrand_ml.asm">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
TC_ASFLAGS = -Xvc -Ox
|
TC_ASFLAGS = -Xvc -Ox
|
||||||
VC_YASMFLAGS = -Xvc -D WINABI -D __YASM__
|
VC_YASMFLAGS = -Xvc -D WINABI -D __YASM__
|
||||||
|
VC_MLFLAGS = /nologo /W3 /Cx /Zi
|
||||||
|
VC_MLEXE = ml.exe
|
||||||
|
|
||||||
!if "$(TC_ARCH)" == "x86"
|
!if "$(TC_ARCH)" == "x86"
|
||||||
TC_ASFLAGS = $(TC_ASFLAGS) -f win32 --prefix _ -D MS_STDCALL -D DLL_EXPORT
|
TC_ASFLAGS = $(TC_ASFLAGS) -f win32 --prefix _ -D MS_STDCALL -D DLL_EXPORT
|
||||||
VC_YASMFLAGS = $(VC_YASMFLAGS) -f win32 -D MS_STDCALL
|
VC_YASMFLAGS = $(VC_YASMFLAGS) -f win32 -D MS_STDCALL
|
||||||
|
VC_MLFLAGS = $(VC_MLFLAGS) /D_M_X86 /safeseh
|
||||||
!else
|
!else
|
||||||
TC_ASFLAGS = $(TC_ASFLAGS) -f win64
|
TC_ASFLAGS = $(TC_ASFLAGS) -f win64
|
||||||
VC_YASMFLAGS = $(VC_YASMFLAGS) -f win64
|
VC_YASMFLAGS = $(VC_YASMFLAGS) -f win64
|
||||||
|
VC_MLFLAGS = $(VC_MLFLAGS) /D_M_X64
|
||||||
|
VC_MLEXE = ml64.exe
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log
|
TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log
|
||||||
@@ -52,3 +57,7 @@ TC_ASM_ERR_LOG = ..\Driver\build_errors_asm.log
|
|||||||
|
|
||||||
"$(OBJ_PATH)\$(O)\sha256_sse4_$(TC_ARCH).obj": sha256_sse4_$(TC_ARCH).asm
|
"$(OBJ_PATH)\$(O)\sha256_sse4_$(TC_ARCH).obj": sha256_sse4_$(TC_ARCH).asm
|
||||||
yasm.exe $(VC_YASMFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\sha256_sse4_$(TC_ARCH).lst" sha256_sse4_$(TC_ARCH).asm 2>$(TC_ASM_ERR_LOG)
|
yasm.exe $(VC_YASMFLAGS) -o "$@" -l "$(OBJ_PATH)\$(O)\sha256_sse4_$(TC_ARCH).lst" sha256_sse4_$(TC_ARCH).asm 2>$(TC_ASM_ERR_LOG)
|
||||||
|
|
||||||
|
"$(OBJ_PATH)\$(O)\rdrand_ml.obj": rdrand_ml.asm
|
||||||
|
$(VC_MLEXE) $(VC_MLFLAGS) /Fo "$@" /c rdrand_ml.asm 2>$(TC_ASM_ERR_LOG)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ INCLUDES = ..
|
|||||||
NTTARGETFILES = \
|
NTTARGETFILES = \
|
||||||
"$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \
|
"$(OBJ_PATH)\$(O)\Aes_$(TC_ARCH).obj" \
|
||||||
"$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj" \
|
"$(OBJ_PATH)\$(O)\Aes_hw_cpu.obj" \
|
||||||
|
"$(OBJ_PATH)\$(O)\rdrand.obj" \
|
||||||
|
"$(OBJ_PATH)\$(O)\rdrand_ml.obj" \
|
||||||
"$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).obj" \
|
"$(OBJ_PATH)\$(O)\gost89_$(TC_ARCH).obj" \
|
||||||
"$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).obj" \
|
"$(OBJ_PATH)\$(O)\Twofish_$(TC_ARCH).obj" \
|
||||||
"$(OBJ_PATH)\$(O)\Camellia_$(TC_ARCH).obj" \
|
"$(OBJ_PATH)\$(O)\Camellia_$(TC_ARCH).obj" \
|
||||||
@@ -23,9 +25,11 @@ SOURCES = \
|
|||||||
Aes_$(TC_ARCH).asm \
|
Aes_$(TC_ARCH).asm \
|
||||||
gost89_$(TC_ARCH).asm \
|
gost89_$(TC_ARCH).asm \
|
||||||
Aes_hw_cpu.asm \
|
Aes_hw_cpu.asm \
|
||||||
|
rdrand_ml.asm \
|
||||||
Aeskey.c \
|
Aeskey.c \
|
||||||
Aestab.c \
|
Aestab.c \
|
||||||
cpu.c \
|
cpu.c \
|
||||||
|
rdrand.c \
|
||||||
Rmd160.c \
|
Rmd160.c \
|
||||||
SerpentFast.c \
|
SerpentFast.c \
|
||||||
SerpentFast_simd.cpp \
|
SerpentFast_simd.cpp \
|
||||||
|
|||||||
32
src/Crypto/rdrand.c
Normal file
32
src/Crypto/rdrand.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// rdrand.cpp - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
|
||||||
|
|
||||||
|
/* modified for VeraCrypt */
|
||||||
|
|
||||||
|
#include "chacha256.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
void CRYPTOPP_FASTCALL MASM_RDRAND_GenerateBlock(byte*, size_t);
|
||||||
|
void CRYPTOPP_FASTCALL MASM_RDSEED_GenerateBlock(byte*, size_t);
|
||||||
|
|
||||||
|
int RDRAND_getBytes(unsigned char* buf, size_t bufLen)
|
||||||
|
{
|
||||||
|
if (!buf || !HasRDRAND())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bufLen)
|
||||||
|
MASM_RDRAND_GenerateBlock(buf, bufLen);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RDSEED_getBytes(unsigned char* buf, size_t bufLen)
|
||||||
|
{
|
||||||
|
if (!buf || !HasRDSEED())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bufLen)
|
||||||
|
MASM_RDSEED_GenerateBlock(buf, bufLen);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
26
src/Crypto/rdrand.h
Normal file
26
src/Crypto/rdrand.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef HEADER_Crypto_RDRAND
|
||||||
|
#define HEADER_Crypto_RDRAND
|
||||||
|
|
||||||
|
#include "Common/Tcdefs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate bufLen random bytes using CPU RDRAND instruction
|
||||||
|
* return 1 in case of success and 0 in case of failure
|
||||||
|
*/
|
||||||
|
int RDRAND_getBytes(unsigned char* buf, size_t bufLen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate bufLen random bytes using CPU RDSEED instruction
|
||||||
|
* return 1 in case of success and 0 in case of failure
|
||||||
|
*/
|
||||||
|
int RDSEED_getBytes(unsigned char* buf, size_t bufLen);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
420
src/Crypto/rdrand_ml.asm
Normal file
420
src/Crypto/rdrand_ml.asm
Normal file
@@ -0,0 +1,420 @@
|
|||||||
|
;; 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.
|
||||||
|
|
||||||
|
;; 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_RDRAND_GenerateBlock and MASM_RDSEED_GenerateBlock
|
||||||
|
SUBTITLE Microsoft specific ASM code to utilize RDRAND and RDSEED for down level Microsoft toolchains
|
||||||
|
|
||||||
|
PUBLIC MASM_RDRAND_GenerateBlock
|
||||||
|
PUBLIC MASM_RDSEED_GenerateBlock
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; C/C++ Function prototypes (both are fastcall)
|
||||||
|
;; X86:
|
||||||
|
;; extern "C" void __fastcall MASM_RDRAND_GenerateBlock(byte* ptr, size_t size);
|
||||||
|
;; X64:
|
||||||
|
;; extern "C" void __fastcall MASM_RDRAND_GenerateBlock(byte* ptr, size_t size);
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
IFDEF _M_X86 ;; Set via the command line
|
||||||
|
|
||||||
|
.486
|
||||||
|
.MODEL FLAT
|
||||||
|
|
||||||
|
;; Fastcall calling conventions exports
|
||||||
|
ALIAS <@MASM_RDRAND_GenerateBlock@8> = <MASM_RDRAND_GenerateBlock>
|
||||||
|
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_RDRAND_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_RDRAND_EAX:
|
||||||
|
;; RDRAND is not available prior to VS2012. Just emit
|
||||||
|
;; the byte codes using DB. This is `rdrand eax`.
|
||||||
|
DB 0Fh, 0C7h, 0F0h
|
||||||
|
|
||||||
|
;; If CF=1, the number returned by RDRAND is valid.
|
||||||
|
;; If CF=0, a random number was not available.
|
||||||
|
|
||||||
|
;; Retry immediately
|
||||||
|
jnc Call_RDRAND_EAX
|
||||||
|
|
||||||
|
RDRAND_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_RDRAND_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_RDRAND_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_RDRAND_RAX:
|
||||||
|
;; RDRAND is not available prior to VS2012. Just emit
|
||||||
|
;; the byte codes using DB. This is `rdrand rax`.
|
||||||
|
DB 048h, 0Fh, 0C7h, 0F0h
|
||||||
|
|
||||||
|
;; If CF=1, the number returned by RDRAND is valid.
|
||||||
|
;; If CF=0, a random number was not available.
|
||||||
|
|
||||||
|
;; Retry immediately
|
||||||
|
jnc Call_RDRAND_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
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
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_RDSEED_GenerateBlock ENDP
|
||||||
|
|
||||||
|
ENDIF ;; _M_X64
|
||||||
|
|
||||||
|
OPTION PROLOGUE:PrologueDef
|
||||||
|
OPTION EPILOGUE:EpilogueDef
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
END
|
||||||
Reference in New Issue
Block a user