ReactOS 0.4.17-dev-1005-g171e1de
rdseed.c
Go to the documentation of this file.
1//
2// rdseed.c Support for RdSeed instruction
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7#include "precomp.h"
8
9#if (SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64) // only available on x86 and amd64 architectures.
10
11#ifdef __clang__
12#pragma clang attribute push (__attribute__((target("rdseed"))), apply_to=function)
13#else
14#pragma GCC push_options
15#pragma GCC target("rdseed")
16#endif
17
18#if SYMCRYPT_MS_VC && _MSC_VER < 1610
19#error MSVC version lacks support for RDSEED intrinsics. Compile for the generic environment instead.
20#endif
21
22//
23// Create a definition that works on SIZE_Ts.
24//
25
26#if SYMCRYPT_CPU_X86
27#define _rdseedxx_step(_p) _rdseed32_step( (unsigned int *) (_p) )
28#else
29#define _rdseedxx_step(_p) _rdseed64_step( (UINT64 *) (_p) )
30#endif
31
35SymCryptRdseedSizet( SIZE_T * p )
36{
37 int i;
38
39 //
40 // There is no way to report errors, and customers rely on the RNG to work properly.
41 // Therefore, higher layers will fatal if this function fails.
42 // This is why we have a very high retry count; the alternative is to fatal.
43 //
44 //
45 for( i=0; i<10000000; i++ )
46 {
47 if( _rdseedxx_step( p ) != 0 )
48 {
49 return SYMCRYPT_NO_ERROR;
50 }
51 }
52 return SYMCRYPT_HARDWARE_FAILURE;
53}
54
55
58SymCryptRdseedStatus(void)
59{
60 //
61 // Check that the library is initialized; otherwise the CPUID info
62 // is all zeroes. (This check only happens in CHKed builds.)
63 //
65
66 if( SYMCRYPT_CPU_FEATURES_PRESENT( SYMCRYPT_CPU_FEATURE_RDSEED ) )
67 {
68 return SYMCRYPT_NO_ERROR;
69 }
70 else
71 {
72 return SYMCRYPT_NOT_IMPLEMENTED;
73 }
74}
75
76
79SymCryptRdseedGetBytes(
80 _Out_writes_( cbResult ) PBYTE pbResult,
81 SIZE_T cbResult )
82{
83 SIZE_T * pBuf;
84 SIZE_T nBuf;
85 SIZE_T i;
86 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
87
88 //
89 // Take care of the obvious errors that can happen
90 //
91 if( SymCryptRdseedStatus() != SYMCRYPT_NO_ERROR ||
92 (cbResult & 0xf) != 0
93 )
94 {
95 SymCryptFatal( 'rdsd' );
96 }
97
98 pBuf = (SIZE_T *) pbResult;
99 nBuf = cbResult / sizeof( SIZE_T );
100
101 for( i=0; i<nBuf; i++ )
102 {
103 scError = SymCryptRdseedSizet( &pBuf[i] );
104 if( scError != SYMCRYPT_NO_ERROR )
105 {
106 goto cleanup;
107 }
108 }
109
110cleanup:
111
112 return scError;
113}
114
115
116VOID
118SymCryptRdseedGet(
119 _Out_writes_( cbResult ) PBYTE pbResult,
120 SIZE_T cbResult )
121{
122 if( SymCryptRdseedGetBytes( pbResult, cbResult ) != SYMCRYPT_NO_ERROR )
123 {
124 SymCryptFatal( 'rdsx' );
125 }
126}
127
128
129#ifdef __clang__
130#pragma clang attribute pop
131#else
132#pragma GCC pop_options
133#endif
134
135#endif // SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
static void cleanup(void)
Definition: main.c:1335
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _Out_writes_(s)
Definition: no_sal2.h:176
BYTE * PBYTE
Definition: pedump.c:66
FORCEINLINE VOID SYMCRYPT_CALL SymCryptCheckLibraryInitialized(void)
Definition: sc_lib.h:296
static const BYTE pbResult[]
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_CALL
#define SYMCRYPT_CPU_FEATURES_PRESENT(x)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define FORCEINLINE
Definition: wdftypes.h:67