Improved quality of random UUIDs
This commit is contained in:
parent
a585d6a32d
commit
46bb5945c6
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user