Add a minval and maxval range for acceptible values from /dev/urandom Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list