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>
|
#include <gcrypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "crypto/random.h"
|
||||||
|
|
||||||
/* #define DEBUG_GNUTLS */
|
/* #define DEBUG_GNUTLS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -146,5 +148,9 @@ int qcrypto_init(Error **errp)
|
|||||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (qcrypto_random_init(errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -31,3 +31,5 @@ int qcrypto_random_bytes(uint8_t *buf,
|
|||||||
gcry_randomize(buf, buflen, GCRY_STRONG_RANDOM);
|
gcry_randomize(buf, buflen, GCRY_STRONG_RANDOM);
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int qcrypto_random_init(Error **errp G_GNUC_UNUSED) { return 0; }
|
||||||
|
@ -22,14 +22,16 @@
|
|||||||
|
|
||||||
#include "crypto/random.h"
|
#include "crypto/random.h"
|
||||||
|
|
||||||
int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
#ifdef _WIN32
|
||||||
size_t buflen G_GNUC_UNUSED,
|
#include <Wincrypt.h>
|
||||||
Error **errp)
|
static HCRYPTPROV hCryptProv;
|
||||||
{
|
#else
|
||||||
int fd;
|
static int fd; /* a file handle to either /dev/urandom or /dev/random */
|
||||||
int ret = -1;
|
#endif
|
||||||
int got;
|
|
||||||
|
|
||||||
|
int qcrypto_random_init(Error **errp)
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
/* TBD perhaps also add support for BSD getentropy / Linux
|
/* TBD perhaps also add support for BSD getentropy / Linux
|
||||||
* getrandom syscalls directly */
|
* getrandom syscalls directly */
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
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");
|
error_setg(errp, "No /dev/urandom or /dev/random found");
|
||||||
return -1;
|
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) {
|
while (buflen > 0) {
|
||||||
got = read(fd, buf, buflen);
|
got = read(fd, buf, buflen);
|
||||||
@ -59,6 +80,14 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
close(fd);
|
|
||||||
return ret;
|
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,
|
size_t buflen,
|
||||||
Error **errp);
|
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 */
|
#endif /* QCRYPTO_RANDOM_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user