Skip to content

Commit a4a6ace

Browse files
Merge pull request #314 from nrclark/randomseed
config: add new randomseed option
2 parents 76ccfcf + 1e1962b commit a4a6ace

File tree

11 files changed

+190
-14
lines changed

11 files changed

+190
-14
lines changed

Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ genimage_SOURCES = \
1818
config.c \
1919
util.c \
2020
crc32.c \
21+
random32.c \
2122
image-android-sparse.c \
2223
image-cpio.c \
2324
image-cramfs.c \
@@ -152,6 +153,8 @@ EXTRA_DIST += \
152153
test/mke2fs.3.dump \
153154
test/qemu.config \
154155
test/qemu.qcow.gz \
156+
test/randomseed.config \
157+
test/randomseed.expected \
155158
test/rauc.config \
156159
test/sharness.sh \
157160
test/signing-ca/ca.cert.pem \

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ variable.
791791

792792
:loglevel: default: 1
793793
genimage log level.
794-
794+
:randomseed: default: none
795+
Random number generator seed (optional).
795796
:outputpath: default: images
796797
Mandatory path where all images are written to (must exist).
797798
:inputpath: default: input

config.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,12 @@ static struct config opts[] = {
489489
.env = "GENIMAGE_QEMU",
490490
.def = "qemu-img",
491491
},
492+
{
493+
.name = "randomseed",
494+
.opt = CFG_STR("randomseed", NULL, CFGF_NONE),
495+
.env = "GENIMAGE_RANDOMSEED",
496+
.def = NULL,
497+
},
492498
{
493499
.name = "rauc",
494500
.opt = CFG_STR("rauc", NULL, CFGF_NONE),

genimage.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include <errno.h>
2222
#include <libgen.h>
2323
#include <sys/stat.h>
24-
#include <sys/time.h>
2524
#include <sys/types.h>
2625
#include <dirent.h>
2726

@@ -700,11 +699,6 @@ int main(int argc, char *argv[])
700699
cfg_opt_t image_end[] = {
701700
CFG_END()
702701
};
703-
struct timeval tv;
704-
705-
/* Seed the rng */
706-
gettimeofday(&tv, NULL);
707-
srandom(tv.tv_usec);
708702

709703
memcpy(imageopts, image_common_opts, sizeof(image_common_opts));
710704

@@ -760,6 +754,13 @@ int main(int argc, char *argv[])
760754
/* again, with config file this time */
761755
set_config_opts(argc, argv, cfg);
762756

757+
str = get_opt("randomseed");
758+
if (!str || (*str == '\0')) {
759+
random32_init();
760+
} else {
761+
random32_enable_prng(str, strnlen(str, 4096));
762+
}
763+
763764
str = get_opt("configdump");
764765
if (str) {
765766
FILE *dump;

genimage.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,8 @@ uint32_t crc32_next(const void *data, size_t len, uint32_t last_crc);
225225

226226
#define ct_assert(e) _Static_assert(e, #e)
227227

228+
void random32_init(void);
229+
void random32_enable_prng(const char *seed, size_t length);
230+
uint32_t random32(void);
231+
228232
#endif /* __PTX_IMAGE_H */

image-hd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ static int setup_uuid(struct image *image, cfg_t *cfg)
871871
if (!disk_signature)
872872
hd->disksig = 0;
873873
else if (!strcmp(disk_signature, "random"))
874-
hd->disksig = random();
874+
hd->disksig = random32();
875875
else {
876876
if (!(hd->table_type & TYPE_MBR)) {
877877
image_error(image, "'disk-signature' is only valid for mbr and hybrid partition-table-type\n");

random32.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* 32-bit xorwow-based PRNG with a seed input. Based on George Marsaglia's
3+
* Xorshift RNGs paper.
4+
*
5+
* Copyright (c) 2025 Nicholas Clark <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License version 2
9+
* as published by the Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include <stdint.h>
21+
#include <stdlib.h>
22+
#include <stdbool.h>
23+
#include <sys/time.h>
24+
25+
#include "genimage.h"
26+
27+
struct prng_state {
28+
uint32_t lane[5];
29+
uint32_t counter;
30+
};
31+
32+
static uint32_t prng_getrandom(struct prng_state *state)
33+
{
34+
uint32_t buffer = state->lane[4];
35+
36+
state->lane[4] = state->lane[3];
37+
state->lane[3] = state->lane[2];
38+
state->lane[2] = state->lane[1];
39+
state->lane[1] = state->lane[0];
40+
41+
buffer ^= buffer >> 2;
42+
buffer ^= buffer << 1;
43+
buffer ^= state->lane[0] ^ (state->lane[0] << 4);
44+
state->lane[0] = buffer;
45+
state->counter += 0x587C5;
46+
47+
return buffer + state->counter;
48+
}
49+
50+
static void prng_seed(struct prng_state *state, uint32_t seed)
51+
{
52+
state->counter = seed;
53+
state->lane[0] = 1 + (seed & 0x0FFFFFFFu);
54+
state->lane[1] = 2 + (seed & 0xFF0FFFFFu);
55+
state->lane[2] = 3 + (seed & 0xFFF00FFFu);
56+
state->lane[3] = 4 + (seed & 0xFFFFF0FFu);
57+
state->lane[4] = 5 + (seed & 0xFFFFFFF0u);
58+
59+
for (int x = 0; x < 8; x++) {
60+
prng_getrandom(state);
61+
}
62+
}
63+
64+
static struct prng_state prng = { { 1, 2, 3, 4, 5 }, 0 };
65+
static bool prng_active = false;
66+
67+
void random32_init(void)
68+
{
69+
struct timeval tv;
70+
gettimeofday(&tv, NULL);
71+
srandom(tv.tv_usec);
72+
prng_active = false;
73+
}
74+
75+
void random32_enable_prng(const char *seed, size_t length)
76+
{
77+
prng_seed(&prng, crc32(seed, length));
78+
prng_active = true;
79+
}
80+
81+
uint32_t random32(void)
82+
{
83+
if (prng_active) {
84+
return prng_getrandom(&prng);
85+
}
86+
return random();
87+
}

test/misc.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,30 @@ test_expect_success "custom" "
143143
echo 'Hello genimage!' > images/test.custom.expect &&
144144
test_cmp images/test.custom.expect images/test.custom
145145
"
146+
test_expect_success "disable random-seed" "
147+
extra_opts="--randomseed=" &&
148+
run_genimage randomseed.config randomseed.img &&
149+
hexdump -C images/randomseed.img > randomseed.expected &&
150+
unset extra_opts &&
151+
test_must_fail diff -q $SHARNESS_TEST_SRCDIR/randomseed.expected randomseed.expected
152+
"
153+
154+
test_expect_success "enable random-seed" "
155+
run_genimage randomseed.config randomseed.img &&
156+
hexdump -C images/randomseed.img > randomseed.expected &&
157+
diff -q $SHARNESS_TEST_SRCDIR/randomseed.expected randomseed.expected
158+
"
159+
160+
test_expect_success "use different random-seeds" "
161+
extra_opts="--randomseed=2" &&
162+
run_genimage randomseed.config randomseed.img &&
163+
hexdump -C images/randomseed.img > randomseed.expected.1 &&
164+
extra_opts="--randomseed=3" &&
165+
run_genimage randomseed.config randomseed.img &&
166+
hexdump -C images/randomseed.img > randomseed.expected.2 &&
167+
unset extra_opts &&
168+
test_must_fail diff -q randomseed.expected.1 randomseed.expected.2
169+
"
146170

147171
exec_test_set_prereq base64
148172
exec_test_set_prereq dd

test/randomseed.config

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
image randomseed.img {
2+
hdimage {
3+
partition-table-type = "gpt"
4+
}
5+
6+
partition rootfs {
7+
size = 1M
8+
}
9+
}
10+
11+
config {
12+
randomseed = 1
13+
}

test/randomseed.expected

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
2+
*
3+
000001c0 02 00 ee 21 29 00 01 00 00 00 47 08 00 00 00 00 |...!).....G.....|
4+
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
5+
*
6+
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
7+
00000200 45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00 |EFI PART....\...|
8+
00000210 a8 9f e4 6e 00 00 00 00 01 00 00 00 00 00 00 00 |...n............|
9+
00000220 47 08 00 00 00 00 00 00 22 00 00 00 00 00 00 00 |G.......".......|
10+
00000230 26 08 00 00 00 00 00 00 18 07 21 30 00 55 81 53 |&.........!0.U.S|
11+
00000240 ff 99 08 fd 68 07 00 40 02 00 00 00 00 00 00 00 |....h..@........|
12+
00000250 80 00 00 00 80 00 00 00 e5 81 84 df 00 00 00 00 |................|
13+
00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
14+
*
15+
00000400 af 3d c6 0f 83 84 72 47 8e 79 3d 69 d8 47 7d e4 |.=....rG.y=i.G}.|
16+
00000410 62 09 50 60 00 40 99 61 ff 94 03 fd 88 82 00 46 |b.P`[email protected]|
17+
00000420 22 00 00 00 00 00 00 00 21 08 00 00 00 00 00 00 |".......!.......|
18+
00000430 00 00 00 00 00 00 00 00 72 00 6f 00 6f 00 74 00 |........r.o.o.t.|
19+
00000440 66 00 73 00 00 00 00 00 00 00 00 00 00 00 00 00 |f.s.............|
20+
00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
21+
*
22+
00104e00 af 3d c6 0f 83 84 72 47 8e 79 3d 69 d8 47 7d e4 |.=....rG.y=i.G}.|
23+
00104e10 62 09 50 60 00 40 99 61 ff 94 03 fd 88 82 00 46 |b.P`[email protected]|
24+
00104e20 22 00 00 00 00 00 00 00 21 08 00 00 00 00 00 00 |".......!.......|
25+
00104e30 00 00 00 00 00 00 00 00 72 00 6f 00 6f 00 74 00 |........r.o.o.t.|
26+
00104e40 66 00 73 00 00 00 00 00 00 00 00 00 00 00 00 00 |f.s.............|
27+
00104e50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
28+
*
29+
00108e00 45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00 |EFI PART....\...|
30+
00108e10 e3 54 c1 02 00 00 00 00 47 08 00 00 00 00 00 00 |.T......G.......|
31+
00108e20 01 00 00 00 00 00 00 00 22 00 00 00 00 00 00 00 |........".......|
32+
00108e30 26 08 00 00 00 00 00 00 18 07 21 30 00 55 81 53 |&.........!0.U.S|
33+
00108e40 ff 99 08 fd 68 07 00 40 27 08 00 00 00 00 00 00 |....h..@'.......|
34+
00108e50 80 00 00 00 80 00 00 00 e5 81 84 df 00 00 00 00 |................|
35+
00108e60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
36+
*
37+
00109000

0 commit comments

Comments
 (0)