Stop using RAND_ in libcrypto for Utils::getSecureRandom() due to annoying valgrind spew from libcrypto use of uninitialized RAM as a random source. Might look into replacing RAND_ in libcrypto with our own simple /dev/urandom / Windows CAPI plugin.

This commit is contained in:
Adam Ierymenko 2013-08-10 10:12:16 -04:00
parent 9979474f1e
commit 67acba4bc9
2 changed files with 37 additions and 21 deletions

View file

@ -30,20 +30,23 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) #include "Constants.hpp"
#ifdef __UNIX_LIKE__
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/uio.h>
#include <dirent.h> #include <dirent.h>
#endif #endif
#ifdef _WIN32 #ifdef __WINDOWS__
#include <Windows.h> #include <Windows.h>
#endif #endif
#include <sys/stat.h> #include <sys/stat.h>
#include <openssl/rand.h>
#include "Utils.hpp" #include "Utils.hpp"
#include "Mutex.hpp" #include "Mutex.hpp"
@ -375,26 +378,36 @@ unsigned int Utils::unhex(const char *hex,void *buf,unsigned int len)
void Utils::getSecureRandom(void *buf,unsigned int bytes) void Utils::getSecureRandom(void *buf,unsigned int bytes)
{ {
unsigned char tmp[16384]; #ifdef __UNIX_LIKE__
while (!RAND_bytes((unsigned char *)buf,bytes)) { static Mutex randomLock;
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) static char randbuf[32768];
FILE *rf = fopen("/dev/urandom","r"); static unsigned int randptr = sizeof(randbuf);
if (rf) {
fread(tmp,sizeof(tmp),1,rf); Mutex::Lock _l(randomLock);
fclose(rf); for(unsigned int i=0;i<bytes;++i) {
RAND_seed(tmp,sizeof(tmp)); if (randptr >= sizeof(randbuf)) {
} else { int fd = ::open("/dev/urandom",O_RDONLY);
fprintf(stderr,"FATAL: could not open /dev/urandom\n"); if (fd < 0) {
fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom: %s"ZT_EOL_S,strerror(errno));
exit(-1); exit(-1);
} }
#else if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) {
#ifdef _WIN32 fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S);
error need win32; exit(-1);
#else
error;
#endif
#endif
} }
::close(fd);
randptr = 0;
}
((char *)buf)[i] = randbuf[randptr++];
}
#else // !__UNIX_LIKE__
#ifdef __WINDOWS__
probably use windows capi...;
#else // !__WINDOWS__
no getSecureRandom() implementation!
#endif // __WINDOWS__
#endif // __UNIX_LIKE__
} }
void Utils::lockDownFile(const char *path,bool isDir) void Utils::lockDownFile(const char *path,bool isDir)

View file

@ -64,6 +64,9 @@ static int testCrypto()
unsigned char buf1[16384]; unsigned char buf1[16384];
unsigned char buf2[sizeof(buf1)],buf3[sizeof(buf1)]; unsigned char buf2[sizeof(buf1)],buf3[sizeof(buf1)];
//Utils::getSecureRandom(buf1,1024);
//std::cout << "[crypto] getSecureRandom() -> " << Utils::hex(buf1,1024) << std::endl;
std::cout << "[crypto] Testing ECDSA... "; std::cout.flush(); std::cout << "[crypto] Testing ECDSA... "; std::cout.flush();
for(unsigned int k=0;k<64;++k) { for(unsigned int k=0;k<64;++k) {
EllipticCurveKeyPair kp; EllipticCurveKeyPair kp;