+++ /dev/null
-/* Copyright (c) 1998,2003-2006,2008 Apple Inc.
- *
- * hashTest.c - test CDSA digest functions.
- *
- * Revision History
- * ----------------
- * 4 May 2000 Doug Mitchell
- * Ported to X/CDSA2.
- * 12 May 1998 Doug Mitchell at Apple
- * Created.
- */
-/*
- * text size = {random, from 100 bytes to 100k, in
- * geometrical steps, i.e. the number of
- * bytes would be 10^r, where r is random out of
- * {2,3,4,5,6}, plus a random integer in {0,..99}};
- *
- * for loop_count
- * text contents = {random data, random size as specified above};
- * generate digest in one shot;
- * generate digest with multiple random-sized updates;
- * verify digests compare;
- * for various bytes of text {
- * corrupt text byte;
- * generate digest in one shot;
- * veridy digest is different;
- * restore corrupted byte;
- * }
- * }
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <Security/cssm.h>
-#include "cspwrap.h"
-#include <Security/cssm.h>
-#include <Security/cssmapple.h>
-#include "cspwrap.h"
-#include "common.h"
-
-/*
- * Defaults.
- */
-#define LOOPS_DEF 50
-#define MIN_EXP 2 /* for data size 10**exp */
-#define DEFAULT_MAX_EXP 3
-#define MAX_EXP 5
-#define INCR_DEFAULT 0 /* munge every incr bytes - zero means
- * "adjust per ptext size" */
-typedef enum {
- ALG_MD2 = 1,
- ALG_MD5,
- ALG_SHA1,
- ALG_SHA224,
- ALG_SHA256,
- ALG_SHA384,
- ALG_SHA512
-};
-
-#define ALG_FIRST ALG_MD2
-#define ALG_LAST ALG_SHA512
-#define MAX_DATA_SIZE (100000 + 100) /* bytes */
-#define LOOP_NOTIFY 20
-
-static void usage(char **argv)
-{
- printf("usage: %s [options]\n", argv[0]);
- printf(" Options:\n");
- printf(" a=algorithm (s=SHA1; m=MD5; M=MD2; 4=SHA224; 2=SHA256; 3=SHA384; 5=SHA512; "
- "default=all\n");
- printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
- printf(" n=minExp (default=%d)\n", MIN_EXP);
- printf(" x=maxExp (default=%d, max=%d)\n", DEFAULT_MAX_EXP, MAX_EXP);
- printf(" i=increment (default=%d)\n", INCR_DEFAULT);
- printf(" p=pauseInterval (default=0, no pause)\n");
- printf(" z (zero data)\n");
- printf(" I (incrementing data)\n");
- printf(" g (good digest only)\n");
- printf(" D (CSP/DL; default = bare CSP)\n");
- printf(" v(erbose)\n");
- printf(" q(uiet)\n");
- printf(" h(elp)\n");
- exit(1);
-}
-
-#define LOG_FREQ 20
-
-static int doTest(CSSM_CSP_HANDLE cspHand,
- uint32 alg,
- CSSM_DATA_PTR ptext,
- CSSM_BOOL verbose,
- CSSM_BOOL quiet,
- CSSM_BOOL mallocDigest,
- unsigned incr,
- CSSM_BOOL goodOnly)
-{
- CSSM_DATA refDigest = {0, NULL};
- CSSM_DATA testDigest = {0, NULL};
- unsigned length;
- unsigned byte;
- unsigned char *data;
- unsigned char origData;
- unsigned char bits;
- int rtn = 0;
- CSSM_RETURN crtn;
- unsigned loop = 0;
-
- /*
- * generate digest in one shot;
- * generate digest with multiple random-sized updates;
- * verify digests compare;
- * for various bytes of ptext {
- * corrupt ptext byte;
- * generate digest in one shot;
- * verify digest is different;
- * restore corrupted byte;
- * }
- */
- crtn = cspDigest(cspHand,
- alg,
- mallocDigest,
- ptext,
- &refDigest);
- if(crtn) {
- rtn = testError(quiet);
- goto abort;
- }
- crtn = cspStagedDigest(cspHand,
- alg,
- mallocDigest,
- CSSM_TRUE, // multi updates
- ptext,
- &testDigest);
- if(crtn) {
- rtn = testError(quiet);
- goto abort;
- }
- if(refDigest.Length != testDigest.Length) {
- printf("Digest length mismatch (1)\n");
- rtn = testError(quiet);
- goto abort;
- }
- if(memcmp(refDigest.Data, testDigest.Data, refDigest.Length)) {
- printf("Digest miscompare (1)\n");
- rtn = testError(quiet);
- if(rtn) {
- goto abort;
- }
- }
- if(goodOnly) {
- rtn = 0;
- goto abort;
- }
- appFreeCssmData(&testDigest, CSSM_FALSE);
- testDigest.Length = 0;
- data = (unsigned char *)ptext->Data;
- length = ptext->Length;
- for(byte=0; byte<length; byte += incr) {
- if(verbose && ((loop++ % LOG_FREQ) == 0)) {
- printf("....byte %d\n", byte);
- }
- origData = data[byte];
- /*
- * Generate random non-zero byte
- */
- do {
- bits = genRand(1, 0xff) & 0xff;
- } while(bits == 0);
- data[byte] ^= bits;
- crtn = cspDigest(cspHand,
- alg,
- mallocDigest,
- ptext,
- &testDigest);
- if(crtn) {
- rtn = testError(quiet);
- break;
- }
- if(!memcmp(refDigest.Data, testDigest.Data, refDigest.Length)) {
- printf("Unexpected digest compare\n");
- rtn = testError(quiet);
- break;
- }
- appFreeCssmData(&testDigest, CSSM_FALSE);
- testDigest.Length = 0;
- data[byte] = origData;
- }
-abort:
- /* free digests */
- if(refDigest.Length) {
- appFreeCssmData(&refDigest, CSSM_FALSE);
- }
- if(testDigest.Length) {
- appFreeCssmData(&testDigest, CSSM_FALSE);
- }
- return rtn;
-}
-
-int main(int argc, char **argv)
-{
- int arg;
- char *argp;
- unsigned loop;
- CSSM_DATA ptext;
- CSSM_CSP_HANDLE cspHand;
- CSSM_BOOL mallocDigest;
- const char *algStr;
- uint32 alg; // ALG_MD5, etc.
- uint32 cssmAlg; // CSSM_ALGID_MD5, etc.
- unsigned actualIncr;
- int i;
-
- /*
- * User-spec'd params
- */
- unsigned loops = LOOPS_DEF;
- CSSM_BOOL verbose = CSSM_FALSE;
- unsigned minExp = MIN_EXP;
- unsigned maxExp = DEFAULT_MAX_EXP;
- CSSM_BOOL quiet = CSSM_FALSE;
- unsigned incr = INCR_DEFAULT;
- unsigned minAlg = ALG_FIRST;
- unsigned maxAlg = ALG_LAST;
- unsigned pauseInterval = 0;
- dataType dt;
- CSSM_BOOL goodOnly = CSSM_FALSE;
- CSSM_BOOL bareCsp = CSSM_TRUE;
-
- for(arg=1; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'a':
- if(argp[1] != '=') {
- usage(argv);
- }
- switch(argp[2]) {
- case 's':
- minAlg = maxAlg = ALG_SHA1;
- break;
- case 'm':
- minAlg = maxAlg = ALG_MD5;
- break;
- case 'M':
- minAlg = maxAlg = ALG_MD2;
- break;
- case '4':
- minAlg = maxAlg = ALG_SHA224;
- break;
- case '2':
- minAlg = maxAlg = ALG_SHA256;
- break;
- case '3':
- minAlg = maxAlg = ALG_SHA384;
- break;
- case '5':
- minAlg = maxAlg = ALG_SHA512;
- break;
- default:
- usage(argv);
- }
- break;
- case 'l':
- loops = atoi(&argp[2]);
- break;
- case 'n':
- minExp = atoi(&argp[2]);
- break;
- case 'x':
- maxExp = atoi(&argp[2]);
- if(maxExp > MAX_EXP) {
- usage(argv);
- }
- break;
- case 'i':
- incr = atoi(&argp[2]);
- break;
- case 'p':
- pauseInterval = atoi(&argp[2]);;
- break;
- case 'v':
- verbose = CSSM_TRUE;
- break;
- case 'q':
- quiet = CSSM_TRUE;
- break;
- case 'D':
- bareCsp = CSSM_FALSE;
- break;
- case 'z':
- dt = DT_Zero;
- break;
- case 'I':
- dt = DT_Increment;
- break;
- case 'g':
- goodOnly = CSSM_TRUE;
- break;
- case 'h':
- default:
- usage(argv);
- }
- }
- ptext.Data = (uint8 *)CSSM_MALLOC(MAX_DATA_SIZE);
- /* length set in test loop */
- if(ptext.Data == NULL) {
- printf("Insufficient heap\n");
- exit(1);
- }
-
- printf("Starting hashTest; args: ");
- for(i=1; i<argc; i++) {
- printf("%s ", argv[i]);
- }
- printf("\n");
- cspHand = cspDlDbStartup(bareCsp, NULL);
- if(cspHand == 0) {
- exit(1);
- }
-
- for(alg=minAlg; alg<=maxAlg; alg++) {
- switch(alg) {
- case ALG_MD5:
- algStr = "MD5";
- cssmAlg = CSSM_ALGID_MD5;
- break;
- case ALG_MD2:
- algStr = "MD2";
- cssmAlg = CSSM_ALGID_MD2;
- break;
- case ALG_SHA1:
- algStr = "SHA1";
- cssmAlg = CSSM_ALGID_SHA1;
- break;
- case ALG_SHA224:
- algStr = "SHA224";
- cssmAlg = CSSM_ALGID_SHA224;
- break;
- case ALG_SHA256:
- algStr = "SHA256";
- cssmAlg = CSSM_ALGID_SHA256;
- break;
- case ALG_SHA384:
- algStr = "SHA384";
- cssmAlg = CSSM_ALGID_SHA384;
- break;
- case ALG_SHA512:
- algStr = "SHA512";
- cssmAlg = CSSM_ALGID_SHA512;
- break;
- }
- if(!quiet) {
- printf("Testing alg %s\n", algStr);
- }
- for(loop=1; ; loop++) {
- ptext.Length = genData(ptext.Data, minExp, maxExp, dt);
- if(incr == 0) {
- /* adjust increment as appropriate */
- actualIncr = (ptext.Length / 50) + 1;
- }
- else {
- actualIncr = incr;
- }
- /* mix up mallocing */
- mallocDigest = (loop & 1) ? CSSM_TRUE : CSSM_FALSE;
- if(!quiet) {
- if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
- printf("..loop %d text size %lu mallocDigest %d\n",
- loop, (unsigned long)ptext.Length, (int)mallocDigest);
- }
- }
- if(doTest(cspHand,
- cssmAlg,
- &ptext,
- verbose,
- quiet,
- mallocDigest,
- actualIncr,
- goodOnly)) {
- exit(1);
- }
- if(loops && (loop == loops)) {
- break;
- }
- if(pauseInterval && ((loop % pauseInterval) == 0)) {
- fpurge(stdin);
- printf("Hit CR to proceed: ");
- getchar();
- }
- }
- }
- if(!quiet) {
- printf("%s test complete\n", argv[0]);
- }
- return 0;
-}