Add a minval and maxval range for acceptible values from /dev/urandom
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/util/vircrypto.c | 2 +-
src/util/virrandom.c | 13 ++++++++++---
src/util/virrandom.h | 3 ++-
src/util/viruuid.c | 2 +-
tests/qemuxml2argvmock.c | 2 +-
tests/vircryptotest.c | 4 ++--
tests/virrandommock.c | 10 +++++++---
tests/virrandomtest.c | 32 ++++++++++++++++++++++++--------
8 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/src/util/vircrypto.c b/src/util/vircrypto.c
index 4f288f0..4125230 100644
--- a/src/util/vircrypto.c
+++ b/src/util/vircrypto.c
@@ -301,7 +301,7 @@ virCryptoGenerateRandom(size_t nbytes)
/* If we don't have gnutls_rnd(), we will generate a less cryptographically
* strong master buf from /dev/urandom.
*/
- if ((ret = virRandomBytes(buf, nbytes)) < 0) {
+ if ((ret = virRandomBytes(buf, nbytes, 0x00, 0xff)) < 0) {
virReportSystemError(ret, "%s", _("failed to generate byte
stream"));
VIR_FREE(buf);
return NULL;
diff --git a/src/util/virrandom.c b/src/util/virrandom.c
index 62a0e31..256819a 100644
--- a/src/util/virrandom.c
+++ b/src/util/virrandom.c
@@ -164,13 +164,17 @@ uint32_t virRandomInt(uint32_t max)
* virRandomBytes
* @buf: Pointer to location to store bytes
* @buflen: Number of bytes to store
+ * @minval: Minimum value acceptable
+ * @maxval: Minimum value acceptable
*
* Generate a stream of random bytes from /dev/urandom
* into @buf of size @buflen
*/
int
virRandomBytes(unsigned char *buf,
- size_t buflen)
+ size_t buflen,
+ uint8_t minval,
+ uint8_t maxval)
{
int fd;
@@ -187,8 +191,11 @@ virRandomBytes(unsigned char *buf,
return n < 0 ? errno : ENODATA;
}
- buf += n;
- buflen -= n;
+ /* Compare to acceptable range */
+ if (*buf >= minval && *buf <= maxval) {
+ buf += n;
+ buflen -= n;
+ }
}
VIR_FORCE_CLOSE(fd);
diff --git a/src/util/virrandom.h b/src/util/virrandom.h
index f457d2d..6b3fb0f 100644
--- a/src/util/virrandom.h
+++ b/src/util/virrandom.h
@@ -27,7 +27,8 @@
uint64_t virRandomBits(int nbits);
double virRandom(void);
uint32_t virRandomInt(uint32_t max);
-int virRandomBytes(unsigned char *buf, size_t buflen)
+int virRandomBytes(unsigned char *buf, size_t buflen,
+ uint8_t minval, uint8_t maxval)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virRandomGenerateWWN(char **wwn, const char *virt_type);
diff --git a/src/util/viruuid.c b/src/util/viruuid.c
index 3cbaae0..f494adf 100644
--- a/src/util/viruuid.c
+++ b/src/util/viruuid.c
@@ -76,7 +76,7 @@ virUUIDGenerate(unsigned char *uuid)
if (uuid == NULL)
return -1;
- if ((err = virRandomBytes(uuid, VIR_UUID_BUFLEN))) {
+ if ((err = virRandomBytes(uuid, VIR_UUID_BUFLEN, 0x00, 0xff))) {
char ebuf[1024];
VIR_WARN("Falling back to pseudorandom UUID,"
" failed to generate random bytes: %s",
diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c
index c6a1f98..76511af 100644
--- a/tests/qemuxml2argvmock.c
+++ b/tests/qemuxml2argvmock.c
@@ -157,7 +157,7 @@ virCryptoGenerateRandom(size_t nbytes)
if (VIR_ALLOC_N(buf, nbytes) < 0)
return NULL;
- ignore_value(virRandomBytes(buf, nbytes));
+ ignore_value(virRandomBytes(buf, nbytes, 0x00, 0xff));
return buf;
}
diff --git a/tests/vircryptotest.c b/tests/vircryptotest.c
index 72265d9..0dd2cf4 100644
--- a/tests/vircryptotest.c
+++ b/tests/vircryptotest.c
@@ -87,8 +87,8 @@ testCryptoEncrypt(const void *opaque)
VIR_ALLOC_N(iv, ivlen) < 0)
goto cleanup;
- if (virRandomBytes(enckey, enckeylen) < 0 ||
- virRandomBytes(iv, ivlen) < 0)
+ if (virRandomBytes(enckey, enckeylen, 0x00, 0xff) < 0 ||
+ virRandomBytes(iv, ivlen, 0x00, 0xff) < 0)
goto cleanup;
if (virCryptoEncryptData(data->algorithm, enckey, enckeylen, iv, ivlen,
diff --git a/tests/virrandommock.c b/tests/virrandommock.c
index 6df5e20..d988bab 100644
--- a/tests/virrandommock.c
+++ b/tests/virrandommock.c
@@ -28,12 +28,16 @@
int
virRandomBytes(unsigned char *buf,
- size_t buflen)
+ size_t buflen,
+ uint8_t minval,
+ uint8_t maxval)
{
size_t i;
- for (i = 0; i < buflen; i++)
- buf[i] = i;
+ for (i = 0; i < buflen; i++) {
+ if (i >= minval && i <= maxval)
+ buf[i] = i;
+ }
return 0;
}
diff --git a/tests/virrandomtest.c b/tests/virrandomtest.c
index 367bdc7..be148d2 100644
--- a/tests/virrandomtest.c
+++ b/tests/virrandomtest.c
@@ -29,27 +29,31 @@
# define VIR_FROM_THIS VIR_FROM_NONE
+struct testRandomData {
+ uint8_t minval;
+ uint8_t maxval;
+};
+
static int
-testRandomBytes(const void *unused ATTRIBUTE_UNUSED)
+testRandomBytes(const void *opaque)
{
int ret = -1;
size_t i;
uint8_t *data;
size_t datalen = 32;
+ const struct testRandomData *range = opaque;
if (VIR_ALLOC_N(data, datalen) < 0)
return -1;
- if (virRandomBytes(data, datalen) < 0) {
+ if (virRandomBytes(data, datalen, range->minval, range->maxval) < 0) {
fprintf(stderr, "Failed to generate random bytes");
goto cleanup;
}
- for (i = 0; i < datalen; i++) {
+ for (i = range->minval; i < datalen; i++) {
if (data[i] != i) {
- fprintf(stderr,
- "virRandomBytes data[%zu]='%x' not in sequence\n",
- i, data[i]);
+ fprintf(stderr, "data[%zu]='%x' not in sequence\n", i,
data[i]);
goto cleanup;
}
}
@@ -67,8 +71,20 @@ mymain(void)
{
int ret = 0;
- if (virtTestRun("RandomBytes", testRandomBytes, NULL) < 0)
- ret = -1;
+# define DO_TEST(name, min, max) \
+ do { \
+ struct testRandomData range = { \
+ .minval = min, \
+ .maxval = max, \
+ }; \
+ if (virtTestRun("Random " name, testRandomBytes, &range) < 0) \
+ ret = -1; \
+ } while (0);
+
+ DO_TEST("AllBytes", 0x00, 0xff);
+ DO_TEST("Printable", 0x20, 0x7f);
+
+# undef DO_TEST
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
2.5.5