.
This commit is contained in:
parent
8915b88de5
commit
a92967a7c1
1 changed files with 25 additions and 43 deletions
|
@ -37,6 +37,8 @@
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Mutex.hpp"
|
#include "Mutex.hpp"
|
||||||
#include "Salsa20.hpp"
|
#include "Salsa20.hpp"
|
||||||
|
#include "AES.hpp"
|
||||||
|
#include "SHA512.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -140,14 +142,11 @@ unsigned int Utils::unhex(const char *h,unsigned int hlen,void *buf,unsigned int
|
||||||
void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||||
{
|
{
|
||||||
static Mutex globalLock;
|
static Mutex globalLock;
|
||||||
static Salsa20 s20;
|
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static uint8_t randomBuf[131072];
|
static uint8_t randomBuf[131072];
|
||||||
static unsigned int randomPtr = sizeof(randomBuf);
|
static unsigned long randomPtr = sizeof(randomBuf);
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
static HCRYPTPROV cryptProvider = NULL;
|
static HCRYPTPROV cryptProvider = NULL;
|
||||||
#else
|
|
||||||
static int devURandomFd = -1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mutex::Lock _l(globalLock);
|
Mutex::Lock _l(globalLock);
|
||||||
|
@ -160,63 +159,46 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
|
||||||
* at almost no cost and with no real downside if the random source is
|
* at almost no cost and with no real downside if the random source is
|
||||||
* good. */
|
* good. */
|
||||||
if (unlikely(!initialized)) {
|
if (unlikely(!initialized)) {
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
uint64_t s20Key[4];
|
|
||||||
s20Key[0] = (uint64_t)time(nullptr);
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
s20Key[1] = (uint64_t)buf; // address of buf
|
|
||||||
#else
|
|
||||||
s20Key[1] = (uint64_t)getpid();
|
|
||||||
#endif
|
|
||||||
s20Key[2] = (uint64_t)s20Key; // address of s20Key[]
|
|
||||||
s20Key[3] = (uint64_t)&s20; // address of s20
|
|
||||||
s20.init(s20Key,s20Key);
|
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
|
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n");
|
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomBuf),(BYTE *)randomBuf)) {
|
||||||
|
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
devURandomFd = ::open("/dev/urandom",O_RDONLY);
|
int devURandomFd = ::open("/dev/urandom",O_RDONLY);
|
||||||
if (devURandomFd < 0) {
|
if (devURandomFd < 0) {
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n");
|
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if ((int)::read(devURandomFd,randomBuf,sizeof(randomBuf)) != (int)sizeof(randomBuf)) {
|
||||||
|
::close(devURandomFd);
|
||||||
|
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to read from /dev/urandom\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
close(devURandomFd);
|
||||||
#endif
|
#endif
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
|
|
||||||
for(unsigned int i=0;i<bytes;++i) {
|
for(unsigned int i=0;i<bytes;++i) {
|
||||||
if (unlikely(randomPtr >= sizeof(randomBuf))) {
|
if (randomPtr >= sizeof(randomBuf)) {
|
||||||
randomPtr = 0;
|
uint8_t h[64];
|
||||||
if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomBuf),(BYTE *)randomBuf)) {
|
SHA512(h,randomBuf,sizeof(randomBuf));
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
|
if (AES::HW_ACCEL) {
|
||||||
exit(1);
|
AES c(h);
|
||||||
|
c.ctr(h + 32,randomBuf,sizeof(randomBuf),randomBuf);
|
||||||
|
} else {
|
||||||
|
Salsa20 c(h,h + 32);
|
||||||
|
c.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
||||||
}
|
}
|
||||||
s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
randomPtr = 0;
|
||||||
}
|
}
|
||||||
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // not __WINDOWS__
|
|
||||||
|
|
||||||
for(unsigned int i=0;i<bytes;++i) {
|
|
||||||
if (unlikely(randomPtr >= sizeof(randomBuf))) {
|
|
||||||
randomPtr = 0;
|
|
||||||
if ((int)::read(devURandomFd,randomBuf,sizeof(randomBuf)) != (int)sizeof(randomBuf)) {
|
|
||||||
::close(devURandomFd);
|
|
||||||
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to read from /dev/urandom\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
|
|
||||||
}
|
|
||||||
((uint8_t *)buf)[i] = randomBuf[randomPtr++];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __WINDOWS__ or not
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Utils::b32e(const uint8_t *data,int length,char *result,int bufSize)
|
int Utils::b32e(const uint8_t *data,int length,char *result,int bufSize)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue