wok rev 17591

syslinux/isohybrib.exe: add --md5, --undo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Feb 10 08:53:27 2015 +0100 (2015-02-10)
parents 93ebe04d2558
children 24b07aa2fafd
files syslinux/stuff/iso2exe/init syslinux/stuff/iso2exe/iso2exe.c syslinux/stuff/iso2exe/iso2exe.sh
line diff
     1.1 --- a/syslinux/stuff/iso2exe/init	Mon Feb 09 21:52:32 2015 +0000
     1.2 +++ b/syslinux/stuff/iso2exe/init	Tue Feb 10 08:53:27 2015 +0100
     1.3 @@ -655,7 +655,7 @@
     1.4  {
     1.5  	dotwait "Checking iso image"
     1.6  	[ "$(ddq if=/dev/loop0 bs=2k skip=16 \
     1.7 -	     count=$(echo $(get 32848 /dev/loop0)) | md5sum)" == \
     1.8 +	     count=$(echo $(get 32848 /dev/loop0 4)) | md5sum)" == \
     1.9  	  "$(ddq if=/dev/loop0 bs=16 count=1 skip=2047 | od -N 16 -t x1 -An | \
    1.10  	     sed 's/ //g')  -" ] && echo "OK" || echo "ERROR"
    1.11  	echo -en "\rChecking iso hybrid boot"
     2.1 --- a/syslinux/stuff/iso2exe/iso2exe.c	Mon Feb 09 21:52:32 2015 +0000
     2.2 +++ b/syslinux/stuff/iso2exe/iso2exe.c	Tue Feb 10 08:53:27 2015 +0100
     2.3 @@ -9,9 +9,11 @@
     2.4  #ifdef WIN32
     2.5  #include <windows.h>
     2.6  #endif
     2.7 +typedef unsigned char uint8_t;
     2.8 +typedef unsigned long uint32_t;
     2.9  #include "iso2exe.h"
    2.10  
    2.11 -static int fd, forced, status = 1;
    2.12 +static int fd, forced, uninstall, status = 1;
    2.13  static char tazlitoinfo[0x8000U - BOOTISOSZ];
    2.14  #define buffer tazlitoinfo
    2.15  #define BUFFERSZ 2048
    2.16 @@ -27,6 +29,217 @@
    2.17  	}
    2.18  }
    2.19  
    2.20 +static int domd5 = 0;
    2.21 +#define ALIGN1
    2.22 +
    2.23 +typedef struct {
    2.24 +	uint32_t l;
    2.25 +	uint32_t h;
    2.26 +} uint64_t;
    2.27 +static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
    2.28 +static uint64_t total64;    /* must be directly before hash[] */
    2.29 +static uint32_t hash[8];    /* 4 elements for md5, 5 for sha1, 8 for sha256 */
    2.30 +
    2.31 +//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
    2.32 +static uint32_t rotl32(uint32_t x, unsigned n)
    2.33 +{
    2.34 +	return (x << n) | (x >> (32 - n));
    2.35 +}
    2.36 +
    2.37 +static void md5_process_block64(void);
    2.38 +
    2.39 +/* Feed data through a temporary buffer.
    2.40 + * The internal buffer remembers previous data until it has 64
    2.41 + * bytes worth to pass on.
    2.42 + */
    2.43 +static void common64_hash(const void *buffer, size_t len)
    2.44 +{
    2.45 +	unsigned bufpos = total64.l & 63;
    2.46 +
    2.47 +	total64.l += len; if (total64.l < len) total64.h++;
    2.48 +
    2.49 +	while (1) {
    2.50 +		unsigned remaining = 64 - bufpos;
    2.51 +		if (remaining > len)
    2.52 +			remaining = len;
    2.53 +		/* Copy data into aligned buffer */
    2.54 +		memcpy(wbuffer + bufpos, buffer, remaining);
    2.55 +		len -= remaining;
    2.56 +		buffer = (const char *)buffer + remaining;
    2.57 +		bufpos += remaining;
    2.58 +		/* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
    2.59 +		bufpos -= 64;
    2.60 +		if (bufpos != 0)
    2.61 +			break;
    2.62 +		/* Buffer is filled up, process it */
    2.63 +		md5_process_block64();
    2.64 +		/*bufpos = 0; - already is */
    2.65 +	}
    2.66 +}
    2.67 +
    2.68 +/* Process the remaining bytes in the buffer */
    2.69 +static void common64_end(void)
    2.70 +{
    2.71 +	unsigned bufpos = total64.l & 63;
    2.72 +	/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
    2.73 +	wbuffer[bufpos++] = 0x80;
    2.74 +
    2.75 +	/* This loop iterates either once or twice, no more, no less */
    2.76 +	while (1) {
    2.77 +		unsigned remaining = 64 - bufpos;
    2.78 +		memset(wbuffer + bufpos, 0, remaining);
    2.79 +		/* Do we have enough space for the length count? */
    2.80 +		if (remaining >= 8) {
    2.81 +			/* Store the 64-bit counter of bits in the buffer */
    2.82 +			//uint64_t t = total64 << 3;
    2.83 +			uint32_t *t = (uint32_t *) (&wbuffer[64 - 8]);
    2.84 +			/* wbuffer is suitably aligned for this */
    2.85 +			//*(uint64_t *) (&wbuffer[64 - 8]) = t;
    2.86 +			t[0] = total64.l << 3;
    2.87 +			t[1] = (total64.h << 3) | (total64.l >> 29);
    2.88 +		}
    2.89 +		md5_process_block64();
    2.90 +		if (remaining >= 8)
    2.91 +			break;
    2.92 +		bufpos = 0;
    2.93 +	}
    2.94 +}
    2.95 +
    2.96 +/* These are the four functions used in the four steps of the MD5 algorithm
    2.97 + * and defined in the RFC 1321.  The first function is a little bit optimized
    2.98 + * (as found in Colin Plumbs public domain implementation).
    2.99 + * #define FF(b, c, d) ((b & c) | (~b & d))
   2.100 + */
   2.101 +#undef FF
   2.102 +#undef FG
   2.103 +#undef FH
   2.104 +#undef FI
   2.105 +#define FF(b, c, d) (d ^ (b & (c ^ d)))
   2.106 +#define FG(b, c, d) FF(d, b, c)
   2.107 +#define FH(b, c, d) (b ^ c ^ d)
   2.108 +#define FI(b, c, d) (c ^ (b | ~d))
   2.109 +
   2.110 +/* Hash a single block, 64 bytes long and 4-byte aligned */
   2.111 +static void md5_process_block64(void)
   2.112 +{
   2.113 +	uint32_t *words = (void*) wbuffer;
   2.114 +	uint32_t A = hash[0];
   2.115 +	uint32_t B = hash[1];
   2.116 +	uint32_t C = hash[2];
   2.117 +	uint32_t D = hash[3];
   2.118 +
   2.119 +	const uint32_t *pc;
   2.120 +	const char *pp;
   2.121 +	const char *ps;
   2.122 +	int i;
   2.123 +	uint32_t temp;
   2.124 +
   2.125 +
   2.126 +	pc = C_array;
   2.127 +	pp = P_array;
   2.128 +	ps = S_array - 4;
   2.129 +
   2.130 +	for (i = 0; i < 64; i++) {
   2.131 +		if ((i & 0x0f) == 0)
   2.132 +			ps += 4;
   2.133 +		temp = A;
   2.134 +		switch (i >> 4) {
   2.135 +		case 0:
   2.136 +			temp += FF(B, C, D);
   2.137 +			break;
   2.138 +		case 1:
   2.139 +			temp += FG(B, C, D);
   2.140 +			break;
   2.141 +		case 2:
   2.142 +			temp += FH(B, C, D);
   2.143 +			break;
   2.144 +		case 3:
   2.145 +			temp += FI(B, C, D);
   2.146 +		}
   2.147 +		temp += words[(int) (*pp++)] + *pc++;
   2.148 +		temp = rotl32(temp, ps[i & 3]);
   2.149 +		temp += B;
   2.150 +		A = D;
   2.151 +		D = C;
   2.152 +		C = B;
   2.153 +		B = temp;
   2.154 +	}
   2.155 +	/* Add checksum to the starting values */
   2.156 +	hash[0] += A;
   2.157 +	hash[1] += B;
   2.158 +	hash[2] += C;
   2.159 +	hash[3] += D;
   2.160 +
   2.161 +}
   2.162 +#undef FF
   2.163 +#undef FG
   2.164 +#undef FH
   2.165 +#undef FI
   2.166 +
   2.167 +/* Initialize structure containing state of computation.
   2.168 + * (RFC 1321, 3.3: Step 3)
   2.169 + */
   2.170 +static void md5_begin(void)
   2.171 +{
   2.172 +	hash[0] = 0x67452301;
   2.173 +	hash[1] = 0xefcdab89;
   2.174 +	hash[2] = 0x98badcfe;
   2.175 +	hash[3] = 0x10325476;
   2.176 +	total64.l = total64.h = 0;
   2.177 +}
   2.178 +
   2.179 +/* Used also for sha1 and sha256 */
   2.180 +#define md5_hash common64_hash
   2.181 +
   2.182 +/* Process the remaining bytes in the buffer and put result from CTX
   2.183 + * in first 16 bytes following RESBUF.  The result is always in little
   2.184 + * endian byte order, so that a byte-wise output yields to the wanted
   2.185 + * ASCII representation of the message digest.
   2.186 + */
   2.187 +#define md5_end common64_end
   2.188 +
   2.189 +static void md5sum(void)
   2.190 +{
   2.191 +	unsigned long sectors = 0;
   2.192 +	int count;
   2.193 +
   2.194 +	lseek(fd, 32768UL, SEEK_SET);
   2.195 +
   2.196 +	md5_begin();
   2.197 +	while ((count = read(fd, buffer, BUFFERSZ)) > 0) {
   2.198 +		if (sectors == 0)
   2.199 +			sectors = LONG(buffer + 80);
   2.200 +		md5_hash(buffer, count);
   2.201 +		if (--sectors == 0)
   2.202 +			break;
   2.203 +	}
   2.204 +
   2.205 +	if (count < 0)
   2.206 +		return;
   2.207 +
   2.208 +	md5_end();
   2.209 +
   2.210 +	lseek(fd, 32752UL, SEEK_SET);
   2.211 +	write(fd, hash, 16);
   2.212 +	memcpy(bootiso + BOOTISOSZ - 16, hash, 16);
   2.213 +}
   2.214 +
   2.215 +static unsigned chksum(unsigned start, unsigned stop)
   2.216 +{
   2.217 +	unsigned i, n = 0;
   2.218 +
   2.219 +	lseek(fd, 0UL /* (unsigned long) (start / BUFFERSZ) */, SEEK_SET);
   2.220 +	while (1) {
   2.221 +		if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
   2.222 +			return 0;
   2.223 +		for (i = start % BUFFERSZ; i < BUFFERSZ; i += 2, start += 2) {
   2.224 +			if (start >= stop)
   2.225 +				return - n;
   2.226 +			n += WORD(buffer + i);
   2.227 +		}
   2.228 +	}
   2.229 +}
   2.230 +
   2.231  static unsigned install(char *filename)
   2.232  {
   2.233  #define heads 64
   2.234 @@ -50,6 +263,23 @@
   2.235  	if (fd == -1)
   2.236  		return OPENERR;
   2.237  
   2.238 +	if (uninstall) {
   2.239 +		struct { char check[sizeof(tazlitoinfo) - BUFFERSZ - 1024]; };
   2.240 +		readsector(0UL);
   2.241 +		n = BUFFERSZ;
   2.242 +		if (WORD(buffer) == 23117) {
   2.243 +			readsector((unsigned long) buffer[69]);
   2.244 +			n = 0;
   2.245 +		}
   2.246 +		lseek(fd, 0UL, SEEK_SET);
   2.247 +		for (i = 0; i < 32; i++, n = BUFFERSZ) {
   2.248 +			write(fd, buffer + n, 1024);
   2.249 +		}
   2.250 +		close(fd);
   2.251 +		status = 0;
   2.252 +		return UNINSTALLMSG;
   2.253 +	}
   2.254 +
   2.255  	if (forced == 0) {
   2.256  		status = 2;
   2.257  		/* Install hybridiso boot sector */
   2.258 @@ -105,18 +335,22 @@
   2.259  	write(fd, tazlitoinfo, sizeof(tazlitoinfo));
   2.260  	write(fd, bootiso + n, BOOTISOSZ - n); /* COM + rootfs + EXE/DOS */
   2.261  
   2.262 -	/* Compute the checksum */
   2.263 -	lseek(fd, 0UL, SEEK_SET);
   2.264 -	for (i = 66, n = 0, j = 0; j < 16; j++, i = 0) {
   2.265 -		if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
   2.266 -			goto nochksum;
   2.267 -		for (; i < BUFFERSZ; i += 2)
   2.268 -			n += WORD(buffer + i);
   2.269 +	if (domd5) {
   2.270 +		puts(bootiso + MD5MSG);
   2.271 +		md5sum();
   2.272  	}
   2.273 -	WORD(bootiso + 64) = -n;
   2.274 -	lseek(fd, 0UL, SEEK_SET);
   2.275 -	write(fd, bootiso, 512);
   2.276 -nochksum:
   2.277 +	
   2.278 +	/* Compute the boot checksums */
   2.279 +	if ((WORD(bootiso + 64) = chksum(66, 32768)) != 0) {
   2.280 +		if (domd5) {
   2.281 +			lseek(fd, 0UL, SEEK_SET);
   2.282 +			write(fd, bootiso, 512);
   2.283 +			n = WORD(bootiso + 2) - 512*(WORD(bootiso + 4) - 1);
   2.284 +			WORD(bootiso + 18) = chksum(0, n) - 1;
   2.285 +		}
   2.286 +		lseek(fd, 0UL, SEEK_SET);
   2.287 +		write(fd, bootiso, 512);
   2.288 +	}
   2.289  	close(fd);
   2.290  	status = 0;
   2.291  	return SUCCESSMSG;
   2.292 @@ -124,7 +358,16 @@
   2.293  
   2.294  int main(int argc, char *argv[])
   2.295  {
   2.296 -	forced = (argc > 2);
   2.297 +	int i;
   2.298 +	for (i = 2; i < argc; i++) {
   2.299 +		char *s = argv[i];
   2.300 +		while ((unsigned)(*s - '-') <= ('/' - '-')) s++;
   2.301 +		switch (*s | 0x20) {
   2.302 +		case 'f' : forced++; break;
   2.303 +		case 'm' : domd5++; break;
   2.304 +		case 'u' : uninstall++; break;
   2.305 +		}
   2.306 +	}
   2.307  	puts(bootiso + install(argv[1]));
   2.308  	if (status > 1)
   2.309  		puts(bootiso + FORCEMSG);
     3.1 --- a/syslinux/stuff/iso2exe/iso2exe.sh	Mon Feb 09 21:52:32 2015 +0000
     3.2 +++ b/syslinux/stuff/iso2exe/iso2exe.sh	Tue Feb 10 08:53:27 2015 +0100
     3.3 @@ -140,8 +140,49 @@
     3.4  
     3.5  #ifdef WIN32
     3.6  static char $name[] = {
     3.7 +/* head */
     3.8  $(hexdump -v -n $HSZ -e '"    " 16/1 "0x%02X, "' -e '"  // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x  ,/      /g')
     3.9 +/* tail */
    3.10  $(hexdump -v -s $OFS -e '"    " 16/1 "0x%02X, "' -e '"  // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x  ,/      /g')
    3.11 +
    3.12 +/* These strange constants are defined in RFC 1321 as
    3.13 +   T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
    3.14 + */
    3.15 +/* static const uint32_t C_array[64] */
    3.16 +EOT
    3.17 +	while read a b c d; do
    3.18 +		for i in $a $b $c $d; do
    3.19 +			echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
    3.20 +		done
    3.21 +	done <<EOT
    3.22 +	0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
    3.23 +	0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
    3.24 +	0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
    3.25 +	0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
    3.26 +	0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
    3.27 +	0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
    3.28 +	0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
    3.29 +	0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
    3.30 +	0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
    3.31 +	0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
    3.32 +	0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
    3.33 +	0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
    3.34 +	0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
    3.35 +	0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
    3.36 +	0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
    3.37 +	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
    3.38 +EOT
    3.39 +	cat <<EOT
    3.40 +/* static const char P_array[64] */
    3.41 +	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
    3.42 +	1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
    3.43 +	5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
    3.44 +	0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
    3.45 +/* static const char S_array[16] */
    3.46 +	7, 12, 17, 22,
    3.47 +	5, 9, 14, 20,
    3.48 +	4, 11, 16, 23,
    3.49 +	6, 10, 15, 21,
    3.50  EOT
    3.51  
    3.52  for mode in data offset ; do
    3.53 @@ -158,21 +199,27 @@
    3.54  #else
    3.55  static char *$name;
    3.56  #endif
    3.57 +
    3.58 +#define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
    3.59 +#define P_array (char *)     ($name + $(($BOOTISOSZ+(64*4))))
    3.60 +#define S_array (char *)     ($name + $(($BOOTISOSZ+(64*4)+64)))
    3.61  #define ELTORITOOFS	3
    3.62  EOT
    3.63  			fi
    3.64 -			echo "#define $tag	$(($BOOTISOSZ+$ofs))"
    3.65 +			echo "#define $tag	$(($BOOTISOSZ+(64*4)+64+16+$ofs))"
    3.66  			ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
    3.67  		fi
    3.68  	done <<EOT
    3.69  READSECTORERR	Read sector failure.
    3.70 -USAGE		Usage: isohybrid.exe file.iso [--forced]
    3.71 +USAGE		Usage: isohybrid.exe file.iso [--forced|--undo|--md5]
    3.72  OPENERR		Can't open r/w the iso file.
    3.73  ELTORITOERR	No EL TORITO SPECIFICATION signature.
    3.74  CATALOGERR	Invalid boot catalog.
    3.75  HYBRIDERR	No isolinux.bin hybrid signature.
    3.76  SUCCESSMSG	Now you can create a USB key with your .iso file.\\\\nSimply rename it to a .exe file and run it.
    3.77  FORCEMSG	You can add --forced to proceed anyway.
    3.78 +MD5MSG		Computing md5sum...
    3.79 +UNINSTALLMSG	Uninstall done.
    3.80  EOT
    3.81  done
    3.82  	rm -rf $DATA
    3.83 @@ -242,7 +289,7 @@
    3.84  		ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
    3.85  	if [ $(stat -c %s $1) -gt 34816 ]; then
    3.86  		echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
    3.87 -		echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1) | \
    3.88 +		echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1 4) | \
    3.89  			md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
    3.90  			ddq bs=16 seek=2047 conv=notrunc of=$1
    3.91  	fi