+++ /dev/null
-/*
- * hashTimeSA.cpp - measure performance of digest ops, standalone version (no
- * dependency on Security.framewortk or on CommonCrypto portion of libSystem).
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <CommonCrypto/CommonDigest.h> /* static lib used in Tiger */
-#include "MD5.h" /* CryptKit version used in Panther and prior */
-#include "SHA1.h" /* ditto */
-#include <Security/cssmtype.h> /* for ALGID values */
-#include <Security/cssmapple.h> /* more ALGID values */
-#include <CoreFoundation/CFDate.h>
-
-/* enumerate digest algorithms our way */
-typedef int HT_Alg;
-enum {
- HA_MD5 = 0,
- HA_SHA1,
- HA_SHA224,
- HA_SHA256,
- HA_SHA384,
- HA_SHA512
-};
-
-#define FIRST_ALG HA_MD5
-#define LAST_ALG HA_SHA512
-
-static void usage(char **argv)
-{
- printf("Usage: %s c|k [option ...]\n", argv[0]);
- printf(" c=CommonCrypto; k=CryptKit\n");
- printf("Options:\n");
- printf(" a=alg; default=all\n");
- printf(" algs: m : MD5\n");
- printf(" s : SHA1\n");
- printf(" 4 : SHA224\n");
- printf(" 2 : SHA256\n");
- printf(" 3 : SHA384\n");
- printf(" 5 : SHA512\n");
- printf(" l=loops (only valid if testspec is given)\n");
- printf(" v verify digest by printing it\n");
- exit(1);
-}
-
-static void dumpDigest(
- const unsigned char *digest,
- unsigned len)
-{
- for(unsigned dex=0; dex<len; dex++) {
- printf("%02X", *digest++);
- if((dex % 4) == 3) {
- printf(" ");
- }
- }
- printf("\n");
-}
-
-/* sort-of random, but repeatable */
-static void initPtext(
- unsigned char *ptext,
- unsigned len)
-{
- srandom(1);
- for(unsigned dex=0; dex<len; dex++) {
- *ptext++ = random();
- }
-}
-
-/* passed to each test */
-typedef struct {
- unsigned loops;
- CSSM_ALGORITHMS algId; // MD5, SHA1
- bool dumpDigest;
-} TestParams;
-
-#define MAX_DIGEST_SIZE 64 // we provide, no malloc below CSSM
-
-#define PTEXT_SIZE 1000 // to digest in bytes
-#define INNER_LOOPS 500
-
-
-/* SHA1 digest is not orthoganal, fix up here */
-static void ckSha1Final(
- void *ctx,
- unsigned char *digest)
-{
- sha1GetDigest((sha1Obj)ctx, digest);
-}
-
-typedef void (*ckInitFcn)(void *digestCtx);
-typedef void (*ckUpdateFcn)(void *digestCtx, const void *data, unsigned len);
-typedef void (*ckFinalFcn)(void *digestCtx, unsigned char *digest);
-
-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;
-}
-
-typedef union {
- CC_MD5_CTX md5;
- CC_SHA1_CTX sha;
- CC_SHA256_CTX sha256;
- CC_SHA512_CTX sha512;
-} CC_CTX;
-
-typedef void (*ccInitFcn)(void *digestCtx);
-typedef void (*ccUpdateFcn)(void *digestCtx, const void *data, CC_LONG len);
-typedef void (*ccFinalFcn)(unsigned char *digest, void *digestCtx);
-
-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;
-}
-
-typedef CSSM_RETURN (*testRunFcn)(TestParams *testParams);
-
-/*
- * Static declaration of a test
- */
-typedef struct {
- const char *testName;
- unsigned loops;
- testRunFcn run;
- char testSpec; // for t=xxx cmd line opt
-} TestDefs;
-
-static TestDefs testDefsCryptKit =
-{ "Large data digest, CryptKit",
- 1000,
- hashDataRateCryptKit,
- 'd',
-};
-
-static TestDefs testDefsCommonCrypto =
-{ "Large data digest, CommonCrypto",
- 1000,
- hashDataRateCommonCrypto,
- 'd',
-};
-
-static void algToAlgId(
- HT_Alg alg,
- CSSM_ALGORITHMS *algId,
- const char **algStr)
-{
- switch(alg) {
- case HA_MD5:
- *algId = CSSM_ALGID_MD5;
- *algStr = "MD5";
- break;
- case HA_SHA1:
- *algId = CSSM_ALGID_SHA1;
- *algStr = "SHA1";
- break;
- case HA_SHA224:
- *algId = CSSM_ALGID_SHA224;
- *algStr = "SHA224";
- break;
- case HA_SHA256:
- *algId = CSSM_ALGID_SHA256;
- *algStr = "SHA256";
- break;
- case HA_SHA384:
- *algId = CSSM_ALGID_SHA384;
- *algStr = "SHA384";
- break;
- case HA_SHA512:
- *algId = CSSM_ALGID_SHA512;
- *algStr = "SHA512";
- break;
- default:
- printf("***algToAlgId screwup\n");
- exit(1);
- }
-}
-
-int main(int argc, char **argv)
-{
- TestParams testParams;
- TestDefs *testDefs = NULL;
- CSSM_RETURN crtn;
- int arg;
- char *argp;
- unsigned cmdLoops = 0; // can be specified in cmd line
- // if not, use TestDefs.loops
- HT_Alg alg;
- const char *algStr;
- int firstAlg = FIRST_ALG;
- int lastAlg = LAST_ALG;
-
- memset(&testParams, 0, sizeof(testParams));
-
- if(argc < 2) {
- usage(argv);
- }
- switch(argv[1][0]) {
- case 'c':
- testDefs = &testDefsCommonCrypto;
- break;
- case 'k':
- testDefs = &testDefsCryptKit;
- break;
- default:
- usage(argv);
- }
-
- for(arg=2; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'l':
- cmdLoops = atoi(&argp[2]);
- break;
- case 'a':
- if(argp[1] == '\0') {
- usage(argv);
- }
- switch(argp[2]) {
- case 'm':
- firstAlg = lastAlg = HA_MD5;
- break;
- case 's':
- firstAlg = lastAlg = HA_SHA1;
- break;
- case '4':
- firstAlg = lastAlg = HA_SHA224;
- break;
- case '2':
- firstAlg = lastAlg = HA_SHA256;
- break;
- case '3':
- firstAlg = lastAlg = HA_SHA384;
- break;
- case '5':
- firstAlg = lastAlg = HA_SHA512;
- break;
- default:
- usage(argv);
- }
- break;
- case 'v':
- testParams.dumpDigest = true;
- break;
- default:
- usage(argv);
- }
- }
-
- printf("%s:\n", testDefs->testName);
- if(cmdLoops) {
- /* user specified */
- testParams.loops = cmdLoops;
- }
- else {
- /* default */
- testParams.loops = testDefs->loops;
- }
- if((lastAlg > HA_SHA1) && (testDefs == &testDefsCryptKit)) {
- /* CryptKit can only do MD5 and SHA1 */
- lastAlg = HA_SHA1;
- }
- for(alg=firstAlg; alg<=lastAlg; alg++) {
- algToAlgId(alg, &testParams.algId, &algStr);
- printf(" === %s ===\n", algStr);
- crtn = testDefs->run(&testParams);
- if(crtn) {
- printf("***Error detected in test, somehow....aborting.\n");
- exit(1);
- }
- }
- return 0;
-}