From 76cc2bf7b43140698618e9dbb87a219c3bd7d32f Mon Sep 17 00:00:00 2001 From: SlowRiot Date: Thu, 20 Nov 2014 01:58:57 +0000 Subject: [PATCH] fixing incorrect buffer size allocation, and unsafe integer size type --- libs/sha1/sha1.cpp | 86 ++++++++++++++++++++++++---------------------- libs/sha1/sha1.h | 38 ++++++++++---------- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/libs/sha1/sha1.cpp b/libs/sha1/sha1.cpp index 883d42837..3d46da7be 100644 --- a/libs/sha1/sha1.cpp +++ b/libs/sha1/sha1.cpp @@ -1,55 +1,57 @@ /* sha1.cpp - source code of - + ============ SHA-1 in C++ ============ - + 100% Public Domain. - + Original C Code -- Steve Reid Small changes to fit into bglibs -- Bruce Guenter Translation to simpler C++ Code -- Volker Grabsch + Fixing bugs and improving style + -- Eugene Hopkinson */ - + #include "sha1.h" #include #include #include - + /* Help macros */ #define SHA1_ROL(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits)))) #define SHA1_BLK(i) (block[i&15] = SHA1_ROL(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1)) - + /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define SHA1_R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + block[i] + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); #define SHA1_R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + SHA1_BLK(i) + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); #define SHA1_R2(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0x6ed9eba1 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); #define SHA1_R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + SHA1_BLK(i) + 0x8f1bbcdc + SHA1_ROL(v,5); w=SHA1_ROL(w,30); #define SHA1_R4(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0xca62c1d6 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); - + SHA1::SHA1() { reset(); } - - + + void SHA1::update(const std::string &s) { std::istringstream is(s); update(is); } - - + + void SHA1::update(std::istream &is) { std::string rest_of_buffer; read(is, rest_of_buffer, BLOCK_BYTES - buffer.size()); buffer += rest_of_buffer; - + while (is) { uint32 block[BLOCK_INTS]; @@ -58,17 +60,17 @@ void SHA1::update(std::istream &is) read(is, buffer, BLOCK_BYTES); } } - - + + /* * Add padding and return the message digest. */ - + std::string SHA1::final() { /* Total number of hashed bits */ uint64 total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8; - + /* Padding */ buffer += 0x80; unsigned int orig_size = buffer.size(); @@ -76,10 +78,10 @@ std::string SHA1::final() { buffer += (char)0x00; } - + uint32 block[BLOCK_INTS]; buffer_to_block(buffer, block); - + if (orig_size > BLOCK_BYTES - 8) { transform(block); @@ -88,12 +90,12 @@ std::string SHA1::final() block[i] = 0; } } - + /* Append total_bits, split this uint64 into two uint32 */ block[BLOCK_INTS - 1] = total_bits; block[BLOCK_INTS - 2] = (total_bits >> 32); transform(block); - + /* Hex std::string */ std::ostringstream result; for (unsigned int i = 0; i < DIGEST_INTS; i++) @@ -101,14 +103,14 @@ std::string SHA1::final() result << std::hex << std::setfill('0') << std::setw(8); result << (digest[i] & 0xffffffff); } - + /* Reset for next run */ reset(); - + return result.str(); } - - + + std::string SHA1::from_file(const std::string &filename) { std::ifstream stream(filename.c_str(), std::ios::binary); @@ -116,8 +118,8 @@ std::string SHA1::from_file(const std::string &filename) checksum.update(stream); return checksum.final(); } - - + + void SHA1::reset() { /* SHA1 initialization constants */ @@ -126,17 +128,17 @@ void SHA1::reset() digest[2] = 0x98badcfe; digest[3] = 0x10325476; digest[4] = 0xc3d2e1f0; - + /* Reset counters */ transforms = 0; buffer = ""; } - - + + /* * Hash a single 512-bit block. This is the core of the algorithm. */ - + void SHA1::transform(uint32 block[BLOCK_BYTES]) { /* Copy digest[] to working vars */ @@ -145,8 +147,8 @@ void SHA1::transform(uint32 block[BLOCK_BYTES]) uint32 c = digest[2]; uint32 d = digest[3]; uint32 e = digest[4]; - - + + /* 4 rounds of 20 operations each. Loop unrolled. */ SHA1_R0(a,b,c,d,e, 0); SHA1_R0(e,a,b,c,d, 1); @@ -228,20 +230,20 @@ void SHA1::transform(uint32 block[BLOCK_BYTES]) SHA1_R4(d,e,a,b,c,77); SHA1_R4(c,d,e,a,b,78); SHA1_R4(b,c,d,e,a,79); - + /* Add the working vars back into digest[] */ digest[0] += a; digest[1] += b; digest[2] += c; digest[3] += d; digest[4] += e; - + /* Count the number of transformations */ transforms++; } - - -void SHA1::buffer_to_block(const std::string &buffer, uint32 block[BLOCK_BYTES]) + + +void SHA1::buffer_to_block(const std::string &buffer, uint32 block[BLOCK_INTS]) { /* Convert the std::string (byte buffer) to a uint32 array (MSB) */ for (unsigned int i = 0; i < BLOCK_INTS; i++) @@ -252,9 +254,9 @@ void SHA1::buffer_to_block(const std::string &buffer, uint32 block[BLOCK_BYTES]) | (buffer[4*i+0] & 0xff)<<24; } } - - -void SHA1::read(std::istream &is, std::string &s, int max) + + +void SHA1::read(std::istream &is, std::string &s, size_t max) { char* sbuf = new char[max]; @@ -263,8 +265,8 @@ void SHA1::read(std::istream &is, std::string &s, int max) delete[] sbuf; } - - + + std::string sha1(const std::string &string) { SHA1 checksum; diff --git a/libs/sha1/sha1.h b/libs/sha1/sha1.h index 15edee12e..898575d6c 100644 --- a/libs/sha1/sha1.h +++ b/libs/sha1/sha1.h @@ -1,27 +1,29 @@ /* sha1.h - header of - + ============ SHA-1 in C++ ============ - + 100% Public Domain. - + Original C Code -- Steve Reid Small changes to fit into bglibs -- Bruce Guenter Translation to simpler C++ Code -- Volker Grabsch + Fixing bugs and improving style + -- Eugene Hopkinson */ - + #ifndef SHA1_HPP #define SHA1_HPP - - + + #include #include - + class SHA1 { public: @@ -30,28 +32,28 @@ public: void update(std::istream &is); std::string final(); static std::string from_file(const std::string &filename); - + private: typedef unsigned long int uint32; /* just needs to be at least 32bit */ typedef unsigned long long uint64; /* just needs to be at least 64bit */ - + static const unsigned int DIGEST_INTS = 5; /* number of 32bit integers per SHA1 digest */ static const unsigned int BLOCK_INTS = 16; /* number of 32bit integers per SHA1 block */ static const unsigned int BLOCK_BYTES = BLOCK_INTS * 4; - + uint32 digest[DIGEST_INTS]; std::string buffer; uint64 transforms; - + void reset(); void transform(uint32 block[BLOCK_BYTES]); - - static void buffer_to_block(const std::string &buffer, uint32 block[BLOCK_BYTES]); - static void read(std::istream &is, std::string &s, int max); + + static void read(std::istream &is, std::string &s, size_t max); + static void buffer_to_block(const std::string &buffer, uint32 block[BLOCK_INTS]); }; - + std::string sha1(const std::string &string); - - - + + + #endif /* SHA1_HPP */ -- 2.30.2