Introduced internal pseudo-random generators iso_random_uuid() and
iso_random_8byte().
This commit is contained in:
parent
3e2479c095
commit
1ed3ba7933
@ -23,17 +23,6 @@
|
||||
/* for gettimeofday() */
|
||||
#include <sys/time.h>
|
||||
|
||||
/* >>> ISOHYBRID : Need ./configure test for uuid_generate() which checks for:
|
||||
uuid_t, uuid_generate, the need for -luuid
|
||||
*/
|
||||
/* <<<
|
||||
#define Libisofs_with_uuid_generatE 1
|
||||
*/
|
||||
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
#include "filesrc.h"
|
||||
#include "ecma119.h"
|
||||
#include "eltorito.h"
|
||||
@ -455,106 +444,6 @@ static int insert_apm_head(uint8_t *buf, int apm_count)
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
|
||||
static void swap_uuid(void *u_pt)
|
||||
{
|
||||
uint8_t tr, *u;
|
||||
|
||||
u = (uint8_t *) u_pt;
|
||||
tr = u[0]; u[0] = u[3]; u[3] = tr;
|
||||
tr = u[1]; u[1] = u[2]; u[2] = tr;
|
||||
tr = u[4]; u[4] = u[5]; u[5] = tr;
|
||||
tr = u[6]; u[6] = u[7]; u[7] = tr;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_uuid_generatE */
|
||||
|
||||
|
||||
/* CRC-32 as of GPT and Ethernet.
|
||||
Parameters are deduced from a table driven implementation in isohybrid.c
|
||||
*/
|
||||
static unsigned int crc32_gpt(unsigned char *data, int count, int flag)
|
||||
{
|
||||
unsigned int acc, top, result = 0;
|
||||
long int i;
|
||||
|
||||
/* Chosen so that the CRC of 0 bytes of input is 0x00000000 */
|
||||
acc = 0x46af6449;
|
||||
|
||||
/* Process data bits and flush numerator by 32 zero bits */
|
||||
for (i = 0; i < count * 8 + 32; i++) {
|
||||
top = acc & 0x80000000;
|
||||
acc = (acc << 1);
|
||||
if (i < count * 8)
|
||||
/* The least significant bits of input bytes get processed first */
|
||||
acc |= ((data[i / 8] >> (i % 8)) & 1);
|
||||
if (top)
|
||||
/* Division by the generating polynomial */
|
||||
acc ^= 0x04c11db7;
|
||||
}
|
||||
/* Mirror residue bits */
|
||||
for (i = 0; i < 32; i++)
|
||||
if (acc & (1 << i))
|
||||
result |= 1 << (31 - i);
|
||||
/* Return bit complement */
|
||||
return result ^ 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
static void random_uuid(Ecma119Image *t, uint8_t *uuid)
|
||||
{
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
uuid_t u;
|
||||
#else
|
||||
uint8_t u[16];
|
||||
/* produced by uuidgen(1) by Andreas Dilger */
|
||||
static uint8_t uuid_template[16] = {
|
||||
0x6e, 0xf5, 0xa3, 0x8b, 0xcb, 0xfa, 0xdd, 0x4e,
|
||||
0x36, 0x9f, 0x0b, 0x12, 0x51, 0xc3, 0x7d, 0x1a
|
||||
};
|
||||
uint32_t rnd, salt;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
static int counter = 0;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
|
||||
uuid_generate(u);
|
||||
swap_uuid((void *) u);
|
||||
memcpy(wpt, u, 16);
|
||||
|
||||
#else
|
||||
|
||||
salt = crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0);
|
||||
|
||||
/* This relies on the uniqueness of the template and the rareness of
|
||||
bootable ISO image production via libisofs. Estimated 53 bits of
|
||||
entropy should influence the production of a single day.
|
||||
So first collisions are to be expected with about 100 million images
|
||||
per day.
|
||||
*/
|
||||
memcpy(u, uuid_template, 16);
|
||||
gettimeofday(&tv, &tz);
|
||||
for (i = 0; i < 4; i++)
|
||||
u[3 + i] = (salt >> (8 * i)) & 0xff;
|
||||
u[8] = (salt >> 8) & 0xff;
|
||||
rnd = ((0xffffffffff & tv.tv_sec) << 8) |
|
||||
(((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff);
|
||||
u[9] ^= counter & 0xff;
|
||||
for (i = 0; i < 4; i++)
|
||||
u[10 + i] ^= (rnd >> (8 * i)) & 0xff;
|
||||
u[14] ^= (tv.tv_usec >> 8) & 0xff;
|
||||
u[15] ^= tv.tv_usec & 0xff;
|
||||
counter++;
|
||||
|
||||
#endif /* ! Libisofs_with_uuid_generatE */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Describe the first three GPT boot images as MBR partitions */
|
||||
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||
int gpt_idx[128], int *gpt_cursor)
|
||||
@ -598,7 +487,7 @@ static void write_gpt_entry(Ecma119Image *t, char *buf, uint8_t type_guid[16],
|
||||
|
||||
memcpy(wpt, type_guid, 16);
|
||||
wpt += 16;
|
||||
random_uuid(t, (uint8_t *) wpt);
|
||||
iso_random_uuid(t, (uint8_t *) wpt);
|
||||
wpt += 16;
|
||||
lsb_to_buf(&wpt, start_lba & 0xffffffff, 32, 0);
|
||||
lsb_to_buf(&wpt, (start_lba >> 32) & 0xffffffff, 32, 0);
|
||||
@ -692,7 +581,7 @@ static int write_gpt_header_block(Ecma119Image *t, char *buf,
|
||||
lsb_to_buf(&wpt, (uint32_t) ((back_lba - 32) >> 32), 32, 1);
|
||||
|
||||
/* Disk GUID */
|
||||
random_uuid(t, (uint8_t *) wpt);
|
||||
iso_random_uuid(t, (uint8_t *) wpt);
|
||||
wpt += 16;
|
||||
|
||||
/* Partition entries start */
|
||||
@ -720,7 +609,7 @@ static int write_gpt_header_block(Ecma119Image *t, char *buf,
|
||||
|
||||
/* CRC-32 of this header while head_crc is 0 */
|
||||
wpt = buf + 16;
|
||||
crc = crc32_gpt((unsigned char *) buf, wpt - buf, 0);
|
||||
crc = iso_crc32_gpt((unsigned char *) buf, wpt - buf, 0);
|
||||
lsb_to_buf(&wpt, crc, 32, 0);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
|
@ -27,6 +27,19 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* for gettimeofday() */
|
||||
#include <sys/time.h>
|
||||
|
||||
/* >>> Need ./configure test for uuid_generate() which checks for:
|
||||
uuid_t, uuid_generate, the need for -luuid
|
||||
*/
|
||||
/*
|
||||
#define Libisofs_with_uuid_generatE 1
|
||||
*/
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||
@ -834,7 +847,8 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
||||
}
|
||||
if (part_end > goal) {
|
||||
|
||||
/* >>> Overlapping partition. ??? Warn ??? Bail out ??? */;
|
||||
/* >>> Overlapping partition. */;
|
||||
/* >>> Vladimir: "Throw error." */;
|
||||
|
||||
}
|
||||
if (part_end < goal) {
|
||||
@ -924,14 +938,6 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
Note that Block0 of the APM is not written but is in the responsibility
|
||||
of the MBR template. Its block size MUST match t->apm_block_size.
|
||||
|
||||
>>> ts B20526
|
||||
>>> ??? Shall i check t->system_area_data whether there are the first
|
||||
>>> ??? four bytes of a Block0 and what block size they announce ?
|
||||
>>> pro: That would prevent cruel mishaps
|
||||
>>> con: t->system_area_data is totally opaque up to now.
|
||||
>>> I cannot easily predict whether the first bytes get altered
|
||||
>>> in the course of processing.
|
||||
|
||||
>>> ts B20526
|
||||
>>> This does not care for eventual image enlargements in last minute.
|
||||
>>> A sa_type, that does this, will have to adjust the last APM entry
|
||||
@ -1170,3 +1176,123 @@ int iso_register_apm_entry(Ecma119Image *t,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
|
||||
static void swap_uuid(void *u_pt)
|
||||
{
|
||||
uint8_t tr, *u;
|
||||
|
||||
u = (uint8_t *) u_pt;
|
||||
tr = u[0]; u[0] = u[3]; u[3] = tr;
|
||||
tr = u[1]; u[1] = u[2]; u[2] = tr;
|
||||
tr = u[4]; u[4] = u[5]; u[5] = tr;
|
||||
tr = u[6]; u[6] = u[7]; u[7] = tr;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_uuid_generatE */
|
||||
|
||||
|
||||
/* CRC-32 as of GPT and Ethernet.
|
||||
Parameters are deduced from a table driven implementation in isohybrid.c
|
||||
*/
|
||||
unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag)
|
||||
{
|
||||
unsigned int acc, top, result = 0;
|
||||
long int i;
|
||||
|
||||
/* Chosen so that the CRC of 0 bytes of input is 0x00000000 */
|
||||
acc = 0x46af6449;
|
||||
|
||||
/* Process data bits and flush numerator by 32 zero bits */
|
||||
for (i = 0; i < count * 8 + 32; i++) {
|
||||
top = acc & 0x80000000;
|
||||
acc = (acc << 1);
|
||||
if (i < count * 8)
|
||||
/* The least significant bits of input bytes get processed first */
|
||||
acc |= ((data[i / 8] >> (i % 8)) & 1);
|
||||
if (top)
|
||||
/* Division by the generating polynomial */
|
||||
acc ^= 0x04c11db7;
|
||||
}
|
||||
/* Mirror residue bits */
|
||||
for (i = 0; i < 32; i++)
|
||||
if (acc & (1 << i))
|
||||
result |= 1 << (31 - i);
|
||||
/* Return bit complement */
|
||||
return result ^ 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16])
|
||||
{
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
uuid_t u;
|
||||
#else
|
||||
uint8_t u[16];
|
||||
/* produced by uuid_generate() and byte-swapped to isohybrid.c habits */
|
||||
static uint8_t uuid_template[16] = {
|
||||
0xee, 0x29, 0x9d, 0xfc, 0x65, 0xcc, 0x7c, 0x40,
|
||||
0x92, 0x61, 0x5b, 0xcd, 0x6f, 0xed, 0x08, 0x34
|
||||
};
|
||||
uint32_t rnd, salt;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
pid_t pid;
|
||||
static int counter = 0;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_uuid_generatE
|
||||
|
||||
uuid_generate(u);
|
||||
swap_uuid((void *) u);
|
||||
memcpy(uuid, u, 16);
|
||||
|
||||
#else
|
||||
|
||||
salt = iso_crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0);
|
||||
salt ^= getpid();
|
||||
|
||||
/* This relies on the uniqueness of the template and the rareness of
|
||||
bootable ISO image production via libisofs. Estimated 53 bits of
|
||||
entropy should influence the production of a single day.
|
||||
So first collisions are to be expected with about 100 million images
|
||||
per day.
|
||||
*/
|
||||
memcpy(u, uuid_template, 16);
|
||||
gettimeofday(&tv, &tz);
|
||||
for (i = 0; i < 4; i++)
|
||||
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;
|
||||
rnd = ((0xffffffffff & tv.tv_sec) << 8) |
|
||||
(((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff);
|
||||
u[9] ^= counter & 0xff;
|
||||
for (i = 0; i < 4; i++)
|
||||
u[10 + i] ^= (rnd >> (8 * i)) & 0xff;
|
||||
u[14] ^= (tv.tv_usec >> 8) & 0xff;
|
||||
u[15] ^= tv.tv_usec & 0xff;
|
||||
counter++;
|
||||
|
||||
memcpy(uuid, u, 16);
|
||||
|
||||
#endif /* ! Libisofs_with_uuid_generatE */
|
||||
|
||||
}
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,4 +103,27 @@ int iso_quick_apm_entry(Ecma119Image *t,
|
||||
uint32_t start_block, uint32_t block_count, char *name, char *type);
|
||||
|
||||
|
||||
/* CRC-32 as of GPT and Ethernet.
|
||||
*/
|
||||
unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag);
|
||||
|
||||
|
||||
/* These two pseudo-random generators produce byte strings which will
|
||||
surely not duplicate in the first 256 calls. If more calls are necessary
|
||||
in the same process, then one must wait until the output of
|
||||
gettimeofday(2) changes.
|
||||
It is advised to obtain them as late as possible, so that Ecma119Image *t
|
||||
can distinguish itself from other image production setups which might be
|
||||
run on other machines with the same process number at the same time.
|
||||
*/
|
||||
|
||||
/* Produces a weakly random variation of a hardcoded real random uuid
|
||||
*/
|
||||
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]);
|
||||
|
||||
|
||||
#endif /* SYSTEM_AREA_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user