]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukrandom: Tighten the implementation of ukswrand
authorMichalis Pappas <michalis@unikraft.io>
Mon, 2 Dec 2024 13:12:53 +0000 (14:12 +0100)
committerUnikraft Bot <monkey@unikraft.io>
Wed, 4 Dec 2024 15:24:38 +0000 (15:24 +0000)
Add an internal check to ensure that the CSPRNG has been initialized.
This is an additional check so that we don't merely rely on the caller's
logic. Use __check_result on the definition of uk_swrand_randr().

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Maria Pana <maria.pana4@gmail.com>
Reviewed-by: Alex Apostolescu <alexx.apostolescu@gmail.com>
Reviewed-by: Simon Kuenzer <simon@unikraft.io>
Approved-by: Simon Kuenzer <simon@unikraft.io>
GitHub-Closes: #1496

lib/ukrandom/chacha.c
lib/ukrandom/random.c
lib/ukrandom/swrand.h

index 8bdd9d6aa84fed516eaa9a72f0e5ae4a6006d19f..8a5631767872f8085f6f078da357f4a5f9ee6dfe 100644 (file)
@@ -75,6 +75,12 @@ UK_LIBPARAM_PARAM_ARR_ALIAS(seed, seedv_cmdl, __u32, CHACHA_SEED_LENGTH,
                            "ChaCha20 256-bit key");
 #endif /* CONFIG_LIBUKRANDOM_CMDLINE_SEED */
 
+/* It is critical that the internal state is initialized before we generate
+ * random numbers. Instead of relying on the calling API, use this as an
+ * additional failsafe for self-protection.
+ */
+static __bool initialized = __false;
+
 /* This value isn't important, as long as it's sufficiently asymmetric */
 static const char sigma[16] = "expand 32-byte k";
 
@@ -191,6 +197,7 @@ int uk_swrand_fdt_init(void *fdt, struct uk_random_driver **drv)
        *drv = (void *)UK_SWRAND_DRIVER_NONE;
 
        chacha_init(&uk_swrand_def, seedv);
+       initialized = __true;
 
        return rc;
 }
@@ -217,6 +224,7 @@ int uk_swrand_cmdline_init(struct uk_random_driver **drv)
        *drv = (void *)UK_SWRAND_DRIVER_NONE;
 
        chacha_init(&uk_swrand_def, seedv_cmdl);
+       initialized = __true;
 
        return 0;
 }
@@ -246,11 +254,12 @@ int uk_swrand_init(struct uk_random_driver **drv)
        uk_pr_info("Entropy source: %s\n", (*drv)->name);
 
        chacha_init(&uk_swrand_def, seedv);
+       initialized = __true;
 
        return 0;
 }
 
-static __u32 uk_swrand_randr_r(struct uk_swrand *r)
+static inline __u32 uk_swrand_randr_r(struct uk_swrand *r)
 {
        __u32 res;
 
@@ -270,13 +279,14 @@ static __u32 uk_swrand_randr_r(struct uk_swrand *r)
        }
 }
 
-__u32 uk_swrand_randr(void)
+int __check_result uk_swrand_randr(__u32 *val)
 {
-       __u32 ret;
+       if (unlikely(initialized == __false))
+               return -ENODEV;
 
        uk_spin_lock(&swrand_lock);
-       ret = uk_swrand_randr_r(&uk_swrand_def);
+       *val = uk_swrand_randr_r(&uk_swrand_def);
        uk_spin_unlock(&swrand_lock);
 
-       return ret;
+       return 0;
 }
index 115fc3b49b18e2f24b5ef13cca47eadb1d632982..692f28c6664cf7589a1d356ab7334e33bae56edd 100644 (file)
@@ -51,6 +51,7 @@ int __check_result uk_random_fill_buffer(void *buf, size_t buflen)
 {
        __sz step, chunk_size, i;
        __u32 rd;
+       int rc;
 
        if (!driver)
                return -ENODEV;
@@ -58,12 +59,18 @@ int __check_result uk_random_fill_buffer(void *buf, size_t buflen)
        step = sizeof(__u32);
        chunk_size = buflen % step;
 
-       for (i = 0; i < buflen - chunk_size; i += step)
-               *(__u32 *)((char *)buf + i) = uk_swrand_randr();
+       for (i = 0; i < buflen - chunk_size; i += step) {
+               rc = uk_swrand_randr(&rd);
+               if (unlikely(rc))
+                       return rc;
+               *(__u32 *)((char *)buf + i) = rd;
+       }
 
        /* fill the remaining bytes of the buffer */
        if (chunk_size > 0) {
-               rd = uk_swrand_randr();
+               rc = uk_swrand_randr(&rd);
+               if (unlikely(rc))
+                       return rc;
                memcpy(buf + i, &rd, chunk_size);
        }
 
index 959971cf02c8819226d13e353eb255a390cdfe10..f210e28374414dc46d5f7472935444ad387dd3c2 100644 (file)
@@ -30,6 +30,6 @@ int uk_swrand_cmdline_init(struct uk_random_driver **drv);
 int uk_swrand_init(struct uk_random_driver **drv);
 
 /* Get a 32-bit random number */
-__u32 uk_swrand_randr(void);
+int __check_result uk_swrand_randr(__u32 *val);
 
 #endif /* __UK_RANDOM_SWRAND_H__ */