crypto: qcrypto_random_bytes() now works on windows w/o any other crypto libs
If no crypto library is included in the build, QEMU uses qcrypto_random_bytes() to generate random data. That function tried to open /dev/urandom or /dev/random and if opening both files failed it errored out. Those files obviously do not exist on windows, so there the code uses CryptGenRandom(). Furthermore there was some refactoring and a new function qcrypto_random_init() was introduced. If a proper crypto library (gnutls or libgcrypt) is included in the build, this function does nothing. If neither is included it initializes the (platform specific) handles that are used by qcrypto_random_bytes(). Either: * a handle to /dev/urandom | /dev/random on unix like systems * a handle to a cryptographic service provider on windows Signed-off-by: Geert Martin Ijewski <gm.ijewski@web.de> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
e4a3507e86
commit
a37278169d
@ -32,6 +32,8 @@
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include "crypto/random.h"
|
||||
|
||||
/* #define DEBUG_GNUTLS */
|
||||
|
||||
/*
|
||||
@ -146,5 +148,9 @@ int qcrypto_init(Error **errp)
|
||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif
|
||||
|
||||
if (qcrypto_random_init(errp) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,3 +31,5 @@ int qcrypto_random_bytes(uint8_t *buf,
|
||||
gcry_randomize(buf, buflen, GCRY_STRONG_RANDOM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qcrypto_random_init(Error **errp G_GNUC_UNUSED) { return 0; }
|
||||
|
@ -41,3 +41,6 @@ int qcrypto_random_bytes(uint8_t *buf,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int qcrypto_random_init(Error **errp G_GNUC_UNUSED) { return 0; }
|
||||
|
@ -22,14 +22,16 @@
|
||||
|
||||
#include "crypto/random.h"
|
||||
|
||||
int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
||||
size_t buflen G_GNUC_UNUSED,
|
||||
Error **errp)
|
||||
{
|
||||
int fd;
|
||||
int ret = -1;
|
||||
int got;
|
||||
#ifdef _WIN32
|
||||
#include <Wincrypt.h>
|
||||
static HCRYPTPROV hCryptProv;
|
||||
#else
|
||||
static int fd; /* a file handle to either /dev/urandom or /dev/random */
|
||||
#endif
|
||||
|
||||
int qcrypto_random_init(Error **errp)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
/* TBD perhaps also add support for BSD getentropy / Linux
|
||||
* getrandom syscalls directly */
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
@ -41,6 +43,25 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
||||
error_setg(errp, "No /dev/urandom or /dev/random found");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
|
||||
error_setg_win32(errp, GetLastError(),
|
||||
"Unable to create cryptographic provider");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
||||
size_t buflen G_GNUC_UNUSED,
|
||||
Error **errp)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int ret = -1;
|
||||
int got;
|
||||
|
||||
while (buflen > 0) {
|
||||
got = read(fd, buf, buflen);
|
||||
@ -59,6 +80,14 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
close(fd);
|
||||
return ret;
|
||||
#else
|
||||
if (!CryptGenRandom(hCryptProv, buflen, buf)) {
|
||||
error_setg_win32(errp, GetLastError(),
|
||||
"Unable to read random bytes");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -40,5 +40,14 @@ int qcrypto_random_bytes(uint8_t *buf,
|
||||
size_t buflen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_random_init:
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Initializes the handles used by qcrypto_random_bytes
|
||||
*
|
||||
* Returns 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_random_init(Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_RANDOM_H */
|
||||
|
Loading…
Reference in New Issue
Block a user