Improved quality of random UUIDs

This commit is contained in:
Thomas Schmitt 2012-10-22 18:59:07 +02:00
parent a585d6a32d
commit 46bb5945c6
2 changed files with 31 additions and 22 deletions

View File

@ -27,6 +27,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
/* for gettimeofday() */ /* for gettimeofday() */
#include <sys/time.h> #include <sys/time.h>
@ -1852,12 +1853,13 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16])
0xee, 0x29, 0x9d, 0xfc, 0x65, 0xcc, 0x7c, 0x40, 0xee, 0x29, 0x9d, 0xfc, 0x65, 0xcc, 0x7c, 0x40,
0x92, 0x61, 0x5b, 0xcd, 0x6f, 0xed, 0x08, 0x34 0x92, 0x61, 0x5b, 0xcd, 0x6f, 0xed, 0x08, 0x34
}; };
static uint8_t uuid_urandom[16];
uint32_t rnd, salt; uint32_t rnd, salt;
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
pid_t pid; pid_t pid;
static int counter = 0; static int counter = 0, use_urandom = 0;
int i; int i, ret, fd;
#endif #endif
#ifdef Libisofs_with_uuid_generatE #ifdef Libisofs_with_uuid_generatE
@ -1868,6 +1870,32 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16])
#else #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(); pid = getpid();
salt = iso_crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0) ^ pid; 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; u[i] = (salt >> (8 * i)) & 0xff;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
u[4 + i] = (pid >> (8 * i)) & 0xff; 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) | rnd = ((0xffffff & tv.tv_sec) << 8) |
(((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff); (((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff);
u[9] ^= counter & 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 /* Probably already called by tail_writer_compute_data_blocks via
iso_align_isohybrid iso_align_isohybrid
*/ */

View File

@ -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]); 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. /* The parameter struct for production of a single GPT entry.
See also the partial GPT description in doc/boot_sectors.txt. See also the partial GPT description in doc/boot_sectors.txt.