[libvirt] [PATCH 1/4] util: Add range parameters to virRandomBytes

John Ferlan jferlan at redhat.com
Sun May 22 14:39:12 UTC 2016


Add a minval and maxval range for acceptible values from /dev/urandom

Signed-off-by: John Ferlan <jferlan at 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




More information about the libvir-list mailing list