2 * Copyright (C) 2012, 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
17 #if defined(KRIPTO_UNIX)
19 #ifndef KRIPTO_DEV_RANDOM
20 #define KRIPTO_DEV_RANDOM "/dev/urandom"
26 #elif defined(KRIPTO_WINDOWS)
28 #if !defined(KRIPTO_RTLGENRANDOM) && !defined(KRIPTO_CRYPTGENRANDOM)
29 #define KRIPTO_RTLGENRANDOM
34 #if defined(KRIPTO_RTLGENRANDOM)
41 #elif defined(KRIPTO_CRYPTGENRANDOM)
47 #ifndef KRIPTO_RESEED_OUTPUT
48 #define KRIPTO_RESEED_OUTPUT 5242880 /* 5MB */
51 #ifndef KRIPTO_RESEED_TIME
52 #define KRIPTO_RESEED_TIME 300 /* 5 min */
60 #include <sys/resource.h>
63 #include <kripto/memwipe.h>
64 #include <kripto/stream.h>
65 #include <kripto/scrypt.h>
66 #include <kripto/stream/chacha.h>
67 #include <kripto/mac.h>
68 #include <kripto/mac.h>
69 #include <kripto/mac/hmac.h>
70 #include <kripto/hash.h>
71 #include <kripto/hash/blake2s.h>
75 kripto_stream
*stream
;
87 #include <kripto/random.h>
89 #if !defined(KRIPTO_WINDOWS) && !defined(KRIPTO_UNIX)
91 static int seed(kripto_random
*s
, uint8_t *out
, unsigned int len
)
95 #if defined(KRIPTO_UNIX)
103 uint8_t unassigned
[4];
106 s
->mac
= kripto_mac_hmac(kripto_hash_blake2s
);
107 if(!s
->mac
) return -1;
109 #if defined(KRIPTO_UNIX)
110 entropy
.pid
= getpid();
111 (void)clock_gettime(CLOCK_REALTIME
, &entropy
.time
);
112 (void)getrusage(RUSAGE_SELF
, &entropy
.usage
);
114 entropy
.time
= time(NULL
);
115 entropy
.clock
= clock();
122 &entropy
, sizeof(entropy
),
127 memcpy(entropy
.unassigned
, &s
, 4);
129 #if defined(KRIPTO_UNIX)
130 (void)clock_gettime(CLOCK_REALTIME
, &entropy
.time
);
131 (void)getrusage(RUSAGE_SELF
, &entropy
.usage
);
133 entropy
.time
= time(NULL
);
134 entropy
.clock
= clock();
141 &entropy
, sizeof(entropy
),
146 kripto_memwipe(&entropy
, sizeof(entropy
));
149 s
->time
= time(NULL
);
154 static kripto_random
*create(void)
159 s
= malloc(sizeof(kripto_random
));
162 if(seed(s
, buf
, 32)) goto err
;
164 s
->stream
= kripto_stream_create
166 kripto_stream_chacha
, 0,
170 if(!s
->stream
) goto err
;
181 kripto_random
*kripto_random_create(void)
183 #if defined(KRIPTO_DEV_RANDOM)
185 const char *dev_random
;
188 dev_random
= getenv("KRIPTO_RANDOM");
190 #ifdef KRIPTO_DEV_RANDOM
191 dev_random
= KRIPTO_DEV_RANDOM
;
196 return (kripto_random
*)fopen(dev_random
, "rb");
198 /*fp = fopen(dev_random, "rb");
199 if(fp) return (kripto_random *)fp;
200 else return create();*/
202 #elif defined(KRIPTO_RTLGENRANDOM)
206 s
= malloc(sizeof(kripto_random
));
209 s
->lib
= LoadLibrary("advapi32.dll");
216 s
->rtlgenrandom
= GetProcAddress(s
->lib
, "SystemFunction036");
226 #elif defined(KRIPTO_CRYPTGENRANDOM)
227 #if sizeof(kripto_random *) < sizeof(HCRYPTPROV)
228 #error sizeof(kripto_random *) < sizeof(HCRYPTPROV)
233 if(!CryptAcquireContext
239 CRYPT_VERIFYCONTEXT
| CRYPT_SILENT
242 return (kripto_random
*)prov
;
251 size_t kripto_random_gen(kripto_random
*s
, void *out
, size_t len
)
255 #if defined(KRIPTO_DEV_RANDOM)
257 return fread(out
, sizeof(char), len
, (FILE *)s
);
259 #elif defined(KRIPTO_RTLGENRANDOM)
261 assert(s
->rtlgenrandom
);
262 if(s
->rtlgenrandom(out
, len
) == TRUE
) return len
;
265 #elif defined(KRIPTO_CRYPTGENRANDOM)
267 if(CryptGenRandom((HCRYPTPROV
)s
, len
, out
)) return len
;
279 s
->output
> KRIPTO_RESEED_OUTPUT
||
280 time(NULL
) - s
->time
> KRIPTO_RESEED_TIME
283 kripto_stream_prng(s
->stream
, iv
, 8);
285 if(seed(s
, buf
, 32)) goto err
;
287 s
->stream
= kripto_stream_recreate
293 if(!s
->stream
) goto err
;
296 kripto_stream_prng(s
->stream
, out
, len
);
301 kripto_memwipe(s
, sizeof(kripto_random
));
308 void kripto_random_destroy(kripto_random
*s
)
312 #if defined(KRIPTO_DEV_RANDOM)
316 #elif defined(KRIPTO_RTLGENRANDOM)
321 #elif defined(KRIPTO_CRYPTGENRANDOM)
323 CryptReleaseContext((HCRYPTPROV
)s
, 0);
327 kripto_stream_destroy(s
->stream
);
330 kripto_memwipe(s
, sizeof(kripto_random
));
336 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || \
337 (defined(__cplusplus) && __cplusplus < 201103L)
339 #define LOG2(X) (log(X) / log(2))
341 #define LOG2(X) log2(X)
344 static unsigned int bitcount(const uint8_t x
)
349 for(mask
= 0x80; mask
; mask
>>= 1)
355 static unsigned int bitflips(const uint8_t prev
, const uint8_t x
)
363 for(mask
= 0x80; mask
; mask
>>= 1)
370 else if(p
&& !(x
& mask
))
380 int kripto_random_test(kripto_random
*s
)
382 uint8_t sample
[4096];
383 unsigned int count
[256];
388 double avg_null
= 0.0;
389 unsigned int bits
= 0;
390 unsigned int bit_flips
= 0;
393 unsigned int dist
[256];
394 unsigned int dist_prev
[256];
395 unsigned int dist_zero
= 0;
397 /* serial correlation */
406 if(kripto_random_gen(s
, sample
, 4096) != 4096) return 0;
408 memset(count
, 0, sizeof(unsigned int) * 256);
409 memset(dist
, 0, sizeof(unsigned int) * 256);
410 memset(dist_prev
, 0, sizeof(unsigned int) * 256);
412 for(i
= 0; i
< 4096; i
++)
416 bits
+= bitcount(sample
[i
]);
418 bit_flips
+= bitflips(prev
& 1, sample
[i
]);
421 if(prev
== sample
[i
]) dist_zero
++;
422 dist
[sample
[i
]] += 4096 - dist_prev
[sample
[i
]];
423 dist_prev
[sample
[i
]] = 4096;
425 /* serial correlation */
426 corr1
+= prev
* sample
[i
];
428 corr3
+= sample
[i
] * sample
[i
];
433 for(i
= 0; i
< 256; i
++)
440 t
= (double)count
[i
] / 4096.0;
441 if(t
) ent
-= t
* LOG2(t
);
443 /* arithmetic mean */
446 /* average null distance */
447 if(count
[i
]) avg_null
+= dist
[i
] / (double)count
[i
];
452 /* serial correlation */
453 corr2
= corr2
* corr2
;
454 corr
= (double)(4096 * corr1
- corr2
)
455 / (double)(4096 * corr3
- corr2
);
456 if(corr
< 0.0) corr
= -corr
; /* absolute */
459 if(ent
< 7.9) return 0;
460 if(avg
< 125 || avg
> 130.5) return 0;
462 if(t
< 0.49 || t
> 0.51) return 0;
463 if(chi
< 192 || chi
> 320) return 0;
464 t
= bit_flips
/ 32768.0;
465 if(t
< 0.49 || t
> 0.51) return 0;
466 if(avg_null
< 192 || avg_null
> 320) return 0;
467 if(dist_zero
/ 4096.0 > 0.1) return 0;
468 if(corr
> 0.1) return 0;