mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Always Salsa20 encrypt the result of the system CSPRNG as a mitigation against various low-entropy bugs such as the recent Raspberry Pi one.
This commit is contained in:
parent
4e12899a8e
commit
3869d6257b
1 changed files with 26 additions and 22 deletions
|
@ -29,6 +29,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
|
@ -149,13 +150,32 @@ unsigned int Utils::unhex(const char *hex,unsigned int maxlen,void *buf,unsigned
|
||||||
|
|
||||||
void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||||
{
|
{
|
||||||
|
static Mutex globalLock;
|
||||||
|
static Salsa20 s20;
|
||||||
|
static bool s20Initialized = false;
|
||||||
|
|
||||||
|
Mutex::Lock _l(globalLock);
|
||||||
|
|
||||||
|
/* Just for posterity we Salsa20 encrypt the result of whatever system
|
||||||
|
* CSPRNG we use. There have been several bugs at the OS or OS distribution
|
||||||
|
* level in the past that resulted in systematically weak or predictable
|
||||||
|
* keys due to random seeding problems. This mitigates that by grabbing
|
||||||
|
* a bit of extra entropy and further randomizing the result, and comes
|
||||||
|
* at almost no cost and with no real downside if the random source is
|
||||||
|
* good. */
|
||||||
|
if (!s20Initialized) {
|
||||||
|
s20Initialized = true;
|
||||||
|
uint64_t s20Key[4];
|
||||||
|
s20Key[0] = (uint64_t)time(0); // system clock
|
||||||
|
s20Key[1] = (uint64_t)buf; // address of buf
|
||||||
|
s20Key[2] = (uint64_t)s20Key; // address of s20Key[]
|
||||||
|
s20Key[3] = (uint64_t)&s20; // address of s20
|
||||||
|
s20.init(s20Key,256,s20Key);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
static HCRYPTPROV cryptProvider = NULL;
|
static HCRYPTPROV cryptProvider = NULL;
|
||||||
static Mutex globalLock;
|
|
||||||
static Salsa20 s20;
|
|
||||||
|
|
||||||
Mutex::Lock _l(globalLock);
|
|
||||||
|
|
||||||
if (cryptProvider == NULL) {
|
if (cryptProvider == NULL) {
|
||||||
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
|
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
|
||||||
|
@ -163,30 +183,17 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||||
exit(1);
|
exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char s20key[32];
|
|
||||||
if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(s20key),(BYTE *)s20key)) {
|
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
s20.init(s20key,256,s20key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CryptGenRandom(cryptProvider,(DWORD)bytes,(BYTE *)buf)) {
|
if (!CryptGenRandom(cryptProvider,(DWORD)bytes,(BYTE *)buf)) {
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
|
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
s20.encrypt12(buf,buf,bytes);
|
|
||||||
|
|
||||||
#else // not __WINDOWS__
|
#else // not __WINDOWS__
|
||||||
|
|
||||||
#ifdef __UNIX_LIKE__
|
|
||||||
|
|
||||||
static char randomBuf[131072];
|
static char randomBuf[131072];
|
||||||
static unsigned int randomPtr = sizeof(randomBuf);
|
static unsigned int randomPtr = sizeof(randomBuf);
|
||||||
static int devURandomFd = -1;
|
static int devURandomFd = -1;
|
||||||
static Mutex globalLock;
|
|
||||||
|
|
||||||
Mutex::Lock _l(globalLock);
|
|
||||||
|
|
||||||
if (devURandomFd <= 0) {
|
if (devURandomFd <= 0) {
|
||||||
devURandomFd = ::open("/dev/urandom",O_RDONLY);
|
devURandomFd = ::open("/dev/urandom",O_RDONLY);
|
||||||
|
@ -215,12 +222,9 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||||
((char *)buf)[i] = randomBuf[randomPtr++];
|
((char *)buf)[i] = randomBuf[randomPtr++];
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // not __UNIX_LIKE__
|
#endif // __WINDOWS__ or not
|
||||||
|
|
||||||
#error No getSecureRandom() implementation available.
|
s20.encrypt12(buf,buf,bytes);
|
||||||
|
|
||||||
#endif // __UNIX_LIKE__
|
|
||||||
#endif // __WINDOWS__
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> Utils::split(const char *s,const char *const sep,const char *esc,const char *quot)
|
std::vector<std::string> Utils::split(const char *s,const char *const sep,const char *esc,const char *quot)
|
||||||
|
|
Loading…
Add table
Reference in a new issue