libreboot-utils: tidy up rand

make it more efficient. much lower rejection
rate now, about 2-5%. deal with bias, but also
get numbers in bulk. not too many.

i'd say this is about right in terms of performance
balance. 64 bytes == 8 large integers.

Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
Leah Rowe
2026-03-25 19:26:48 +00:00
parent cbe48caf1b
commit a6f76ac4ee
+14 -15
View File
@@ -879,33 +879,32 @@ err:
int int
mkhtemp_fill_random(char *p, size_t xc) mkhtemp_fill_random(char *p, size_t xc)
{ {
static char ch[] = static const char ch[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
size_t chx = 0; unsigned char scratch[64];
size_t r;
/* clamp rand to prevent modulo bias size_t off = 0;
*/ size_t i;
size_t limit = ((size_t)-1) - (((size_t)-1) % (sizeof(ch) - 1));
int saved_errno = errno; /* clamp rand to prevent modulo bias */
size_t limit = 256 - (256 % (sizeof(ch) - 1));
if (if_err(p == NULL, EFAULT)) if (if_err(p == NULL, EFAULT))
return -1; return -1;
for (chx = 0; chx < xc; chx++) {
retry_rand: retry_rand:
rset(&r, sizeof(r)); rset(scratch, sizeof(scratch));
if (r >= limit)
goto retry_rand;
p[chx] = ch[r % (sizeof(ch) - 1)]; for (i = 0; i < sizeof(scratch) && off < xc; i++) {
if (scratch[i] < limit)
p[off++] = ch[scratch[i] % (sizeof(ch) - 1)];
} }
errno = saved_errno; if (off < xc)
return 0; goto retry_rand;
return 0;
} }
/* WARNING: **ONCE** per file. /* WARNING: **ONCE** per file.