mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	core: C++-ify SHA1 interface
All callers of the SHA1 code are C++. Might just as well use a C++ like interface. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									729356e0b1
								
							
						
					
					
						commit
						21f68387ae
					
				
					 6 changed files with 71 additions and 78 deletions
				
			
		|  | @ -91,7 +91,7 @@ SOURCES += subsurface-mobile-main.cpp \ | |||
| 	core/gas.c \ | ||||
| 	core/membuffer.cpp \ | ||||
| 	core/selection.cpp \ | ||||
| 	core/sha1.c \ | ||||
| 	core/sha1.cpp \ | ||||
| 	core/string-format.cpp \ | ||||
| 	core/strtod.cpp \ | ||||
| 	core/tag.cpp \ | ||||
|  |  | |||
|  | @ -162,7 +162,7 @@ set(SUBSURFACE_CORE_LIB_SRCS | |||
| 	save-xml.cpp | ||||
| 	selection.cpp | ||||
| 	selection.h | ||||
| 	sha1.c | ||||
| 	sha1.cpp | ||||
| 	sha1.h | ||||
| 	ssrf.h | ||||
| 	statistics.c | ||||
|  |  | |||
|  | @ -138,18 +138,14 @@ extern "C" int add_dive_site_to_table(struct dive_site *ds, struct dive_site_tab | |||
| 	/* If the site doesn't yet have an UUID, create a new one.
 | ||||
| 	 * Make this deterministic for testing. */ | ||||
| 	if (!ds->uuid) { | ||||
| 		SHA_CTX ctx; | ||||
| 		uint32_t csum[5]; | ||||
| 
 | ||||
| 		SHA1_Init(&ctx); | ||||
| 		SHA1 sha; | ||||
| 		if (ds->name) | ||||
| 			SHA1_Update(&ctx, ds->name, strlen(ds->name)); | ||||
| 			sha.update(ds->name, strlen(ds->name)); | ||||
| 		if (ds->description) | ||||
| 			SHA1_Update(&ctx, ds->description, strlen(ds->description)); | ||||
| 			sha.update(ds->description, strlen(ds->description)); | ||||
| 		if (ds->notes) | ||||
| 			SHA1_Update(&ctx, ds->notes, strlen(ds->notes)); | ||||
| 		SHA1_Final((unsigned char *)csum, &ctx); | ||||
| 		ds->uuid = csum[0]; | ||||
| 			sha.update(ds->notes, strlen(ds->notes)); | ||||
| 		ds->uuid = sha.hash_uint32(); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Take care to never have the same uuid twice. This could happen on
 | ||||
|  |  | |||
|  | @ -135,9 +135,6 @@ std::string normalize_cloud_name(const std::string &remote_in) | |||
| 
 | ||||
| std::string get_local_dir(const std::string &url, const std::string &branch) | ||||
| { | ||||
| 	SHA_CTX ctx; | ||||
| 	unsigned char hash[20]; | ||||
| 
 | ||||
| 	// this optimization could in theory lead to odd things happening if the
 | ||||
| 	// cloud backend servers ever get out of sync - but when a user switches
 | ||||
| 	// between those servers (either because one is down, or because the algorithm
 | ||||
|  | @ -148,11 +145,11 @@ std::string get_local_dir(const std::string &url, const std::string &branch) | |||
| 
 | ||||
| 	// That zero-byte update is so that we don't get hash
 | ||||
| 	// collisions for "repo1 branch" vs "repo 1branch".
 | ||||
| 	SHA1_Init(&ctx); | ||||
| 	SHA1_Update(&ctx, remote.c_str(), remote.size()); | ||||
| 	SHA1_Update(&ctx, "", 1); | ||||
| 	SHA1_Update(&ctx, branch.c_str(), branch.size()); | ||||
| 	SHA1_Final(hash, &ctx); | ||||
| 	SHA1 sha; | ||||
| 	sha.update(remote); | ||||
| 	sha.update("", 1); | ||||
| 	sha.update(branch); | ||||
| 	auto hash = sha.hash(); | ||||
| 	return format_string_std("%s/cloudstorage/%02x%02x%02x%02x%02x%02x%02x%02x", | ||||
| 			system_default_directory(), | ||||
| 			hash[0], hash[1], hash[2], hash[3], | ||||
|  |  | |||
|  | @ -8,7 +8,6 @@ | |||
| 
 | ||||
| /* this is only to get definitions for memcpy(), ntohl() and htonl() */ | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
| #ifdef WIN32 | ||||
| #include <winsock2.h> | ||||
| #else | ||||
|  | @ -132,16 +131,16 @@ | |||
| #define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B &C) + (D &(B ^ C))), 0x8f1bbcdc, A, B, C, D, E) | ||||
| #define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B ^ C ^ D), 0xca62c1d6, A, B, C, D, E) | ||||
| 
 | ||||
| static void blk_SHA1_Block(blk_SHA_CTX *ctx, const void *block) | ||||
| static void blk_SHA1_Block(unsigned int H[], const void *block) | ||||
| { | ||||
| 	unsigned int A, B, C, D, E; | ||||
| 	unsigned int array[16]; | ||||
| 
 | ||||
| 	A = ctx->H[0]; | ||||
| 	B = ctx->H[1]; | ||||
| 	C = ctx->H[2]; | ||||
| 	D = ctx->H[3]; | ||||
| 	E = ctx->H[4]; | ||||
| 	A = H[0]; | ||||
| 	B = H[1]; | ||||
| 	C = H[2]; | ||||
| 	D = H[3]; | ||||
| 	E = H[4]; | ||||
| 
 | ||||
| 	/* Round 1 - iterations 0-16 take their input from 'block' */ | ||||
| 	T_0_15(0, A, B, C, D, E); | ||||
|  | @ -233,80 +232,84 @@ static void blk_SHA1_Block(blk_SHA_CTX *ctx, const void *block) | |||
| 	T_60_79(78, C, D, E, A, B); | ||||
| 	T_60_79(79, B, C, D, E, A); | ||||
| 
 | ||||
| 	ctx->H[0] += A; | ||||
| 	ctx->H[1] += B; | ||||
| 	ctx->H[2] += C; | ||||
| 	ctx->H[3] += D; | ||||
| 	ctx->H[4] += E; | ||||
| 	H[0] += A; | ||||
| 	H[1] += B; | ||||
| 	H[2] += C; | ||||
| 	H[3] += D; | ||||
| 	H[4] += E; | ||||
| } | ||||
| 
 | ||||
| void blk_SHA1_Init(blk_SHA_CTX *ctx) | ||||
| { | ||||
| 	ctx->size = 0; | ||||
| 
 | ||||
| SHA1::SHA1() : | ||||
| 	size(0), | ||||
| 	/* Initialize H with the magic constants (see FIPS180 for constants) */ | ||||
| 	ctx->H[0] = 0x67452301; | ||||
| 	ctx->H[1] = 0xefcdab89; | ||||
| 	ctx->H[2] = 0x98badcfe; | ||||
| 	ctx->H[3] = 0x10325476; | ||||
| 	ctx->H[4] = 0xc3d2e1f0; | ||||
| 	H { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 } | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len) | ||||
| void SHA1::update(const void *data, unsigned long len) | ||||
| { | ||||
| 	unsigned int lenW = ctx->size & 63; | ||||
| 	unsigned int lenW = size & 63; | ||||
| 
 | ||||
| 	ctx->size += len; | ||||
| 	size += len; | ||||
| 
 | ||||
| 	/* Read the data into W and process blocks as they get full */ | ||||
| 	if (lenW) { | ||||
| 		unsigned int left = 64 - lenW; | ||||
| 		if (len < left) | ||||
| 			left = len; | ||||
| 		memcpy(lenW + (char *)ctx->W, data, left); | ||||
| 		memcpy(lenW + (char *)W, data, left); | ||||
| 		lenW = (lenW + left) & 63; | ||||
| 		len -= left; | ||||
| 		data = ((const char *)data + left); | ||||
| 		if (lenW) | ||||
| 			return; | ||||
| 		blk_SHA1_Block(ctx, ctx->W); | ||||
| 		blk_SHA1_Block(H, W); | ||||
| 	} | ||||
| 	while (len >= 64) { | ||||
| 		blk_SHA1_Block(ctx, data); | ||||
| 		blk_SHA1_Block(H, data); | ||||
| 		data = ((const char *)data + 64); | ||||
| 		len -= 64; | ||||
| 	} | ||||
| 	if (len) | ||||
| 		memcpy(ctx->W, data, len); | ||||
| 		memcpy(W, data, len); | ||||
| } | ||||
| 
 | ||||
| void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx) | ||||
| void SHA1::update(const std::string &s) | ||||
| { | ||||
| 	update(s.data(), s.size()); | ||||
| } | ||||
| 
 | ||||
| std::array<unsigned char, 20> SHA1::hash() | ||||
| { | ||||
| 	std::array<unsigned char, 20> hashout; | ||||
| 	static const unsigned char pad[64] = { 0x80 }; | ||||
| 	unsigned int padlen[2]; | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* Pad with a binary 1 (ie 0x80), then zeroes, then length */ | ||||
| 	padlen[0] = htonl((uint32_t)(ctx->size >> 29)); | ||||
| 	padlen[1] = htonl((uint32_t)(ctx->size << 3)); | ||||
| 	padlen[0] = htonl((uint32_t)(size >> 29)); | ||||
| 	padlen[1] = htonl((uint32_t)(size << 3)); | ||||
| 
 | ||||
| 	i = ctx->size & 63; | ||||
| 	blk_SHA1_Update(ctx, pad, 1 + (63 & (55 - i))); | ||||
| 	blk_SHA1_Update(ctx, padlen, 8); | ||||
| 	i = size & 63; | ||||
| 	update(pad, 1 + (63 & (55 - i))); | ||||
| 	update(padlen, 8); | ||||
| 
 | ||||
| 	/* Output hash */ | ||||
| 	for (i = 0; i < 5; i++) | ||||
| 		put_be32(hashout + i * 4, ctx->H[i]); | ||||
| 		put_be32(&hashout[i * 4], H[i]); | ||||
| 	return hashout; | ||||
| } | ||||
| 
 | ||||
| uint32_t SHA1::hash_uint32() | ||||
| { | ||||
| 	auto hashout = hash(); | ||||
| 	return (hashout[0] << 0) | (hashout[1] << 8) | | ||||
| 	       (hashout[2] << 16) | (hashout[3] << 24); | ||||
| } | ||||
| 
 | ||||
| uint32_t SHA1_uint32(const void *dataIn, unsigned long len) | ||||
| { | ||||
| 	uint32_t hashout[5]; | ||||
| 	SHA_CTX ctx; | ||||
| 
 | ||||
| 	SHA1_Init(&ctx); | ||||
| 	SHA1_Update(&ctx, dataIn, len); | ||||
| 	SHA1_Final((unsigned char *)hashout, &ctx); | ||||
| 
 | ||||
| 	return hashout[0]; | ||||
| 	SHA1 sha; | ||||
| 	sha.update(dataIn, len); | ||||
| 	return sha.hash_uint32(); | ||||
| } | ||||
							
								
								
									
										29
									
								
								core/sha1.h
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								core/sha1.h
									
										
									
									
									
								
							|  | @ -9,31 +9,28 @@ | |||
| #define SHA1_H | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| typedef struct | ||||
| #include <array> | ||||
| #include <string> | ||||
| 
 | ||||
| struct SHA1 | ||||
| { | ||||
| 	SHA1(); | ||||
| 	void update(const void *dataIn, unsigned long len); | ||||
| 	void update(const std::string &s); | ||||
| 	// Note: the hash() functions change state. Call only once.
 | ||||
| 	std::array<unsigned char, 20> hash(); | ||||
| 	uint32_t hash_uint32(); // Return first 4 bytes of hash interpreted
 | ||||
| 				// as little-endian unsigned integer.
 | ||||
| private: | ||||
| 	unsigned long long size; | ||||
| 	unsigned int H[5]; | ||||
| 	unsigned int W[16]; | ||||
| } blk_SHA_CTX; | ||||
| 
 | ||||
| void blk_SHA1_Init(blk_SHA_CTX *ctx); | ||||
| void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len); | ||||
| void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx); | ||||
| 
 | ||||
| /* Make us use the standard names */ | ||||
| #define SHA_CTX blk_SHA_CTX | ||||
| #define SHA1_Init blk_SHA1_Init | ||||
| #define SHA1_Update blk_SHA1_Update | ||||
| #define SHA1_Final blk_SHA1_Final | ||||
| }; | ||||
| 
 | ||||
| /* Helper function that calculates an SHA1 has and returns the first 4 bytes as uint32_t */ | ||||
| uint32_t SHA1_uint32(const void *dataIn, unsigned long len); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif // SHA1_H
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue