From 46bb5945c60165249b8410a91be846c8cdb64270 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 22 Oct 2012 18:59:07 +0200 Subject: [PATCH] Improved quality of random UUIDs --- libisofs/system_area.c | 49 ++++++++++++++++++++++++++---------------- libisofs/system_area.h | 4 ---- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 12644c2..abc5a9b 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -27,6 +27,7 @@ #include #include #include +#include /* for gettimeofday() */ #include @@ -1852,12 +1853,13 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]) 0xee, 0x29, 0x9d, 0xfc, 0x65, 0xcc, 0x7c, 0x40, 0x92, 0x61, 0x5b, 0xcd, 0x6f, 0xed, 0x08, 0x34 }; + static uint8_t uuid_urandom[16]; uint32_t rnd, salt; struct timeval tv; struct timezone tz; pid_t pid; - static int counter = 0; - int i; + static int counter = 0, use_urandom = 0; + int i, ret, fd; #endif #ifdef Libisofs_with_uuid_generatE @@ -1868,6 +1870,32 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]) #else + /* First try /dev/urandom. + (Weakening the result by 8 bit saves a lot of pool entropy.) + */ + if ((counter & 0xff) == 0) { + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + goto fallback; + ret = read(fd, uuid_urandom, 16); + if (ret != 16) { + close(fd); + goto fallback; + } + /* Mark as UUID version 4 */ + uuid_urandom[7] = (uuid_urandom[7] & 0x0f) | 0x40; + uuid_urandom[8] = (uuid_urandom[8] & 0x3f) | 0x80; + close(fd); + use_urandom = 1; + } + if (!use_urandom) + goto fallback; + memcpy(uuid, uuid_urandom, 16); + uuid[9] ^= counter & 0xff; + counter++; + return; + +fallback:; pid = getpid(); salt = iso_crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0) ^ pid; @@ -1883,7 +1911,7 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]) u[i] = (salt >> (8 * i)) & 0xff; for (i = 0; i < 2; i++) u[4 + i] = (pid >> (8 * i)) & 0xff; - u[6] = ((salt >> 8) | (pid >> 16)) & 0xff; + u[6] = ((salt >> 8) ^ (pid >> 16)) & 0xff; rnd = ((0xffffff & tv.tv_sec) << 8) | (((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff); u[9] ^= counter & 0xff; @@ -1900,21 +1928,6 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]) } -void iso_random_8byte(Ecma119Image *t, uint8_t result[8]) -{ - uint8_t uuid[16]; - int i; - - iso_random_uuid(t, uuid); - for (i = 0; i < 8; i++) { - if (i == 1) - result[i] = uuid[9]; /* The intra-process counter */ - else - result[i] = uuid[i] ^ uuid[i + 8]; - } -} - - /* Probably already called by tail_writer_compute_data_blocks via iso_align_isohybrid */ diff --git a/libisofs/system_area.h b/libisofs/system_area.h index 2be6da4..9585fde 100644 --- a/libisofs/system_area.h +++ b/libisofs/system_area.h @@ -186,10 +186,6 @@ unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag); */ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]); -/* Produces a weakly random variation of a hardcoded real random template -*/ -void iso_random_8byte(Ecma119Image *t, uint8_t result[8]); - /* The parameter struct for production of a single GPT entry. See also the partial GPT description in doc/boot_sectors.txt.