"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