ReactOS 0.4.15-dev-7928-g68a8619
havege.c
Go to the documentation of this file.
1
46/*
47 * The HAVEGE RNG was designed by Andre Seznec in 2002.
48 *
49 * http://www.irisa.fr/caps/projects/hipsor/publi.php
50 *
51 * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
52 */
53
54#if !defined(MBEDTLS_CONFIG_FILE)
55#include "mbedtls/config.h"
56#else
57#include MBEDTLS_CONFIG_FILE
58#endif
59
60#if defined(MBEDTLS_HAVEGE_C)
61
62#include "mbedtls/havege.h"
63#include "mbedtls/timing.h"
65
66#include <limits.h>
67#include <string.h>
68
69/* If int isn't capable of storing 2^32 distinct values, the code of this
70 * module may cause a processor trap or a miscalculation. If int is more
71 * than 32 bits, the code may not calculate the intended values. */
72#if INT_MIN + 1 != -0x7fffffff
73#error "The HAVEGE module requires int to be exactly 32 bits, with INT_MIN = -2^31."
74#endif
75#if UINT_MAX != 0xffffffff
76#error "The HAVEGE module requires unsigned to be exactly 32 bits."
77#endif
78
79/* ------------------------------------------------------------------------
80 * On average, one iteration accesses two 8-word blocks in the havege WALK
81 * table, and generates 16 words in the RES array.
82 *
83 * The data read in the WALK table is updated and permuted after each use.
84 * The result of the hardware clock counter read is used for this update.
85 *
86 * 25 conditional tests are present. The conditional tests are grouped in
87 * two nested groups of 12 conditional tests and 1 test that controls the
88 * permutation; on average, there should be 6 tests executed and 3 of them
89 * should be mispredicted.
90 * ------------------------------------------------------------------------
91 */
92
93#define SWAP(X,Y) { unsigned *T = (X); (X) = (Y); (Y) = T; }
94
95#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
96#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
97
98#define TST1_LEAVE U1++; }
99#define TST2_LEAVE U2++; }
100
101#define ONE_ITERATION \
102 \
103 PTEST = PT1 >> 20; \
104 \
105 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
106 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
107 TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
108 \
109 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
110 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
111 TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
112 \
113 PTX = (PT1 >> 18) & 7; \
114 PT1 &= 0x1FFF; \
115 PT2 &= 0x1FFF; \
116 CLK = (unsigned) mbedtls_timing_hardclock(); \
117 \
118 i = 0; \
119 A = &WALK[PT1 ]; RES[i++] ^= *A; \
120 B = &WALK[PT2 ]; RES[i++] ^= *B; \
121 C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
122 D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
123 \
124 IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
125 *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
126 *B = IN ^ U1; \
127 *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
128 *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
129 \
130 A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
131 B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
132 C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
133 D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
134 \
135 if( PTEST & 1 ) SWAP( A, C ); \
136 \
137 IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
138 *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
139 *B = IN; CLK = (unsigned) mbedtls_timing_hardclock(); \
140 *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
141 *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
142 \
143 A = &WALK[PT1 ^ 4]; \
144 B = &WALK[PT2 ^ 1]; \
145 \
146 PTEST = PT2 >> 1; \
147 \
148 PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
149 PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
150 PTY = (PT2 >> 10) & 7; \
151 \
152 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
153 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
154 TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
155 \
156 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
157 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
158 TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
159 \
160 C = &WALK[PT1 ^ 5]; \
161 D = &WALK[PT2 ^ 5]; \
162 \
163 RES[i++] ^= *A; \
164 RES[i++] ^= *B; \
165 RES[i++] ^= *C; \
166 RES[i++] ^= *D; \
167 \
168 IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
169 *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
170 *B = IN ^ U2; \
171 *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
172 *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
173 \
174 A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
175 B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
176 C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
177 D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
178 \
179 IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
180 *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
181 *B = IN; \
182 *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
183 *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
184 \
185 PT1 = ( RES[( i - 8 ) ^ PTX] ^ \
186 WALK[PT1 ^ PTX ^ 7] ) & (~1); \
187 PT1 ^= (PT2 ^ 0x10) & 0x10; \
188 \
189 for( n++, i = 0; i < 16; i++ ) \
190 POOL[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
191
192/*
193 * Entropy gathering function
194 */
195static void havege_fill( mbedtls_havege_state *hs )
196{
197 unsigned i, n = 0;
198 unsigned U1, U2, *A, *B, *C, *D;
199 unsigned PT1, PT2, *WALK, *POOL, RES[16];
200 unsigned PTX, PTY, CLK, PTEST, IN;
201
202 WALK = (unsigned *) hs->WALK;
203 POOL = (unsigned *) hs->pool;
204 PT1 = hs->PT1;
205 PT2 = hs->PT2;
206
207 PTX = U1 = 0;
208 PTY = U2 = 0;
209
210 (void)PTX;
211
212 memset( RES, 0, sizeof( RES ) );
213
214 while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
215 {
216 ONE_ITERATION
217 ONE_ITERATION
218 ONE_ITERATION
219 ONE_ITERATION
220 }
221
222 hs->PT1 = PT1;
223 hs->PT2 = PT2;
224
225 hs->offset[0] = 0;
227}
228
229/*
230 * HAVEGE initialization
231 */
233{
234 memset( hs, 0, sizeof( mbedtls_havege_state ) );
235
236 havege_fill( hs );
237}
238
240{
241 if( hs == NULL )
242 return;
243
245}
246
247/*
248 * HAVEGE rand function
249 */
250int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
251{
252 int val;
253 size_t use_len;
255 unsigned char *p = buf;
256
257 while( len > 0 )
258 {
259 use_len = len;
260 if( use_len > sizeof(int) )
261 use_len = sizeof(int);
262
263 if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
264 havege_fill( hs );
265
266 val = hs->pool[hs->offset[0]++];
267 val ^= hs->pool[hs->offset[1]++];
268
269 memcpy( p, &val, use_len );
270
271 len -= use_len;
272 p += use_len;
273 }
274
275 return( 0 );
276}
277
278#endif /* MBEDTLS_HAVEGE_C */
#define U2(x)
Definition: wordpad.c:46
#define D(d)
Definition: builtin.c:4557
#define C(c)
Definition: builtin.c:4556
#define NULL
Definition: types.h:112
#define A(row, col)
#define B(row, col)
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
HAVEGE: HArdware Volatile Entropy Gathering and Expansion.
void mbedtls_havege_free(mbedtls_havege_state *hs)
Clear HAVEGE state.
void mbedtls_havege_init(mbedtls_havege_state *hs)
HAVEGE initialization.
int mbedtls_havege_random(void *p_rng, unsigned char *output, size_t len)
HAVEGE rand function.
#define MBEDTLS_HAVEGE_COLLECT_SIZE
Definition: havege.h:60
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
void mbedtls_platform_zeroize(void *buf, size_t len)
Securely zeroize a buffer.
Definition: platform_util.c:98
Common and shared functions used by multiple modules in the Mbed TLS library.
struct tagTEST * PTEST
Configuration options (set of defines)
#define U1(x)
Definition: test.h:199
#define memset(x, y, z)
Definition: compat.h:39
HAVEGE state structure.
Definition: havege.h:70
int WALK[8192]
Definition: havege.h:73
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]
Definition: havege.h:72
Portable interface to timeouts and to the CPU cycle counter.
#define IN
Definition: typedefs.h:39