Selaa lähdekoodia

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.

Adam Ierymenko 12 vuotta sitten
vanhempi
commit
67acba4bc9
2 muutettua tiedostoa jossa 37 lisäystä ja 21 poistoa
  1. 34 21
      node/Utils.cpp
  2. 3 0
      selftest.cpp

+ 34 - 21
node/Utils.cpp

@@ -30,20 +30,23 @@
 #include <stdlib.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 <errno.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/uio.h>
 #include <dirent.h>
 #endif
 
-#ifdef _WIN32
+#ifdef __WINDOWS__
 #include <Windows.h>
 #endif
 
 #include <sys/stat.h>
-#include <openssl/rand.h>
 
 #include "Utils.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)
 {
-	unsigned char tmp[16384];
-	while (!RAND_bytes((unsigned char *)buf,bytes)) {
-#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
-		FILE *rf = fopen("/dev/urandom","r");
-		if (rf) {
-			fread(tmp,sizeof(tmp),1,rf);
-			fclose(rf);
-			RAND_seed(tmp,sizeof(tmp));
-		} else {
-			fprintf(stderr,"FATAL: could not open /dev/urandom\n");
-			exit(-1);
+#ifdef __UNIX_LIKE__
+	static Mutex randomLock;
+	static char randbuf[32768];
+	static unsigned int randptr = sizeof(randbuf);
+
+	Mutex::Lock _l(randomLock);
+	for(unsigned int i=0;i<bytes;++i) {
+		if (randptr >= sizeof(randbuf)) {
+			int fd = ::open("/dev/urandom",O_RDONLY);
+			if (fd < 0) {
+				fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom: %s"ZT_EOL_S,strerror(errno));
+				exit(-1);
+			}
+			if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) {
+				fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S);
+				exit(-1);
+			}
+			::close(fd);
+			randptr = 0;
 		}
-#else
-#ifdef _WIN32
-		error need win32;
-#else
-		error;
-#endif
-#endif
+		((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)

+ 3 - 0
selftest.cpp

@@ -64,6 +64,9 @@ static int testCrypto()
 	unsigned char buf1[16384];
 	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();
 	for(unsigned int k=0;k<64;++k) {
 		EllipticCurveKeyPair kp;