C4Err TestHashKAT( int algor, char *name, uint8_t *msg, size_t msgsize, int passes, uint8_t * expected, size_t expectedLen) { uint8_t hashBuf [256]; uint8_t hashState [kHASH_ContextAllocSize]; size_t hashStateLen = 0; C4Err err = kC4Err_NoErr; int i; HASH_ContextRef hash = kInvalidHASH_ContextRef; err = HASH_Init(algor, &hash); err = HASH_Export(hash, hashState, sizeof(hashState), &hashStateLen); HASH_Free(hash); hash = NULL; err = HASH_Import(hashState, hashStateLen, &hash); CKERR; ZERO(hashState, sizeof(hashState)); /* calculate the hash.. */ for (i = 0; i < passes; i++) { err = HASH_Update( hash, msg, msgsize); CKERR; err = HASH_Export(hash, hashState, sizeof(hashState), &hashStateLen); HASH_Free(hash); hash = NULL; err = HASH_Import(hashState, hashStateLen, &hash); CKERR; ZERO(hashState, sizeof(hashState)); } err = HASH_Final (hash, hashBuf); CKERR; err = ( compareResults( expected, hashBuf, expectedLen , kResultFormat_Byte, "Message Digest")); CKERR; /* quick HASH API */ if(passes == 1) { err = HASH_DO(algor, msg, msgsize, sizeof(hashBuf), hashBuf); CKERR; err = ( compareResults( expected, hashBuf, expectedLen , kResultFormat_Byte, "Quick HASH")); CKERR; } done: if( HASH_ContextRefIsValid(hash)) HASH_Free(hash); return err; }
C4Err ECC_PubKeyHash( ECC_ContextRef ctx, void *outData, size_t bufSize, size_t *outDataLen) { C4Err err = kC4Err_NoErr; HASH_ContextRef hash = kInvalidHASH_ContextRef; uint8_t pubKey[256]; size_t pubKeyLen = 0; u08b_t hashBuf[16]; size_t hashBytes = 0; validateECCContext(ctx); ValidateParam(ctx->isInited); ValidateParam(outData); err = HASH_Init(kHASH_Algorithm_SHA256, &hash); CKERR; err = ECC_Export_ANSI_X963( ctx, pubKey, sizeof(pubKey), &pubKeyLen);CKERR; err = HASH_Update(hash, pubKey, pubKeyLen) ;CKERR; err = HASH_Final(hash,hashBuf); err = HASH_GetSize(hash, &hashBytes); hashBytes = bufSize < hashBytes ? bufSize :hashBytes; memcpy( outData,hashBuf, hashBytes); if(outDataLen) *outDataLen = hashBytes; done: if(HASH_ContextRefIsValid(hash)) HASH_Free(hash); return err; }
C4Err HASH_DO(HASH_Algorithm algorithm, const unsigned char *in, unsigned long inlen, unsigned long outLen, uint8_t *out) { C4Err err = kC4Err_NoErr; HASH_ContextRef hashRef = kInvalidHASH_ContextRef; uint8_t hashBuf[128]; uint8_t *p = (outLen < sizeof(hashBuf))?hashBuf:out; #if _USES_COMMON_CRYPTO_ /* use apple algorithms if possible*/ switch(algorithm) { case kHASH_Algorithm_MD5: CC_MD5(in, (CC_LONG) inlen, hashBuf); goto complete; break; case kHASH_Algorithm_SHA1: CC_SHA1(in, (CC_LONG) inlen, hashBuf); goto complete; break; case kHASH_Algorithm_SHA224: CC_SHA224(in, (CC_LONG) inlen, hashBuf); goto complete; break; case kHASH_Algorithm_SHA256: CC_SHA256(in, (CC_LONG) inlen, hashBuf); goto complete; break; case kHASH_Algorithm_SHA384: CC_SHA384(in, (CC_LONG) inlen, hashBuf); goto complete; break; case kHASH_Algorithm_SHA512: CC_SHA512(in, (CC_LONG) inlen, hashBuf); goto complete; break; default: break; } #endif err = HASH_Init( algorithm, & hashRef); CKERR; err = HASH_Update( hashRef, in, inlen); CKERR; err = HASH_Final( hashRef, p); CKERR; complete: if((err == kC4Err_NoErr) & (p!= out)) COPY(hashBuf, out, outLen); done: if(!IsNull(hashRef)) HASH_Free(hashRef); return err; }
SCLError Siren_ComputeHash( HASH_Algorithm hash, const char* sirenData, uint8_t* hashOut, bool sorted) { SCLError err = kSCLError_NoErr; yajl_gen_status stat = yajl_gen_status_ok; yajl_handle pHand = NULL; SirenJSONcontext *jctx = NULL; static yajl_callbacks callbacks = { NULL, sParse_bool, NULL, NULL, sParse_number, sParse_string, sParse_start_map, sParse_map_key, sParse_end_map, NULL, NULL }; yajl_alloc_funcs allocFuncs = { yajlMalloc, yajlRealloc, yajlFree, (void *) NULL }; jctx = XMALLOC(sizeof (SirenJSONcontext)); CKNULL(jctx); ZERO(jctx, sizeof(SirenJSONcontext)); err = HASH_Init(hash, &jctx->hash); CKERR; // use yajl to fill the hashableItems with tags and values we can hash pHand = yajl_alloc(&callbacks, &allocFuncs, (void *) jctx); yajl_config(pHand, yajl_allow_comments, 1); stat = (yajl_gen_status) yajl_parse(pHand, (uint8_t*)sirenData, strlen(sirenData)); CKSTAT; stat = (yajl_gen_status) yajl_complete_parse(pHand); CKSTAT; // hash the items found in hashableItems using sHashable_tags_list order int items2Hash = jctx->hashableItemsCount; #if DEBUG_HASH DPRINTF(XCODE_COLORS_RED_TXT,"\nSiren_ComputeHash %s\n", sorted?"sorted":"" ); #endif if(sorted) { for(int j = 0; sHashable_tags_list[j] && items2Hash > 0; j++) { for(int i = 0; i < jctx->hashableItemsCount; i++) { char* tag = sHashable_tags_list[j]; HashableItem *item = &jctx->hashableItems[i]; if(item->tag && strncmp(tag, item->tag, strlen(tag)) == 0 ) { err = shashItem(jctx->hash, item); items2Hash--; break; } } } } else { for(int i = 0; i < items2Hash; i++) { HashableItem *item = &jctx->hashableItems[i]; if(item->tag) { err = shashItem(jctx->hash, item); } } } err = HASH_Final(jctx->hash, hashOut); CKERR; #if DEBUG_HASH DPRINTF(XCODE_COLORS_RED_TXT,"\n"); dumpHex(hashOut, 32, 0); DPRINTF(XCODE_COLORS_RED_TXT,"\n"); #endif done: if(IsntNull(jctx)) { ZERO(jctx, sizeof(SirenJSONcontext)); XFREE(jctx); } if(IsntNull(pHand)) yajl_free(pHand); return err; }