]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/hashCompat/hashCompat.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / hashCompat / hashCompat.c
diff --git a/SecurityTests/cspxutils/hashCompat/hashCompat.c b/SecurityTests/cspxutils/hashCompat/hashCompat.c
new file mode 100644 (file)
index 0000000..a329191
--- /dev/null
@@ -0,0 +1,321 @@
+/* 
+ * hashCompat.c - test compatibilty of two different implementations of a
+ * various digest algorithms - one in the standard AppleCSP, one in BSAFE.
+ *
+ * Written by Doug Mitchell. 
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <Security/cssm.h>
+#include <Security/cssmapple.h>
+#include "cspwrap.h"
+#include "common.h"
+#include "bsafeUtils.h"
+#include <string.h>
+
+/*
+ * Defaults.
+ */
+#define LOOPS_DEF              200
+#define MIN_EXP                        2               /* for data size 10**exp */
+#define DEFAULT_MAX_EXP        4
+#define MAX_EXP                        5
+
+#define MAX_DATA_SIZE  (100000 + 100)          /* bytes */
+#define LOOP_NOTIFY            20
+
+/*
+ * Enumerate algs our own way to allow iteration.
+ */
+enum {
+       ALG_SHA1        = 1,
+       ALG_MD5,
+       ALG_MD2
+};
+
+#define ALG_FIRST                      ALG_SHA1
+#define ALG_LAST                       ALG_MD2
+
+static void usage(char **argv)
+{
+       printf("usage: %s [options]\n", argv[0]);
+       printf("   Options:\n");
+       printf("   a=algorithm (s=SHA1; 5=MD5; 2=MD2; 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("   p=pauseInterval (default=0, no pause)\n");
+       printf("   D (CSP/DL; default = bare CSP)\n");
+       printf("   v(erbose)\n");
+       printf("   q(uiet)\n");
+       printf("   h(elp)\n");
+       exit(1);
+}
+
+/* 
+ * generate digest using reference BSAFE.
+ */
+static CSSM_RETURN genDigestBSAFE(
+       CSSM_ALGORITHMS         hashAlg,
+       const CSSM_DATA         *inText,
+       CSSM_DATA_PTR           outText)                        // mallocd and returned
+{
+       CSSM_RETURN crtn;
+
+       crtn = buGenDigest(hashAlg,
+               inText,
+               outText);
+       return crtn;
+}
+
+/*
+ * Generate digest using CSP.
+ */
+static CSSM_RETURN genDigestCSSM(
+       CSSM_CSP_HANDLE         cspHand,
+       CSSM_ALGORITHMS         hashAlg,
+       const CSSM_DATA         *inText,
+       CSSM_DATA_PTR           outText)                        // mallocd and returned if doGen
+{
+
+       outText->Data = NULL;
+       outText->Length = 0;
+       return cspStagedDigest(cspHand,
+               hashAlg,
+               CSSM_TRUE,              // mallocDigest
+               CSSM_TRUE,              // multiUpdates
+               inText, 
+               outText);
+}
+
+#define LOG_FREQ       20
+
+static int doTest(CSSM_CSP_HANDLE cspHand,
+       const CSSM_DATA         *ptext,
+       uint32                          hashAlg,
+       CSSM_BOOL                       quiet)
+{
+       CSSM_DATA               hashRef = {0, NULL};            // digest, BSAFE reference
+       CSSM_DATA               hashTest = {0, NULL};           // digest, CSP test
+       int                             rtn = 0;
+       CSSM_RETURN             crtn;
+               
+       /*
+        * generate with each method;
+        * verify digests compare;
+        */
+       crtn = genDigestBSAFE(hashAlg,
+               ptext,
+               &hashRef);
+       if(crtn) {
+               return testError(quiet);
+       }
+       crtn = genDigestCSSM(cspHand,
+               hashAlg,
+               ptext,
+               &hashTest);
+       if(crtn) {
+               return testError(quiet);
+       }
+
+       /* ensure both methods resulted in same hash */
+       if(hashRef.Length != hashTest.Length) {
+               printf("hash length mismatch (1)\n");
+               rtn = testError(quiet);
+               if(rtn) {
+                       goto abort;
+               }
+       }
+       if(memcmp(hashRef.Data, hashTest.Data, hashTest.Length)) {
+               printf("hash miscompare\n");
+               rtn = testError(quiet);
+       }
+       else {
+               rtn = 0;
+       }
+abort:
+       if(hashTest.Length) {
+               CSSM_FREE(hashTest.Data);
+       }
+       if(hashRef.Length) {
+               CSSM_FREE(hashRef.Data);
+       }
+       return rtn;
+}
+
+
+int main(int argc, char **argv)
+{
+       int                                     arg;
+       char                            *argp;
+       unsigned                        loop;
+       CSSM_DATA                       ptext;
+       CSSM_CSP_HANDLE         cspHand;
+       const char                      *algStr;
+       uint32                          hashAlg;                // CSSM_ALGID_xxx 
+       int                                     i;
+       unsigned                        currAlg;                // ALG_xxx
+       int                                     rtn = 0;
+       
+       /*
+        * User-spec'd params
+        */
+       unsigned        minAlg = ALG_FIRST;
+       unsigned        maxAlg = ALG_LAST;
+       unsigned        loops = LOOPS_DEF;
+       CSSM_BOOL       verbose = CSSM_FALSE;
+       unsigned        minExp = MIN_EXP;
+       unsigned        maxExp = DEFAULT_MAX_EXP;
+       CSSM_BOOL       quiet = CSSM_FALSE;
+       unsigned        pauseInterval = 0;
+       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 '5':
+                                               minAlg = maxAlg = ALG_MD5;
+                                               break;
+                                       case '2':
+                                               minAlg = maxAlg = ALG_MD2;
+                                               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 'v':
+                       verbose = CSSM_TRUE;
+                               break;
+                       case 'D':
+                               bareCsp = CSSM_FALSE;
+                               break;
+                   case 'q':
+                       quiet = CSSM_TRUE;
+                               break;
+                   case 'p':
+                       pauseInterval = atoi(&argp[2]);;
+                               break;
+                   case 'h':
+                   default:
+                               usage(argv);
+               }
+       }
+       if(minExp > maxExp) {
+               printf("***minExp must be <= maxExp\n");
+               usage(argv);
+       }
+       ptext.Data = (uint8 *)CSSM_MALLOC(MAX_DATA_SIZE);
+       if(ptext.Data == NULL) {
+               printf("Insufficient heap space\n");
+               exit(1);
+       }
+       /* ptext length set in test loop */
+
+       printf("Starting hashCompat; args: ");
+       for(i=1; i<argc; i++) {
+               printf("%s ", argv[i]);
+       }
+       printf("\n");
+       cspHand = cspDlDbStartup(bareCsp, NULL);
+       if(cspHand == 0) {
+               exit(1);
+       }
+       if(pauseInterval) {
+               fpurge(stdin);
+               printf("Top of test; hit CR to proceed: ");
+               getchar();
+       }
+       for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
+               switch(currAlg) {
+                       case ALG_SHA1:
+                               hashAlg = CSSM_ALGID_SHA1;
+                               algStr = "SHA1";
+                               break;
+                       case ALG_MD5:
+                               hashAlg = CSSM_ALGID_MD5;
+                               algStr = "MD5";
+                               break;
+                       case ALG_MD2:
+                               hashAlg = CSSM_ALGID_MD2;
+                               algStr = "MD2";
+                               break;
+                       default:
+                               printf("***Brrzap. Bad alg.\n");
+                               exit(1);
+               }
+               
+               if(!quiet || verbose) {
+                       printf("Testing alg %s\n", algStr);
+               }
+               for(loop=1; ; loop++) {
+                       /* random ptext length and data */
+                       ptext.Length = genData(ptext.Data, minExp, maxExp, DT_Random);
+                       if(!quiet) {
+                               if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
+                                       printf("..loop %d text size %lu \n", loop, ptext.Length);
+                               }
+                       }
+                       
+                       if(doTest(cspHand,
+                                       &ptext,
+                                       hashAlg,
+                                       quiet)) {
+                               rtn = 1;
+                               break;
+                       }
+                       if(pauseInterval && ((loop % pauseInterval) == 0)) {
+                               char c;
+                               fpurge(stdin);
+                               printf("Hit CR to proceed, q to abort: ");
+                               c = getchar();
+                               if(c == 'q') {
+                                       goto testDone;
+                               }
+                       }
+                       if(loops && (loop == loops)) {
+                               break;
+                       }
+               }       /* main loop */
+               if(rtn) {
+                       break;
+               }               
+       }       /* for algs */
+       
+testDone:
+       cspShutdown(cspHand, bareCsp);
+       if(pauseInterval) {
+               fpurge(stdin);
+               printf("ModuleDetach/Unload complete; hit CR to exit: ");
+               getchar();
+       }
+       if((rtn == 0) && !quiet) {
+               printf("%s complete\n", argv[0]);
+       }
+       CSSM_FREE(ptext.Data);
+       return rtn;
+}
+
+