From 1ed3ba7933a83434b454ba9d527b7ff4e017fd7d Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 27 May 2012 16:05:56 +0200 Subject: [PATCH] Introduced internal pseudo-random generators iso_random_uuid() and iso_random_8byte(). --- libisofs/make_isohybrid_mbr.c | 117 +-------------------------- libisofs/system_area.c | 144 +++++++++++++++++++++++++++++++--- libisofs/system_area.h | 23 ++++++ 3 files changed, 161 insertions(+), 123 deletions(-) diff --git a/libisofs/make_isohybrid_mbr.c b/libisofs/make_isohybrid_mbr.c index 45058a6..9caa347 100644 --- a/libisofs/make_isohybrid_mbr.c +++ b/libisofs/make_isohybrid_mbr.c @@ -23,17 +23,6 @@ /* for gettimeofday() */ #include -/* >>> 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 -#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; diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 858ee88..cbb0e4a 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -27,6 +27,19 @@ #include #include +/* for gettimeofday() */ +#include + +/* >>> 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 +#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]; + } +} + diff --git a/libisofs/system_area.h b/libisofs/system_area.h index 524b9e5..c5b5be3 100644 --- a/libisofs/system_area.h +++ b/libisofs/system_area.h @@ -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_ */