mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[checksum] switch to 7-zip's SHA-256 algorithm
* That's more like it! When compiled in 64-bit we get about the same speed as 7-zip (slower when 32-bit, but shhh, or people will ask for a 64-bit version of Rufus...) * Looks like what was holding us back was the sha256_write() from Brad Conte's * Also fix WDK compilation and harmonize the BE->LE conversions
This commit is contained in:
		
							parent
							
								
									07114edc6f
								
							
						
					
					
						commit
						00ffbae61f
					
				
					 4 changed files with 106 additions and 78 deletions
				
			
		
							
								
								
									
										155
									
								
								src/checksum.c
									
										
									
									
									
								
							
							
						
						
									
										155
									
								
								src/checksum.c
									
										
									
									
									
								
							|  | @ -3,7 +3,7 @@ | |||
|  * Message-Digest algorithms (md5sum, sha1sum, sha256sum) | ||||
|  * Copyright © 1998-2001 Free Software Foundation, Inc. | ||||
|  * Copyright © 2004 g10 Code GmbH | ||||
|  * Copyright © 2006-2012 Brad Conte <brad@bradconte.com> | ||||
|  * Copyright © 2002-2015 Wei Dai & Igor Pavlov | ||||
|  * Copyright © 2015-2016 Pete Batard <pete@akeo.ie> | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  | @ -23,8 +23,7 @@ | |||
| /*
 | ||||
|  * SHA-1 code taken from GnuPG, as per copyrights above. | ||||
|  * | ||||
|  * SHA-256 code modified from crypto-algorithms by Brad Conte: | ||||
|  * https://github.com/B-Con/crypto-algorithms - Public Domain
 | ||||
|  * SHA-256 taken from 7-zip's Sha256.c, itself based on Crypto++ - Public Domain | ||||
|  * | ||||
|  * MD5 code from various public domain sources sharing the following | ||||
|  * copyright declaration: | ||||
|  | @ -79,7 +78,7 @@ char ALIGNED(64) buffer[2][BUFFER_SIZE]; | |||
| #define ROR(a,b) (((a) >> (b)) | ((a) << (32-(b)))) | ||||
| 
 | ||||
| // For SHA-256
 | ||||
| static const uint32_t k[64] = { | ||||
| static const uint32_t K[64] = { | ||||
| 	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, | ||||
| 	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, | ||||
| 	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, | ||||
|  | @ -97,8 +96,8 @@ static const uint32_t k[64] = { | |||
| typedef struct ALIGNED(8) { | ||||
| 	unsigned char buf[64]; | ||||
| 	uint32_t state[8]; | ||||
| 	uint64_t bytecount; | ||||
| 	uint64_t bitcount; | ||||
| 	uint32_t bytecount; | ||||
| } SUM_CONTEXT; | ||||
| 
 | ||||
| static void md5_init(SUM_CONTEXT *ctx) | ||||
|  | @ -150,13 +149,13 @@ static void sha1_transform(SUM_CONTEXT *ctx, const unsigned char *data) | |||
| 	memcpy(x, data, sizeof(x)); | ||||
| #else | ||||
| 	{ | ||||
| 		int i; | ||||
| 		unsigned char *p2; | ||||
| 		for (i = 0, p2 = (unsigned char*)x; i < 16; i++, p2 += 4) { | ||||
| 			p2[3] = *data++; | ||||
| 			p2[2] = *data++; | ||||
| 			p2[1] = *data++; | ||||
| 			p2[0] = *data++; | ||||
| 		unsigned k; | ||||
| 		for (k = 0; k < 16; k += 4) { | ||||
| 			const unsigned char *p2 = data + k * 4; | ||||
| 			x[k] = get_be32(p2); | ||||
| 			x[k + 1] = get_be32(p2 + 4); | ||||
| 			x[k + 2] = get_be32(p2 + 8); | ||||
| 			x[k + 3] = get_be32(p2 + 12); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
|  | @ -270,7 +269,7 @@ static void sha1_transform(SUM_CONTEXT *ctx, const unsigned char *data) | |||
| 
 | ||||
| static void sha256_transform(SUM_CONTEXT *ctx, const unsigned char *data) | ||||
| { | ||||
| 	uint32_t a, b, c, d, e, f, g, h, i, t1, t2, m[64]; | ||||
| 	uint32_t a, b, c, d, e, f, g, h, j, x[16]; | ||||
| 
 | ||||
| 	a = ctx->state[0]; | ||||
| 	b = ctx->state[1]; | ||||
|  | @ -281,44 +280,53 @@ static void sha256_transform(SUM_CONTEXT *ctx, const unsigned char *data) | |||
| 	g = ctx->state[6]; | ||||
| 	h = ctx->state[7]; | ||||
| 
 | ||||
| #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) | ||||
| #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||||
| #define CH(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) | ||||
| #define MAJ(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) | ||||
| #define EP0(x) (ROR(x,2) ^ ROR(x,13) ^ ROR(x,22)) | ||||
| #define EP1(x) (ROR(x,6) ^ ROR(x,11) ^ ROR(x,25)) | ||||
| #define SIG0(x) (ROR(x,7) ^ ROR(x,18) ^ ((x) >> 3)) | ||||
| #define SIG1(x) (ROR(x,17) ^ ROR(x,19) ^ ((x) >> 10)) | ||||
| 
 | ||||
| #define BLK0(i) (x[i]) | ||||
| #define BLK2(i) (x[i] += SIG1(x[((i)-2)&15]) + x[((i)-7)&15] + SIG0(x[((i)-15)&15])) | ||||
| #define R(a,b,c,d,e,f,g,h, i) \ | ||||
| 	h += EP1(e) + CH(e,f,g) + K[(i)+(j)] + (j ? BLK2(i) : BLK0(i)); \ | ||||
| 	d += h; \ | ||||
| 	h += EP0(a) + MAJ(a, b, c) | ||||
| #define RX_8(i) \ | ||||
| 	R(a,b,c,d,e,f,g,h, i); \ | ||||
| 	R(h,a,b,c,d,e,f,g, i+1); \ | ||||
| 	R(g,h,a,b,c,d,e,f, i+2); \ | ||||
| 	R(f,g,h,a,b,c,d,e, i+3); \ | ||||
| 	R(e,f,g,h,a,b,c,d, i+4); \ | ||||
| 	R(d,e,f,g,h,a,b,c, i+5); \ | ||||
| 	R(c,d,e,f,g,h,a,b, i+6); \ | ||||
| 	R(b,c,d,e,f,g,h,a, i+7) | ||||
| 
 | ||||
| #ifdef BIG_ENDIAN_HOST | ||||
| 	memcpy(m, data, sizeof(m)); | ||||
| 	memcpy(x, data, sizeof(x)); | ||||
| #else | ||||
| 	{ | ||||
| 		unsigned char *p2; | ||||
| 		for (i = 0, p2 = (unsigned char*)m; i < 16; i++, p2 += 4) { | ||||
| 			p2[3] = *data++; | ||||
| 			p2[2] = *data++; | ||||
| 			p2[1] = *data++; | ||||
| 			p2[0] = *data++; | ||||
| 		unsigned k; | ||||
| 		for (k = 0; k < 16; k += 4) { | ||||
| 			const unsigned char *p2 = data + k * 4; | ||||
| 			x[k] = get_be32(p2); | ||||
| 			x[k + 1] = get_be32(p2 + 4); | ||||
| 			x[k + 2] = get_be32(p2 + 8); | ||||
| 			x[k + 3] = get_be32(p2 + 12); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	for (i = 16; i < 64; ++i) | ||||
| 		m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; | ||||
| 
 | ||||
| 	for (i = 0; i < 64; ++i) { | ||||
| 		t1 = h + EP1(e) + CH(e, f, g) + k[i] + m[i]; | ||||
| 		t2 = EP0(a) + MAJ(a, b, c); | ||||
| 		h = g; | ||||
| 		g = f; | ||||
| 		f = e; | ||||
| 		e = d + t1; | ||||
| 		d = c; | ||||
| 		c = b; | ||||
| 		b = a; | ||||
| 		a = t1 + t2; | ||||
| 	for (j = 0; j < 64; j += 16) { | ||||
| 		RX_8(0); | ||||
| 		RX_8(8); | ||||
| 	} | ||||
| 
 | ||||
| #undef EP0 | ||||
| #undef EP1 | ||||
| #undef SIG0 | ||||
| #undef SIG1 | ||||
| 
 | ||||
| 	ctx->state[0] += a; | ||||
| 	ctx->state[1] += b; | ||||
| 	ctx->state[2] += c; | ||||
|  | @ -344,13 +352,13 @@ static void md5_transform(SUM_CONTEXT *ctx, const unsigned char *data) | |||
| 	memcpy(x, data, sizeof(x)); | ||||
| #else | ||||
| 	{ | ||||
| 		int i; | ||||
| 		unsigned char *p; | ||||
| 		for (i = 0, p = (unsigned char*)x; i < 16; i++, p += 4) { | ||||
| 			p[3] = *data++; | ||||
| 			p[2] = *data++; | ||||
| 			p[1] = *data++; | ||||
| 			p[0] = *data++; | ||||
| 		unsigned k; | ||||
| 		for (k = 0; k < 16; k += 4) { | ||||
| 			const unsigned char *p2 = data + k * 4; | ||||
| 			x[k] = get_be32(p2); | ||||
| 			x[k + 1] = get_be32(p2 + 4); | ||||
| 			x[k + 2] = get_be32(p2 + 8); | ||||
| 			x[k + 3] = get_be32(p2 + 12); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
|  | @ -475,18 +483,32 @@ static void sha1_write(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len) | |||
| 
 | ||||
| static void sha256_write(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len) | ||||
| { | ||||
| 	uint32_t i; | ||||
| 	uint64_t pos = ctx->bytecount & 0x3F; | ||||
| 	uint64_t num; | ||||
| 
 | ||||
| 	for (i = 0; i < len; ++i) { | ||||
| 		ctx->buf[ctx->bytecount] = buf[i]; | ||||
| 		ctx->bytecount++; | ||||
| 		if (ctx->bytecount == 64) { | ||||
| 			PREFETCH64(&buf[i + 64]); | ||||
| 			sha256_transform(ctx, ctx->buf); | ||||
| 			ctx->bitcount += 64 * 8; | ||||
| 			ctx->bytecount = 0; | ||||
| 		} | ||||
| 	ctx->bytecount += len; | ||||
| 
 | ||||
| 	num = 64 - pos; | ||||
| 	if (num > len) { | ||||
| 		memcpy(ctx->buf + pos, buf, len); | ||||
| 		return; | ||||
| 	} | ||||
| 	len -= num; | ||||
| 	memcpy(ctx->buf + pos, buf, num); | ||||
| 	buf += num; | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		PREFETCH64(buf + 64); | ||||
| 		sha256_transform(ctx, ctx->buf); | ||||
| 		if (len < 64) | ||||
| 			break; | ||||
| 		len -= 64; | ||||
| 		memcpy(ctx->buf, buf, 64); | ||||
| 		buf += 64; | ||||
| 	} | ||||
| 
 | ||||
| 	if (len != 0) | ||||
| 		memcpy(ctx->buf, buf, len); | ||||
| } | ||||
| 
 | ||||
| /* Update the message digest with the contents of the buffer (MD5) */ | ||||
|  | @ -575,27 +597,21 @@ static void sha1_final(SUM_CONTEXT *ctx) | |||
| 
 | ||||
| static void sha256_final(SUM_CONTEXT *ctx) | ||||
| { | ||||
| 	uint32_t i; | ||||
| 	uint64_t pos = ctx->bytecount & 0x3F; | ||||
| 	unsigned char *p; | ||||
| 
 | ||||
| 	i = ctx->bytecount; | ||||
| 	ctx->buf[pos++] = 0x80; | ||||
| 
 | ||||
| 	// Pad whatever data is left in the buffer.
 | ||||
| 	if (ctx->bytecount < 56) { | ||||
| 		ctx->buf[i++] = 0x80; | ||||
| 		while (i < 56) | ||||
| 			ctx->buf[i++] = 0x00; | ||||
| 	} | ||||
| 	else { | ||||
| 		ctx->buf[i++] = 0x80; | ||||
| 		while (i < 64) | ||||
| 			ctx->buf[i++] = 0x00; | ||||
| 		sha256_transform(ctx, ctx->buf); | ||||
| 		memset(ctx->buf, 0, 56); | ||||
| 	while (pos != (64 - 8)) { | ||||
| 		pos &= 0x3F; | ||||
| 		if (pos == 0) | ||||
| 			sha256_transform(ctx, ctx->buf); | ||||
| 		ctx->buf[pos++] = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	// Append to the padding the total message's length in bits and transform.
 | ||||
| 	ctx->bitcount += ctx->bytecount * 8; | ||||
| 	ctx->bitcount = ctx->bytecount << 3; | ||||
| 	ctx->buf[63] = (unsigned char) (ctx->bitcount); | ||||
| 	ctx->buf[62] = (unsigned char) (ctx->bitcount >> 8); | ||||
| 	ctx->buf[61] = (unsigned char) (ctx->bitcount >> 16); | ||||
|  | @ -682,10 +698,13 @@ static void md5_final(SUM_CONTEXT *ctx) | |||
| #undef X | ||||
| } | ||||
| 
 | ||||
| //#define NULL_TEST
 | ||||
| #ifdef NULL_TEST | ||||
| // These 'null' calls are useful for testing load balancing and individual algorithm speed
 | ||||
| static void null_init(SUM_CONTEXT *ctx) { memset(ctx, 0, sizeof(*ctx)); } | ||||
| static void null_write(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len) { } | ||||
| static void null_final(SUM_CONTEXT *ctx) { } | ||||
| #endif | ||||
| 
 | ||||
| typedef void sum_init_t(SUM_CONTEXT *ctx); | ||||
| typedef void sum_write_t(SUM_CONTEXT *ctx, const unsigned char *buf, size_t len); | ||||
|  |  | |||
|  | @ -108,8 +108,9 @@ const char* additional_copyrights = | |||
| "https://www.gnupg.org\\line\n" | ||||
| "GNU General Public License (GPL) v3 or later\\line\n" | ||||
| "\\line\n" | ||||
| "SHA-256 checksum from Brad Conte's crypto-algorithms:\\line\n" | ||||
| "https://github.com/B-Con/crypto-algorithms\\line\n" | ||||
| "SHA-256 checksum from 7-zip by Igor Pavlov and Crypto++ by Wei Dai:\\line\n" | ||||
| "http://7-zip.org\\line\n" | ||||
| "https://github.com/weidai11/cryptopp/\\line\n" | ||||
| "Public Domain\\line\n" | ||||
| "\\line\n" | ||||
| "About and License dialogs inspired by WinSCP by Martin Prikryl\\line\n" | ||||
|  |  | |||
|  | @ -52,21 +52,29 @@ | |||
| #define PREFETCH64(m) do { _m_prefetch(m); _m_prefetch(m+32); } while(0) | ||||
| #endif | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
| #if defined (_MSC_VER) && (_MSC_VER >= 1300) | ||||
| #include <stdlib.h> | ||||
| #pragma intrinsic(_byteswap_ushort) | ||||
| #pragma intrinsic(_byteswap_ulong) | ||||
| #pragma intrinsic(_byteswap_uint64) | ||||
| #define bswap_uint64 _byteswap_uint64 | ||||
| #define bswap_uint32 _byteswap_ulong | ||||
| #define bswap_uint16 _byteswap_ushort | ||||
| #else | ||||
| #define get_be32(p) bswap_uint32(*(const uint32_t *)(const uint8_t *)(p)) | ||||
| #define get_be64(p) bswap_uint64(*(const uint64_t *)(const uint8_t *)(p)) | ||||
| #elif defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) | ||||
| #define bswap_uint64 __builtin_bswap64 | ||||
| #define bswap_uint32 __builtin_bswap32 | ||||
| #define bswap_uint16 __builtin_bswap16 | ||||
| #define get_be32(p) bswap_uint32(*(const uint32_t *)(const uint8_t *)(p)) | ||||
| #define get_be64(p) bswap_uint64(*(const uint32_t *)(const uint8_t *)(p)) | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Nibbled from https://github.com/hanji/popcnt/blob/master/populationcount.cpp
 | ||||
|  * Since MSVC x86_32 does not have intrinsic popcount64 and I don't have all day | ||||
|  */ | ||||
| static inline int popcnt64(register uint64_t u) | ||||
| static __inline int popcnt64(register uint64_t u) | ||||
| { | ||||
| 	u = (u & 0x5555555555555555) + ((u >> 1) & 0x5555555555555555); | ||||
| 	u = (u & 0x3333333333333333) + ((u >> 2) & 0x3333333333333333); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 242, 376 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_ACCEPTFILES | ||||
| CAPTION "Rufus 2.8.874" | ||||
| CAPTION "Rufus 2.8.875" | ||||
| FONT 8, "Segoe UI Symbol", 400, 0, 0x0 | ||||
| BEGIN | ||||
|     LTEXT           "Device",IDS_DEVICE_TXT,9,6,200,8 | ||||
|  | @ -320,8 +320,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 2,8,874,0 | ||||
|  PRODUCTVERSION 2,8,874,0 | ||||
|  FILEVERSION 2,8,875,0 | ||||
|  PRODUCTVERSION 2,8,875,0 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -338,13 +338,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "2.8.874" | ||||
|             VALUE "FileVersion", "2.8.875" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "2.8.874" | ||||
|             VALUE "ProductVersion", "2.8.875" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue