"Fossies" - the Fresh Open Source Software Archive 
Member "tcpflow-1.6.1/src/be13_api/dfxml/src/hash_t.h" (19 Feb 2021, 8254 Bytes) of package /linux/misc/tcpflow-1.6.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "hash_t.h" see the
Fossies "Dox" file reference documentation.
1 /*
2 * C++ covers for md5, sha1, and sha256 (and sha512 if present)
3 *
4 * hash representation classes: md5_t, sha1_t, sha256_t (sha512_t)
5 * has generators: md5_generator(), sha1_generator(), sha256_generator()
6 *
7 * Generating a hash:
8 * sha1_t val = sha1_generator::hash_buf(buf,bufsize)
9 * sha1_t generator hasher;
10 * hasher.update(buf,bufsize)
11 * hasher.update(buf,bufsize)
12 * hasher.update(buf,bufsize)
13 * sha1_t val = hasher.final()
14 *
15 * Using the values:
16 * string val.hexdigest() --- return a hext digest
17 * val.size() --- the size of the hash in bytes
18 * uint8_t val.digest[SIZE] --- the buffer of the raw bytes
19 * uint8_t val.final() --- synonym for md.digest
20 *
21 * This can be updated in the future for Mac so that the hash__ class
22 * is then subclassed by a hash__openssl or a hash__commonCrypto class.
23 *
24 *
25 * Revision History:
26 * 2012 - Simson L. Garfinkel - Created for bulk_extractor.
27 *
28 * This file is public domain
29 */
30
31 #ifndef HASH_T_H
32 #define HASH_T_H
33
34 #include <cstring>
35 #include <cstdlib>
36
37 /**
38 * For reasons that defy explanation (at the moment), this is required.
39 */
40
41
42 #ifdef __APPLE__
43 #include <AvailabilityMacros.h>
44 #undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
45 #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
46 #endif
47
48 #include <stdint.h>
49 #include <assert.h>
50 #include <fcntl.h>
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <iostream>
54 #include <unistd.h>
55
56 #if defined(HAVE_OPENSSL_HMAC_H) && defined(HAVE_OPENSSL_EVP_H)
57 #include <openssl/hmac.h>
58 #include <openssl/evp.h>
59 #else
60 #error OpenSSL required for hash_t.h
61 #endif
62
63 #ifdef HAVE_SYS_MMAN_H
64 #include <sys/mman.h>
65 #endif
66
67 #ifdef HAVE_SYS_MMAP_H
68 #include <sys/mmap.h>
69 #endif
70
71 template<const EVP_MD *md(),size_t SIZE>
72 class hash__
73 {
74 public:
75 uint8_t digest[SIZE];
76 static size_t size() {
77 return(SIZE);
78 }
79 hash__(){
80 }
81 hash__(const uint8_t *provided){
82 memcpy(this->digest,provided,size());
83 }
84 const uint8_t *final() const {
85 return this->digest;
86 }
87 /* python like interface for hexdigest */
88 static unsigned int hex2int(char ch){
89 if(ch>='0' && ch<='9') return ch-'0';
90 if(ch>='a' && ch<='f') return ch-'a'+10;
91 if(ch>='A' && ch<='F') return ch-'A'+10;
92 return 0;
93 }
94 static unsigned int hex2int(char ch0,char ch1){
95 return (hex2int(ch0)<<4) | hex2int(ch1);
96 }
97 static hash__ fromhex(const std::string &hexbuf) {
98 hash__ res;
99 assert(hexbuf.size()==SIZE*2);
100 for(unsigned int i=0;i+1<hexbuf.size() && (i/2)<size();i+=2){
101 res.digest[i/2] = hex2int(hexbuf[i],hexbuf[i+1]);
102 }
103 return res;
104 }
105 const char *hexdigest(char *hexbuf,size_t bufsize) const {
106 const char *hexbuf_start = hexbuf;
107 for(unsigned int i=0;i<SIZE && bufsize>=3;i++){
108 snprintf(hexbuf,bufsize,"%02x",this->digest[i]);
109 hexbuf += 2;
110 bufsize -= 2;
111 }
112 return hexbuf_start;
113 }
114 std::string hexdigest() const {
115 std::string ret;
116 char buf[SIZE*2+1];
117 return std::string(hexdigest(buf,sizeof(buf)));
118 }
119 /**
120 * Convert a hex representation to binary, and return
121 * the number of bits converted.
122 * @param binbuf output buffer
123 * @param binbuf_size size of output buffer in bytes.
124 * @param hex input buffer (in hex)
125 * @return the number of converted bits.
126 */
127 static int hex2bin(uint8_t *binbuf,size_t binbuf_size,const char *hex)
128 {
129 int bits = 0;
130 while(hex[0] && hex[1] && binbuf_size>0){
131 *binbuf++ = hex2int(hex[0],hex[1]);
132 hex += 2;
133 bits += 8;
134 binbuf_size -= 1;
135 }
136 return bits;
137 }
138 static const hash__ *new_from_hex(const char *hex) {
139 hash__ *val = new hash__();
140 if(hex2bin(val->digest,sizeof(val->digest),hex)!=SIZE*8){
141 std::cerr << "invalid input " << hex << "(" << SIZE*8 << ")\n";
142 exit(1);
143 }
144 return val;
145 }
146 bool operator<(const hash__ &s2) const {
147 /* Check the first byte manually as a performance hack */
148 if(this->digest[0] < s2.digest[0]) return true;
149 if(this->digest[0] > s2.digest[0]) return false;
150 return memcmp(this->digest,s2.digest, SIZE) < 0;
151 }
152 bool operator==(const hash__ &s2) const {
153 if(this->digest[0] != s2.digest[0]) return false;
154 return memcmp(this->digest,s2.digest, SIZE) == 0;
155 }
156 friend std::ostream& operator<<(std::ostream& os,const hash__ &s2) {
157 os << s2.hexdigest();
158 return os;
159 }
160 };
161
162 typedef hash__<EVP_md5,16> md5_t;
163 typedef hash__<EVP_sha1,20> sha1_t;
164 typedef hash__<EVP_sha256,32> sha256_t;
165 #ifdef HAVE_EVP_SHA512
166 typedef hash__<EVP_sha512,64> sha512_t;
167 #endif
168
169 template<typename T>
170 inline std::string digest_name();
171 template<>
172 inline std::string digest_name<md5_t>() {
173 return "MD5";
174 }
175 template<>
176 inline std::string digest_name<sha1_t>() {
177 return "SHA1";
178 }
179 template<>
180 inline std::string digest_name<sha256_t>() {
181 return "SHA256";
182 }
183 #ifdef HAVE_EVP_SHA512
184 template<>
185 inline std::string digest_name<sha512_t>() {
186 return "SHA512";
187 }
188 #endif
189
190 template<const EVP_MD *md(),size_t SIZE>
191 class hash_generator__ { /* generates the hash */
192 private:
193 EVP_MD_CTX* mdctx; /* the context for computing the value */
194 bool initialized; /* has the context been initialized? */
195 bool finalized;
196 /* Static function to determine if something is zero */
197 static bool iszero(const uint8_t *buf,size_t bufsize){
198 for(unsigned int i=0;i<bufsize;i++){
199 if(buf[i]!=0) return false;
200 }
201 return true;
202 }
203 /* Not allowed to copy; these are prototyped but not defined, so any attempt to use them will fail, but we won't get the -Weffc++ warnings */
204 hash_generator__ & operator=(const hash_generator__ &);
205 hash_generator__(const hash_generator__ &);
206 public:
207 int64_t hashed_bytes;
208 /* This function takes advantage of the fact that different hash functions produce residues with different sizes */
209 hash_generator__():mdctx(NULL),initialized(false),finalized(false),hashed_bytes(0){ }
210 ~hash_generator__(){
211 release();
212 }
213 void release(){ /* free allocated memory */
214 if(initialized){
215 #ifdef HAVE_EVP_MD_CTX_FREE
216 EVP_MD_CTX_free(mdctx);
217 #else
218 EVP_MD_CTX_destroy(mdctx);
219 #endif
220 initialized = false;
221 hashed_bytes = 0;
222 }
223 }
224 void init(){
225 if(initialized==false){
226 #ifdef HAVE_EVP_MD_CTX_NEW
227 mdctx = EVP_MD_CTX_new();
228 #else
229 mdctx = EVP_MD_CTX_create();
230 #endif
231 if (!mdctx) throw std::bad_alloc();
232 EVP_DigestInit_ex(mdctx, md(), NULL);
233 initialized = true;
234 finalized = false;
235 hashed_bytes = 0;
236 }
237 }
238 void update(const uint8_t *buf,size_t bufsize){
239 if(!initialized) init();
240 if(finalized){
241 std::cerr << "hashgen_t::update called after finalized\n";
242 exit(1);
243 }
244 EVP_DigestUpdate(mdctx,buf,bufsize);
245 hashed_bytes += bufsize;
246 }
247 hash__<md,SIZE> final() {
248 if(finalized){
249 std::cerr << "currently friendly_geneator does not cache the final value\n";
250 assert(0);
251 exit(1); // in case compiled with assertions disabled
252 }
253 if(!initialized){
254 init(); /* do it now! */
255 }
256 hash__<md,SIZE> val;
257 unsigned int len = sizeof(val.digest);
258 EVP_DigestFinal(mdctx,val.digest,&len);
259 finalized = true;
260 return val;
261 }
262
263 /** Compute a sha1 from a buffer and return the hash */
264 static hash__<md,SIZE> hash_buf(const uint8_t *buf,size_t bufsize){
265 /* First time through find the SHA1 of 512 NULLs */
266 hash_generator__ g;
267 g.update(buf,bufsize);
268 return g.final();
269 }
270
271 #ifdef HAVE_MMAP
272 /** Static method allocateor */
273 static hash__<md,SIZE> hash_file(const char *fname){
274 int fd = open(fname,O_RDONLY
275 #ifdef O_BINARY
276 |O_BINARY
277 #endif
278 );
279 if(fd<0) throw fname;
280 struct stat st;
281 if(fstat(fd,&st)<0){
282 close(fd);
283 throw fname;
284 }
285 const uint8_t *buf = (const uint8_t *)mmap(0,st.st_size,PROT_READ,MAP_FILE|MAP_SHARED,fd,0);
286 if(buf==0){
287 close(fd);
288 throw fname;
289 }
290 hash__<md,SIZE> s = hash_buf(buf,st.st_size);
291 munmap((void *)buf,st.st_size);
292 close(fd);
293 return s;
294 }
295 #endif
296 };
297
298 typedef hash_generator__<EVP_md5,16> md5_generator;
299 typedef hash_generator__<EVP_sha1,20> sha1_generator;
300 typedef hash_generator__<EVP_sha256,32> sha256_generator;
301
302 #ifdef HAVE_EVP_SHA512
303 typedef hash_generator__<EVP_sha512,64> sha512_generator;
304 #define HAVE_SHA512_T
305 #endif
306
307 #endif