int checkhash(unsigned char *data, size_t datalen, char *checkhash) { char keyword[100]; memcpy(together + pos, data, datalen); pos += datalen; mhash_keygen((keygenid)0, (hashid)10, 10, keyword, 100, (void *)"aaaa", 3, key, keylen); MHASH hash = mhash_hmac_init((hashid)10, keyword, 100, mhash_get_hash_pblock((hashid)10)); mhash(hash, data, datalen); void *mac = mhash_hmac_end(hash); char hash_printed[1000] = "0x"; for (int j = 0; j < mhash_get_block_size((hashid)10); j++) { unsigned char *m = (unsigned char *)mac; char r[3]; snprintf(r, 3, "%.2x", m[j]); strcat(hash_printed, r); } printf("%s\n", hash_printed); return strcmp(hash_printed, checkhash) == 0; }
/* test HMAC */ int verify_hmac(const void *data, size_t datalen, hashid hid, unsigned char *hmac, char *key, int keylen) { MHASH td; unsigned char *our_hmac = NULL; int rc = -1; td = mhash_hmac_init(hid, key, keylen, mhash_get_hash_pblock(hid)); if (!td) return -1; our_hmac = malloc(mhash_get_block_size(hid)); if (!our_hmac) return -1; (void)mhash(td, data, datalen); if (mhash_hmac_deinit(td, our_hmac)) goto out_free; rc = memcmp(our_hmac, hmac, mhash_get_block_size(hid)); out_free: if (our_hmac) free(our_hmac); return rc; }
static unsigned digest_block_size(PX_MD * h) { MHASH mh = (MHASH) h->p.ptr; hashid id = mhash_get_mhash_algo(mh); return mhash_get_hash_pblock(id); }
int conf_input_wrapper(char* buf, int max_size, FILE* in) { int retval=0; int c=0; char* tmp=NULL; void* key=NULL; int keylen=0; /* FIXME Add support for gzipped config. :) */ #ifdef WITH_MHASH /* Read a character at a time until we are doing md */ if(conf->do_configmd){ retval=fread(buf,1,max_size,in); }else { c=fgetc(in); retval= (c==EOF) ? 0 : (buf[0] = c,1); } #else retval=fread(buf,1,max_size,in); #endif #ifdef WITH_MHASH if(conf->do_configmd||conf->config_check){ if(((conf->do_configmd==1)&&conf->config_check)||!conf->confmd){ if(conf->do_configmd==1){ conf->do_configmd+=1; } if((key=get_conf_key())!=NULL){ keylen=get_conf_key_len(); if( (conf->confmd= mhash_hmac_init(conf->confhmactype, key, keylen, mhash_get_hash_pblock(conf->confhmactype)))== MHASH_FAILED){ error(0, "mhash_hmac_init() failed for %i for config check. Aborting\n", conf->confhmactype); exit(EXIT_FAILURE); } } else { conf->do_configmd=0; return retval; } } /* FIXME This does not handle the case that @@end_config is on buffer boundary. */ if((tmp=strnstr(buf,"@@end_config",retval))!=NULL){ /* We have end of config don't feed the last line to mhash */ mhash(conf->confmd,(void*)buf,tmp-buf); } else { mhash(conf->confmd,(void*)buf,retval); } } #endif return retval; }
static const char * vmod_hmac_sha256(const struct vrt_ctx *ctx, const char *key,size_t lkey, const char *msg,size_t lmsg,bool raw) { hashid hash = MHASH_SHA256; size_t blocksize = mhash_get_block_size(hash); char *p; char *ptmp; p = WS_Alloc(ctx->ws, blocksize * 2 + 1); ptmp = p; unsigned char *mac; unsigned u; u = WS_Reserve(ctx->ws, 0); assert(u > blocksize); mac = (unsigned char*)ctx->ws->f; int i; MHASH td; assert(msg); assert(key); assert(mhash_get_hash_pblock(hash) > 0); td = mhash_hmac_init(hash, (void *) key, lkey, mhash_get_hash_pblock(hash)); mhash(td, msg, lmsg); mhash_hmac_deinit(td,mac); if(raw){ WS_Release(ctx->ws, blocksize); return (char *)mac; } WS_Release(ctx->ws, 0); for (i = 0; i<blocksize;i++) { sprintf(ptmp,"%.2x",mac[i]); ptmp+=2; } return p; }
int main(void) { hashid hashid; const char *s; int ok, allok = 1; for(hashid = 0; hashid <= mhash_count(); hashid++) if ((s = mhash_get_hash_name_static(hashid)) && mhash_get_hash_pblock(hashid)) { printf("Checking fragmentation capabilities of %s: ", s); fflush(stdout); printf((ok = frag_test(hashid)) ? "OK\n" : "Failed\n"); allok &= ok; } return allok ? 0 : 1; }
/* calculate the HMAC of the message in data and store it in result * it is up to the caller to make sure that there's enough space * at result for the MAC */ int calc_hmac(const void *data, size_t datalen, hashid hid, unsigned char *result, char *key, int keylen) { MHASH td; size_t block_size; block_size = mhash_get_hash_pblock(hid); if (!block_size) return -1; td = mhash_hmac_init(hid, key, keylen, block_size); if (!td) return -1; (void)mhash(td, data, datalen); if (mhash_hmac_deinit(td, result)) return -1; return 0; }
int db_input_wrapper(char* buf, int max_size, int db) { int retval=0; int c=0; int err=0; int* domd=NULL; url_t* db_url=NULL; #ifdef WITH_MHASH char* tmp=NULL; MHASH* md=NULL; void* key=NULL; int keylen; #endif FILE** db_filep=NULL; #ifdef WITH_ZLIB gzFile* db_gzp=NULL; #endif switch(db) { case DB_OLD: { db_url=conf->db_in_url; domd=&(conf->do_dboldmd); #ifdef WITH_MHASH md=&(conf->dboldmd); #endif db_filep=&(conf->db_in); #ifdef WITH_ZLIB db_gzp=&(conf->db_gzin); #endif break; } case DB_NEW: { db_url=conf->db_new_url; domd=&(conf->do_dbnewmd); #ifdef WITH_MHASH md=&(conf->dbnewmd); #endif db_filep=&(conf->db_new); #ifdef WITH_ZLIB db_gzp=&(conf->db_gznew); #endif break; } } #ifdef WITH_CURL switch (db_url->type) { case url_http: case url_https: case url_ftp: { retval=url_fread(buf,1,max_size,(URL_FILE *)*db_filep); break; } default: #endif /* WITH CURL */ /* Read a character at a time until we are doing md */ #ifdef WITH_ZLIB if((*db_gzp==NULL)&&(*domd)){ retval=fread(buf,1,max_size,*db_filep); } if((*db_gzp!=NULL)&&(*domd)){ if(gzeof(*db_gzp)){ retval=0; buf[0]='\0'; }else { if((retval=gzread(*db_gzp,buf,max_size))<0){ error(0,_("gzread() failed: gzerr=%s!\n"),gzerror(*db_gzp,&err)); retval=0; buf[0]='\0'; } else { /* gzread returns 0 even if uncompressed bytes were read*/ error(240,"nread=%d,strlen(buf)=%lu,errno=%s,gzerr=%s\n", retval,(unsigned long)strnlen((char*)buf, max_size), strerror(errno),gzerror(*db_gzp,&err)); if(retval==0){ retval=strnlen((char*)buf, max_size); } } } } if((*db_gzp!=NULL)&&!(*domd)){ c=gzgetc(*db_gzp); retval= (c==EOF) ? 0 : (buf[0] = c,1); } if((*db_gzp==NULL)&&!(*domd)){ c=fgetc(*db_filep); if(c==(unsigned char)'\037'){ c=fgetc(*db_filep); if(c==(unsigned char)'\213'){ /* We got gzip header. */ error(255,"Got Gzip header. Handling..\n"); lseek(fileno(*db_filep),0L,SEEK_SET); *db_gzp=gzdopen(fileno(*db_filep),"rb"); c=gzgetc(*db_gzp); error(255,"First character after gzip header is: %c(%#X)\n",c,c); if(c==-1) { int xx; error(0,"Error reading gzipped file: %s\n",gzerror(*db_gzp,&xx)); exit(EXIT_FAILURE); } }else { /* False alarm */ ungetc(c,*db_filep); } } retval= (c==EOF) ? 0 : (buf[0] = c,1); } #else /* WITH_ZLIB */ #ifdef WITH_MHASH if(*domd){ retval=fread(buf,1,max_size,*db_filep); }else { c=fgetc(*db_filep); retval= (c==EOF) ? 0 : (buf[0] = c,1); } #else /* WITH_MHASH */ retval=fread(buf,1,max_size,*db_filep); #endif /* WITH_MHASH */ #endif /* WITH_ZLIB */ #ifdef WITH_MHASH if(*domd){ if(!*md){ if((key=get_db_key())!=NULL){ keylen=get_db_key_len(); if( (*md= mhash_hmac_init(conf->dbhmactype, key, keylen, mhash_get_hash_pblock(conf->dbhmactype)))== MHASH_FAILED){ error(0, "mhash_hmac_init() failed for db check. Aborting\n"); exit(EXIT_FAILURE); } } else { *domd=0; } } /* FIXME This does not handle the case that @@end_config is on buffer boundary. */ if (*domd!=0) { if((tmp=strnstr(buf,"@@end_db",retval))!=NULL){ /* We have end of db don't feed the last line to mhash */ mhash(*md,(void*)buf,tmp-buf); /* We don't want to come here again after the *md has been deinited by db_readline_file() */ *domd=0; } else { mhash(*md,(void*)buf,retval); } } } #endif #ifdef WITH_CURL } #endif /* WITH CURL */ return retval; }
int main() { mutils_word8 *tmp; mutils_word8 *password; mutils_word32 passlen; mutils_word8 *data; mutils_word32 datalen; MHASH td; mutils_word8 *mac; mutils_word32 j; int result; passlen=sizeof(KEY1) - 1; password = mutils_malloc(passlen + 1); mutils_memcpy(password, (mutils_word8 *) KEY1, passlen); datalen = mutils_strlen((mutils_word8 *) DATA1); data = mutils_malloc(datalen+1); mutils_strcpy(data, (mutils_word8 *) DATA1); td = mhash_hmac_init(MHASH_MD5, password, passlen, mhash_get_hash_pblock(MHASH_MD5)); mhash(td, data, datalen); mac = mhash_hmac_end(td); tmp = mutils_asciify(mac, mhash_get_block_size(MHASH_MD5)); result = mutils_strcmp((mutils_word8 *) DIGEST1, tmp); mutils_free(password); mutils_free(data); if (result != 0) { fprintf(stderr, "HMAC-Test: Failed\n"); fprintf(stderr, "Digest size: %d\n", mhash_get_block_size(MHASH_MD5)); fprintf(stderr, "Expecting: 0x%s\n", DIGEST1); fprintf(stderr, "Got: 0x%s\n", tmp); return(MUTILS_INVALID_RESULT); } mutils_free(tmp); /* Test No 2 */ mutils_memset(tmp, 0, sizeof(tmp)); passlen=sizeof(KEY2) - 1; password = (mutils_word8 *) mutils_malloc(passlen+1); mutils_memcpy(password, KEY2, passlen); datalen = mutils_strlen((mutils_word8 *) DATA2); data = (mutils_word8 *) mutils_malloc(datalen+1); mutils_strcpy(data, (mutils_word8 *) DATA2); td = mhash_hmac_init(MHASH_MD5, password, passlen, mhash_get_hash_pblock(MHASH_MD5)); mhash(td, data, datalen); mac = mhash_hmac_end(td); tmp = mutils_asciify(mac, mhash_get_block_size(MHASH_MD5)); result = mutils_strcmp((mutils_word8 *) DIGEST2, tmp); mutils_free(password); mutils_free(data); if (result != 0) { fprintf(stderr, "HMAC-Test: Failed\n"); fprintf(stderr, "Expecting: 0x%s\nGot: 0x%s\n", DIGEST2, tmp); return(MUTILS_INVALID_RESULT); } fprintf(stderr, "MD5 HMAC-Test: Ok\n"); mutils_free(tmp); return(MUTILS_OK); }
int frag_test(hashid hashid) { unsigned char digest1[MAX_DIGEST_SIZE]; /* enough space to hold digests */ unsigned char digest2[MAX_DIGEST_SIZE]; unsigned char buf1[MAX_INPUT_SIZE + 1]; unsigned char buf2[MAX_INPUT_SIZE]; MHASH td1, td2; size_t input_size, digest_size; int i, offs, left; unsigned char val = 0; input_size = mhash_get_hash_pblock(hashid); assert(input_size <= MAX_INPUT_SIZE); digest_size = mhash_get_block_size(hashid); assert(digest_size <= MAX_DIGEST_SIZE); td1 = mhash_init(hashid); /* get two mhash instances */ td2 = mhash_init(hashid); for(i = offs = 0; i < 2 * input_size; i++, val++) /* first part */ { memset(buf1, val, input_size + 1); /* the first instance gets framgments */ mhash(td1, buf1, input_size + 1); /* of size (input_size+1) */ left = input_size - offs; /* the second instance gets fragments */ memset(buf2 + offs, val, left); /* of size input_size */ mhash(td2, buf2, input_size); offs = (input_size + 1) - left; memset(buf2, val, offs); if (offs == input_size) { mhash(td2, buf2, input_size); offs = 0; } } mhash(td2, buf2, offs); for(i = offs = 0; i < 2 * input_size; i++, val++) /* second part */ { memset(buf1, val, input_size - 1); /* the first instance gets framgments */ mhash(td1, buf1, input_size - 1); /* of size (input_size-1) */ if (offs == 0) /* the second instance gets fragments */ { /* of size input_size */ offs = input_size - 1; memset(buf2, val, offs); } else { left = input_size - offs; memset(buf2 + offs, val, left); mhash(td2, buf2, input_size); offs = (input_size - 1) - left; memset(buf2, val, offs); } } mhash(td2, buf2, offs); mhash_deinit(td1, digest1); /* return 1 if the calculated hash values match */ mhash_deinit(td2, digest2); return ! strncmp(digest1, digest2, digest_size); }