Bladeren bron

CSPRNG performance improvement, self test build fix.

Adam Ierymenko 8 jaren geleden
bovenliggende
commit
21f4a97c35
2 gewijzigde bestanden met toevoegingen van 28 en 23 verwijderingen
  1. 22 17
      node/Utils.cpp
  2. 6 6
      selftest.cpp

+ 22 - 17
node/Utils.cpp

@@ -144,6 +144,8 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
 	static Mutex globalLock;
 	static Salsa20 s20;
 	static bool s20Initialized = false;
+	static uint8_t randomBuf[65536];
+	static unsigned int randomPtr = sizeof(randomBuf);
 
 	Mutex::Lock _l(globalLock);
 
@@ -168,27 +170,31 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
 
 	static HCRYPTPROV cryptProvider = NULL;
 
-	if (cryptProvider == NULL) {
-		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");
-			exit(1);
-			return;
+	for(unsigned int i=0;i<bytes;++i) {
+		if (randomPtr >= sizeof(randomBuf)) {
+			if (cryptProvider == NULL) {
+				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");
+					exit(1);
+				}
+			}
+			if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(randomBuf),(BYTE *)randomBuf)) {
+				fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
+				exit(1);
+			}
+			randomPtr = 0;
+			s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
 		}
-	}
-	if (!CryptGenRandom(cryptProvider,(DWORD)bytes,(BYTE *)buf)) {
-		fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
-		exit(1);
+		((uint8_t *)buf)[i] = randomBuf[randomPtr++];
 	}
 
 #else // not __WINDOWS__
 
-	static char randomBuf[65536];
-	static unsigned int randomPtr = sizeof(randomBuf);
 	static int devURandomFd = -1;
 
-	if (devURandomFd <= 0) {
+	if (devURandomFd < 0) {
 		devURandomFd = ::open("/dev/urandom",O_RDONLY);
-		if (devURandomFd <= 0) {
+		if (devURandomFd < 0) {
 			fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n");
 			exit(1);
 			return;
@@ -201,7 +207,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
 				if ((int)::read(devURandomFd,randomBuf,sizeof(randomBuf)) != (int)sizeof(randomBuf)) {
 					::close(devURandomFd);
 					devURandomFd = ::open("/dev/urandom",O_RDONLY);
-					if (devURandomFd <= 0) {
+					if (devURandomFd < 0) {
 						fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to open /dev/urandom\n");
 						exit(1);
 						return;
@@ -209,13 +215,12 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
 				} else break;
 			}
 			randomPtr = 0;
+			s20.crypt12(randomBuf,randomBuf,sizeof(randomBuf));
 		}
-		((char *)buf)[i] = randomBuf[randomPtr++];
+		((uint8_t *)buf)[i] = randomBuf[randomPtr++];
 	}
 
 #endif // __WINDOWS__ or not
-
-	s20.crypt12(buf,buf,bytes);
 }
 
 bool Utils::scopy(char *dest,unsigned int len,const char *src)

+ 6 - 6
selftest.cpp

@@ -154,9 +154,9 @@ static int testCrypto()
 		memset(buf3,0,sizeof(buf3));
 		Salsa20 s20;
 		s20.init("12345678123456781234567812345678",256,"12345678");
-		s20.encrypt20(buf1,buf2,sizeof(buf1));
+		s20.crypt20(buf1,buf2,sizeof(buf1));
 		s20.init("12345678123456781234567812345678",256,"12345678");
-		s20.decrypt20(buf2,buf3,sizeof(buf2));
+		s20.crypt20(buf2,buf3,sizeof(buf2));
 		if (memcmp(buf1,buf3,sizeof(buf1))) {
 			std::cout << "FAIL (encrypt/decrypt test)" << std::endl;
 			return -1;
@@ -165,7 +165,7 @@ static int testCrypto()
 	Salsa20 s20(s20TV0Key,256,s20TV0Iv);
 	memset(buf1,0,sizeof(buf1));
 	memset(buf2,0,sizeof(buf2));
-	s20.encrypt20(buf1,buf2,64);
+	s20.crypt20(buf1,buf2,64);
 	if (memcmp(buf2,s20TV0Ks,64)) {
 		std::cout << "FAIL (test vector 0)" << std::endl;
 		return -1;
@@ -173,7 +173,7 @@ static int testCrypto()
 	s20.init(s2012TV0Key,256,s2012TV0Iv);
 	memset(buf1,0,sizeof(buf1));
 	memset(buf2,0,sizeof(buf2));
-	s20.encrypt12(buf1,buf2,64);
+	s20.crypt12(buf1,buf2,64);
 	if (memcmp(buf2,s2012TV0Ks,64)) {
 		std::cout << "FAIL (test vector 1)" << std::endl;
 		return -1;
@@ -195,7 +195,7 @@ static int testCrypto()
 		double bytes = 0.0;
 		uint64_t start = OSUtils::now();
 		for(unsigned int i=0;i<200;++i) {
-			s20.encrypt12(bb,bb,1234567);
+			s20.crypt12(bb,bb,1234567);
 			bytes += 1234567.0;
 		}
 		uint64_t end = OSUtils::now();
@@ -213,7 +213,7 @@ static int testCrypto()
 		double bytes = 0.0;
 		uint64_t start = OSUtils::now();
 		for(unsigned int i=0;i<200;++i) {
-			s20.encrypt20(bb,bb,1234567);
+			s20.crypt20(bb,bb,1234567);
 			bytes += 1234567.0;
 		}
 		uint64_t end = OSUtils::now();