X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/cspxutils/hashTest/hashTest.c diff --git a/SecurityTests/cspxutils/hashTest/hashTest.c b/SecurityTests/cspxutils/hashTest/hashTest.c new file mode 100644 index 00000000..b791b8a5 --- /dev/null +++ b/SecurityTests/cspxutils/hashTest/hashTest.c @@ -0,0 +1,397 @@ +/* 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 +#include +#include +#include +#include +#include "cspwrap.h" +#include +#include +#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 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