// JCS, There may be a more efficient method but I can't find it // because using the DoFinal/DoUpdate functions directly calls // Store/Restore at inappropriate times and scribbles over stored // data // This is the only way I've found to both generate a hash value // and get this in the correctly updated state EXPORT_C TPtrC8 CHMAC::Hash(const TDesC8& aMessage) { TPtrC8 ptr(KNullDesC8()); TPtrC8 finalPtr(KNullDesC8()); StoreState(); if (iDigest) { ptr.Set(iDigest->Final(aMessage)); iDigest->Update(iOuterPad); finalPtr.Set(iDigest->Final(ptr)); } RestoreState(); iDigest->Update(aMessage); return (finalPtr); }
static CSSM_RETURN hashDataRateCryptKit( TestParams *params) { ckUpdateFcn updatePtr = NULL; ckFinalFcn finalPtr = NULL; ckInitFcn initPtr = NULL; struct MD5Context md5; sha1Obj sha; void *ctx; unsigned loop; unsigned iloop; double startTime, endTime; double timeSpent, timeSpentMs; uint8 ptext[PTEXT_SIZE]; uint8 digest[MAX_DIGEST_SIZE]; unsigned digestLen = 16; /* we reuse this one inside the loop */ switch(params->algId) { case CSSM_ALGID_SHA1: sha = sha1Alloc(); ctx = sha; initPtr = (ckInitFcn)sha1Reinit; updatePtr = (ckUpdateFcn)sha1AddData; finalPtr = (ckFinalFcn)ckSha1Final; digestLen = 20; break; case CSSM_ALGID_MD5: ctx = &md5; initPtr = (ckInitFcn)MD5Init; updatePtr = (ckUpdateFcn)MD5Update; finalPtr = (ckFinalFcn)MD5Final; break; default: printf("***Sorry, CryptKit can only do SHA1 and MD5.\n"); return 1; } /* random data, const thru the loops */ initPtext(ptext, PTEXT_SIZE); /* start critical timing loop */ startTime = CFAbsoluteTimeGetCurrent(); for(loop=0; loop<params->loops; loop++) { initPtr(ctx); for(iloop=0; iloop<INNER_LOOPS; iloop++) { updatePtr(ctx, ptext, PTEXT_SIZE); } finalPtr(ctx, digest); } endTime = CFAbsoluteTimeGetCurrent(); timeSpent = endTime - startTime; timeSpentMs = timeSpent * 1000.0; float bytesPerLoop = INNER_LOOPS * PTEXT_SIZE; float totalBytes = params->loops * bytesPerLoop; /* careful, KByte = 1024, ms = 1/1000 */ printf(" Digest %.0f bytes : %u ops in %.2f ms; %f ms/op, %.0f KBytes/s\n", bytesPerLoop, params->loops, timeSpentMs, timeSpentMs / (double)params->loops, ((float)totalBytes / 1024.0) / timeSpent); if(params->dumpDigest) { dumpDigest(digest, digestLen); } return CSSM_OK; }
static CSSM_RETURN hashDataRateCommonCrypto( TestParams *params) { CC_CTX ctx; ccUpdateFcn updatePtr = NULL; ccFinalFcn finalPtr = NULL; ccInitFcn initPtr = NULL; unsigned loop; unsigned iloop; double startTime, endTime; double timeSpent, timeSpentMs; uint8 ptext[PTEXT_SIZE]; uint8 digest[MAX_DIGEST_SIZE]; unsigned digestLen = 16; /* we reuse this one inside the loop */ switch(params->algId) { case CSSM_ALGID_SHA1: initPtr = (ccInitFcn)CC_SHA1_Init; updatePtr = (ccUpdateFcn)CC_SHA1_Update; finalPtr = (ccFinalFcn)CC_SHA1_Final; digestLen = 20; break; case CSSM_ALGID_SHA224: initPtr = (ccInitFcn)CC_SHA224_Init; updatePtr = (ccUpdateFcn)CC_SHA224_Update; finalPtr = (ccFinalFcn)CC_SHA224_Final; digestLen = 28; break; case CSSM_ALGID_SHA256: initPtr = (ccInitFcn)CC_SHA256_Init; updatePtr = (ccUpdateFcn)CC_SHA256_Update; finalPtr = (ccFinalFcn)CC_SHA256_Final; digestLen = 32; break; case CSSM_ALGID_SHA384: initPtr = (ccInitFcn)CC_SHA384_Init; updatePtr = (ccUpdateFcn)CC_SHA384_Update; finalPtr = (ccFinalFcn)CC_SHA384_Final; digestLen = 48; break; case CSSM_ALGID_SHA512: initPtr = (ccInitFcn)CC_SHA512_Init; updatePtr = (ccUpdateFcn)CC_SHA512_Update; finalPtr = (ccFinalFcn)CC_SHA512_Final; digestLen = 64; break; case CSSM_ALGID_MD5: initPtr = (ccInitFcn)CC_MD5_Init; updatePtr = (ccUpdateFcn)CC_MD5_Update; finalPtr = (ccFinalFcn)CC_MD5_Final; digestLen = 16; break; default: printf("***BRRRZAP!\n"); return 1; } /* random data, const thru the loops */ initPtext(ptext, PTEXT_SIZE); /* start critical timing loop */ startTime = CFAbsoluteTimeGetCurrent(); for(loop=0; loop<params->loops; loop++) { initPtr(&ctx); for(iloop=0; iloop<INNER_LOOPS; iloop++) { updatePtr(&ctx, ptext, PTEXT_SIZE); } finalPtr(digest, &ctx); } endTime = CFAbsoluteTimeGetCurrent(); timeSpent = endTime - startTime; timeSpentMs = timeSpent * 1000.0; float bytesPerLoop = INNER_LOOPS * PTEXT_SIZE; float totalBytes = params->loops * bytesPerLoop; /* careful, KByte = 1024, ms = 1/1000 */ printf(" Digest %.0f bytes : %u ops in %.2f ms; %f ms/op, %.0f KBytes/s\n", bytesPerLoop, params->loops, timeSpentMs, timeSpentMs / (double)params->loops, ((float)totalBytes / 1024.0) / timeSpent); if(params->dumpDigest) { dumpDigest(digest, digestLen); } return CSSM_OK; }