--- /dev/null
+/*
+ * asymCompat.c - test compatibilty of two different implementations of a
+ * RSA and DSA - one in the standard AppleCSP, one in BSAFE.
+ */
+
+#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>
+#include "cspdlTesting.h"
+
+/*
+ * Defaults.
+ */
+#define OLOOPS_DEF 10 /* outer loops, one set of keys per loop */
+#define SIG_LOOPS_DEF 100 /* sig loops */
+#define ENC_LOOPS_DEF 100 /* encrypt/decrypt loops */
+#define MAX_TEXT_SIZE 1025
+
+#define LOOP_NOTIFY 20
+
+static void usage(char **argv)
+{
+ printf("usage: %s [options]\n", argv[0]);
+ printf(" Options:\n");
+ printf(" a=algorithm (r=RSA; d=DSA; default=both)\n");
+ printf(" l=outerloops (default=%d; 0=forever)\n", OLOOPS_DEF);
+ printf(" s=sigLoops (default=%d)\n", SIG_LOOPS_DEF);
+ printf(" e=encryptLoops (default=%d)\n", ENC_LOOPS_DEF);
+ printf(" k=keySizeInBits; default is random\n");
+ printf(" S (sign/verify only)\n");
+ printf(" E (encrypt/decrypt only)\n");
+ printf(" r (generate ref keys)\n");
+ printf(" R (generate public ref keys)\n");
+ 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);
+}
+
+static const char *algToStr(CSSM_ALGORITHMS sigAlg)
+{
+ switch(sigAlg) {
+ case CSSM_ALGID_RSA: return "RSA";
+ case CSSM_ALGID_DSA: return "DSA";
+ case CSSM_ALGID_SHA1WithRSA: return "SHA1WithRSA";
+ case CSSM_ALGID_MD5WithRSA: return "MD5WithRSA";
+ case CSSM_ALGID_SHA1WithDSA: return "SHA1WithDSA";
+ default:
+ printf("***Unknown sigAlg\n");
+ exit(1);
+ }
+ /* NOT REACHED */
+ return "";
+}
+
+/*
+ * CDSA private key decrypt with blinding option.
+ */
+static CSSM_RETURN _cspDecrypt(CSSM_CSP_HANDLE cspHand,
+ uint32 algorithm, // CSSM_ALGID_FEED, etc.
+ uint32 mode, // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
+ CSSM_PADDING padding, // CSSM_PADDING_PKCS1, etc.
+ CSSM_BOOL blinding,
+ const CSSM_KEY *key, // public or session key
+ const CSSM_DATA *ctext,
+ CSSM_DATA_PTR ptext) // RETURNED
+{
+ CSSM_CC_HANDLE cryptHand;
+ CSSM_RETURN crtn;
+ CSSM_RETURN ocrtn = CSSM_OK;
+ CSSM_SIZE bytesDecrypted;
+ CSSM_DATA remData = {0, NULL};
+
+ cryptHand = genCryptHandle(cspHand,
+ algorithm,
+ mode,
+ padding,
+ key,
+ NULL, // pubKey,
+ NULL, // iv,
+ 0, // effectiveKeySizeInBits,
+ 0); // rounds
+ if(cryptHand == 0) {
+ return CSSMERR_CSP_INTERNAL_ERROR;
+ }
+ if(blinding) {
+ CSSM_CONTEXT_ATTRIBUTE newAttr;
+ newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING;
+ newAttr.AttributeLength = sizeof(uint32);
+ newAttr.Attribute.Uint32 = 1;
+ crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &newAttr);
+ if(crtn) {
+ printError("CSSM_UpdateContextAttributes", crtn);
+ return crtn;
+ }
+ }
+
+ crtn = CSSM_DecryptData(cryptHand,
+ ctext,
+ 1,
+ ptext,
+ 1,
+ &bytesDecrypted,
+ &remData);
+ if(crtn == CSSM_OK) {
+ // NOTE: We return the proper length in ptext....
+ ptext->Length = bytesDecrypted;
+
+ // FIXME - sometimes get mallocd RemData here, but never any valid data
+ // there...side effect of CSPFullPluginSession's buffer handling logic;
+ // but will we ever actually see valid data in RemData? So far we never
+ // have....
+ if(remData.Data != NULL) {
+ appFree(remData.Data, NULL);
+ }
+ }
+ else {
+ printError("CSSM_DecryptData", crtn);
+ ocrtn = crtn;
+ }
+ crtn = CSSM_DeleteContext(cryptHand);
+ if(crtn) {
+ printError("CSSM_DeleteContext", crtn);
+ ocrtn = crtn;
+ }
+ return ocrtn;
+}
+
+/* sign with RSA blinging option */
+static CSSM_RETURN _cspSign(CSSM_CSP_HANDLE cspHand,
+ uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc.
+ CSSM_KEY_PTR key, // private key
+ const CSSM_DATA *text,
+ CSSM_BOOL rsaBlinding,
+ CSSM_DATA_PTR sig) // RETURNED
+{
+ CSSM_CC_HANDLE sigHand;
+ CSSM_RETURN crtn;
+ CSSM_RETURN ocrtn = CSSM_OK;
+ const CSSM_DATA *ptext;
+ CSSM_DATA digest = {0, NULL};
+ CSSM_ALGORITHMS digestAlg = CSSM_ALGID_NONE;
+
+ /* handle special cases for raw sign */
+ switch(algorithm) {
+ case CSSM_ALGID_SHA1:
+ digestAlg = CSSM_ALGID_SHA1;
+ algorithm = CSSM_ALGID_RSA;
+ break;
+ case CSSM_ALGID_MD5:
+ digestAlg = CSSM_ALGID_MD5;
+ algorithm = CSSM_ALGID_RSA;
+ break;
+ case CSSM_ALGID_DSA:
+ digestAlg = CSSM_ALGID_SHA1;
+ algorithm = CSSM_ALGID_DSA;
+ break;
+ default:
+ break;
+ }
+ if(digestAlg != CSSM_ALGID_NONE) {
+ crtn = cspDigest(cspHand,
+ digestAlg,
+ CSSM_FALSE, // mallocDigest
+ text,
+ &digest);
+ if(crtn) {
+ return crtn;
+ }
+ /* sign digest with raw RSA/DSA */
+ ptext = &digest;
+ }
+ else {
+ ptext = text;
+ }
+ crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+ algorithm,
+ NULL, // passPhrase
+ key,
+ &sigHand);
+ if(crtn) {
+ printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
+ return crtn;
+ }
+ if(rsaBlinding) {
+ CSSM_CONTEXT_ATTRIBUTE newAttr;
+ newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING;
+ newAttr.AttributeLength = sizeof(uint32);
+ newAttr.Attribute.Uint32 = 1;
+ crtn = CSSM_UpdateContextAttributes(sigHand, 1, &newAttr);
+ if(crtn) {
+ printError("CSSM_UpdateContextAttributes", crtn);
+ return crtn;
+ }
+ }
+ crtn = CSSM_SignData(sigHand,
+ ptext,
+ 1,
+ digestAlg,
+ sig);
+ if(crtn) {
+ printError("CSSM_SignData", crtn);
+ ocrtn = crtn;
+ }
+ crtn = CSSM_DeleteContext(sigHand);
+ if(crtn) {
+ printError("CSSM_DeleteContext", crtn);
+ ocrtn = crtn;
+ }
+ if(digest.Data != NULL) {
+ CSSM_FREE(digest.Data);
+ }
+ return ocrtn;
+}
+
+
+/*
+ * Sign/verify test.
+ *
+ * for specified numLoops {
+ * generate random text;
+ * sign with BSAFE priv key, verify with CDSA pub key;
+ * sign with CDSA priv key, verify with BSAFE pub key;
+ * }
+ */
+static int sigTest(
+ CSSM_CSP_HANDLE cspHand,
+ unsigned numLoops,
+
+ /* one matched key pair */
+ BU_KEY bsafePrivKey,
+ CSSM_KEY_PTR cdsaPubKey,
+
+ /* another matched key pair */
+ CSSM_KEY_PTR cdsaPrivKey,
+ BU_KEY bsafePubKey,
+
+ CSSM_DATA_PTR ptext,
+ unsigned maxPtextSize,
+ CSSM_ALGORITHMS sigAlg,
+ CSSM_BOOL rsaBlinding,
+ CSSM_BOOL quiet,
+ CSSM_BOOL verbose)
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA sig = {0, NULL};
+ unsigned loop;
+ uint32 keySizeInBits = cdsaPrivKey->KeyHeader.LogicalKeySizeInBits;
+
+ if(!quiet) {
+ printf(" ...sig alg %s keySize %u\n", algToStr(sigAlg), (unsigned)keySizeInBits);
+ }
+ for(loop=0; loop<numLoops; loop++) {
+ simpleGenData(ptext, 1, maxPtextSize);
+ if(!quiet) {
+ if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
+ printf(" ...loop %d keySize %u textSize %lu\n",
+ loop, (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits,
+ (unsigned long)ptext->Length);
+ }
+ }
+
+ /* sign with BSAFE, verify with CDSA */
+ crtn = buSign(bsafePrivKey,
+ sigAlg,
+ ptext,
+ keySizeInBits,
+ &sig);
+ if(crtn) {
+ return testError(quiet);
+ }
+ crtn = cspSigVerify(cspHand,
+ sigAlg,
+ cdsaPubKey,
+ ptext,
+ &sig,
+ CSSM_OK);
+ if(crtn) {
+ printf("***ERROR: Sign with BSAFE, vfy with CDSA, alg %s\n",
+ algToStr(sigAlg));
+ if(testError(quiet)) {
+ return 1;
+ }
+ }
+ appFreeCssmData(&sig, CSSM_FALSE);
+
+ /* sign with CDSA, verify with BSAFE */
+ crtn = _cspSign(cspHand,
+ sigAlg,
+ cdsaPrivKey,
+ ptext,
+ rsaBlinding,
+ &sig);
+ if(crtn) {
+ return testError(quiet);
+ }
+ crtn = buVerify(bsafePubKey,
+ sigAlg,
+ ptext,
+ &sig);
+ if(crtn) {
+ printf("***ERROR: Sign with CDSA, vfy with BSAFE, alg %s\n",
+ algToStr(sigAlg));
+ if(testError(quiet)) {
+ return 1;
+ }
+ }
+ appFreeCssmData(&sig, CSSM_FALSE);
+ }
+ return CSSM_OK;
+}
+
+/*
+ * RSA Encrypt/decrypt test.
+ *
+ * for specified numLoops {
+ * generate random text;
+ * encrypt with BSAFE pub key, decrypt with CDSA priv key, verify;
+ * encrypt with CDSA pub key, decrypt with BSAFE priv key, verify;
+ * }
+ */
+static int encryptTest(
+ CSSM_CSP_HANDLE cspHand,
+ unsigned numLoops,
+
+ /* one matched key pair */
+ BU_KEY bsafePrivKey,
+ CSSM_KEY_PTR cdsaPubKey,
+
+ /* another matched key pair */
+ CSSM_KEY_PTR cdsaPrivKey,
+ BU_KEY bsafePubKey,
+
+ CSSM_DATA_PTR ptext,
+ unsigned maxPtextSize,
+ CSSM_BOOL rsaBlinding,
+ CSSM_BOOL quiet,
+ CSSM_BOOL verbose)
+{
+ CSSM_RETURN crtn;
+ CSSM_DATA ctext = {0, NULL};
+ CSSM_DATA rptext = {0, NULL};
+ unsigned loop;
+ unsigned actKeySizeBytes;
+
+ actKeySizeBytes = cdsaPrivKey->KeyHeader.LogicalKeySizeInBits / 8;
+ if(actKeySizeBytes < 12) {
+ printf("***Key with %u key bits is too small for RSA encrypt\n",
+ (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits);
+ return 1;
+ }
+ if(maxPtextSize > (actKeySizeBytes - 11)) {
+ maxPtextSize = actKeySizeBytes - 11;
+ }
+ if(!quiet) {
+ printf(" ...encr alg RSA\n");
+ }
+ for(loop=0; loop<numLoops; loop++) {
+ simpleGenData(ptext, 1, maxPtextSize);
+ if(!quiet) {
+ if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
+ printf(" ...loop %d keySize %u textSize %lu\n",
+ loop, (unsigned)cdsaPrivKey->KeyHeader.LogicalKeySizeInBits,
+ (unsigned long)ptext->Length);
+ }
+ }
+
+ /* encrypt with BSAFE, decrypt with CDSA */
+ crtn = buEncryptDecrypt(bsafePubKey,
+ CSSM_TRUE, // encrypt
+ CSSM_ALGID_RSA,
+ CSSM_ALGMODE_NONE,
+ NULL, // iv
+ cdsaPrivKey->KeyHeader.LogicalKeySizeInBits,
+ 0, // rounds
+ ptext,
+ &ctext);
+ if(crtn) {
+ return testError(quiet);
+ }
+ crtn = _cspDecrypt(cspHand,
+ CSSM_ALGID_RSA,
+ CSSM_ALGMODE_NONE,
+ CSSM_PADDING_PKCS1,
+ rsaBlinding,
+ cdsaPrivKey,
+ &ctext,
+ &rptext);
+ if(crtn) {
+ printf("***ERROR: encrypt with BSAFE, decrypt with CDSA\n");
+ return testError(quiet);
+ }
+ if(!appCompareCssmData(ptext, &rptext)) {
+ printf("***DATA MISCOMPARE: encrypt with BSAFE, decrypt with CDSA\n");
+ return testError(quiet);
+ }
+ appFreeCssmData(&ctext, CSSM_FALSE);
+ appFreeCssmData(&rptext, CSSM_FALSE);
+
+ /* encrypt with CDSA, decrypt with BSAFE */
+ crtn = cspEncrypt(cspHand,
+ CSSM_ALGID_RSA,
+ CSSM_ALGMODE_NONE,
+ CSSM_PADDING_PKCS1,
+ cdsaPubKey,
+ NULL, // (FEE) pub key
+ 0, // effectiveKeyBits
+ 0, // rounds
+ NULL, // IV
+ ptext,
+ &ctext,
+ CSSM_FALSE); // mallocCtext
+ if(crtn) {
+ return testError(quiet);
+ }
+ crtn = buEncryptDecrypt(bsafePrivKey,
+ CSSM_FALSE, // encrypt
+ CSSM_ALGID_RSA,
+ CSSM_ALGMODE_NONE,
+ NULL, // iv
+ cdsaPrivKey->KeyHeader.LogicalKeySizeInBits,
+ 0, // rounds
+ &ctext,
+ &rptext);
+ if(crtn) {
+ printf("***ERROR: encrypt with CDSA, decrypt with BSAFE\n");
+ return testError(quiet);
+ }
+ if(!appCompareCssmData(ptext, &rptext)) {
+ printf("***DATA MISCOMPARE: encrypt with CDSA, decrypt with BSAFE\n");
+ return testError(quiet);
+ }
+ appFreeCssmData(&ctext, CSSM_FALSE);
+ appFreeCssmData(&rptext, CSSM_FALSE);
+ }
+ return CSSM_OK;
+}
+
+static int doTest(
+ CSSM_CSP_HANDLE cspHand,
+ CSSM_ALGORITHMS keyAlg, // RSA/DSA
+ CSSM_ALGORITHMS sigAlg,
+ unsigned sigLoops, // may be zero
+ unsigned encrLoops, // ditto; it will be zero for DSA
+ CSSM_BOOL rsaBlinding,
+ CSSM_DATA_PTR ptext,
+ unsigned maxPtextSize,
+ uint32 keySizeInBits, // 0 --> random per alg
+ CSSM_BOOL pubRefKeys,
+ CSSM_BOOL privRefKeys,
+ CSSM_BOOL bareCsp, // for other workarounds
+ CSSM_BOOL quiet,
+ CSSM_BOOL verbose)
+{
+ CSSM_KEY cdsaGenPubKey;
+ CSSM_KEY cdsaGenPrivKey; // only used to create bsafeDerivePrivKey
+ CSSM_KEY cdsaTempKey; // raw key if privRefKeys true
+ CSSM_KEY cdsaDerivePrivKey; // same as bsafeGenPrivKey
+ BU_KEY bsafeGenPubKey;
+ BU_KEY bsafeGenPrivKey; // only used to create cdsaDerivePrivKey
+ BU_KEY bsafeDerivePrivKey; // same as cdsaGenPrivKey
+ unsigned actKeySizeBits;
+ CSSM_RETURN crtn;
+ int rtn;
+
+ if(!keySizeInBits) {
+ /* random key size */
+ actKeySizeBits = randKeySizeBits(keyAlg, OT_Encrypt);
+ }
+ else {
+ /* caller/user specified */
+ actKeySizeBits = keySizeInBits;
+ }
+ if(verbose) {
+ printf(" ...generating %s key pair, keySize %d bits...\n",
+ algToStr(keyAlg), actKeySizeBits);
+ }
+
+ /*
+ * Generate two keypairs
+ */
+ if(keyAlg == CSSM_ALGID_DSA) {
+ CSSM_BOOL doGenParams;
+
+ if(bareCsp || CSPDL_DSA_GEN_PARAMS) {
+ doGenParams = CSSM_TRUE;
+ }
+ else {
+ /* CSPDL - no gen params */
+ doGenParams = CSSM_FALSE;
+ }
+ crtn = cspGenDSAKeyPair(cspHand,
+ "foo",
+ 3,
+ actKeySizeBits,
+ &cdsaGenPubKey,
+ pubRefKeys,
+ CSSM_KEYUSE_ANY,
+ CSSM_KEYBLOB_RAW_FORMAT_NONE,
+ &cdsaGenPrivKey,
+ privRefKeys,
+ CSSM_KEYUSE_SIGN,
+ CSSM_KEYBLOB_RAW_FORMAT_NONE,
+ doGenParams, // genParams
+ NULL); // params
+ }
+ else {
+ crtn = cspGenKeyPair(cspHand,
+ keyAlg,
+ "foo",
+ 3,
+ actKeySizeBits,
+ &cdsaGenPubKey,
+ pubRefKeys,
+ CSSM_KEYUSE_ANY,
+ CSSM_KEYBLOB_RAW_FORMAT_NONE,
+ &cdsaGenPrivKey,
+ privRefKeys,
+ CSSM_KEYUSE_ANY,
+ CSSM_KEYBLOB_RAW_FORMAT_NONE,
+ CSSM_FALSE); // genSeed not used
+ }
+ if(crtn) {
+ return testError(quiet);
+ }
+ crtn = buGenKeyPair(actKeySizeBits,
+ keyAlg,
+ &bsafeGenPubKey,
+ &bsafeGenPrivKey);
+ if(crtn) {
+ return testError(quiet);
+ }
+
+ /*
+ * Convert private keys to other library.
+ * NOTE: the reason we're only converting private keys is solely due to the
+ * fact that BSAFE does not handle PKCS1 formatted public key blobs. Very odd.
+ * But it's too much of a pain to re-implement that wheel here, and SSL and
+ * cert handling in general verify the CSP's PKCS1-style public key handling.
+ */
+ if(privRefKeys) {
+ /* first generate a temporary raw CDSA key */
+ crtn = buBsafePrivKeyToCdsa(keyAlg,
+ actKeySizeBits,
+ bsafeGenPrivKey,
+ &cdsaTempKey);
+ if(crtn) {
+ return testError(quiet);
+ }
+
+ /* convert it to the ref key we'll actually use */
+ crtn = cspRawKeyToRef(cspHand, &cdsaTempKey, &cdsaDerivePrivKey);
+ cspFreeKey(cspHand, &cdsaTempKey);
+ }
+ else {
+ crtn = buBsafePrivKeyToCdsa(keyAlg,
+ actKeySizeBits,
+ bsafeGenPrivKey,
+ &cdsaDerivePrivKey);
+ }
+ if(crtn) {
+ return testError(quiet);
+ }
+ if(privRefKeys) {
+ /* we have a CDSA priv ref key; convert it to raw format */
+ crtn = cspRefKeyToRaw(cspHand, &cdsaGenPrivKey, &cdsaTempKey);
+ if(crtn) {
+ return testError(quiet);
+ }
+ /* now convert it to BSAFE */
+ crtn = buCdsaPrivKeyToBsafe(&cdsaTempKey, &bsafeDerivePrivKey);
+ cspFreeKey(cspHand, &cdsaTempKey);
+ }
+ else {
+ crtn = buCdsaPrivKeyToBsafe(&cdsaGenPrivKey, &bsafeDerivePrivKey);
+ }
+ if(crtn) {
+ return testError(quiet);
+ }
+
+ if(sigLoops) {
+ rtn = sigTest(cspHand,
+ sigLoops,
+ bsafeDerivePrivKey,
+ &cdsaGenPubKey,
+ &cdsaDerivePrivKey,
+ bsafeGenPubKey,
+ ptext,
+ maxPtextSize,
+ sigAlg,
+ rsaBlinding,
+ quiet,
+ verbose);
+ if(rtn) {
+ return rtn;
+ }
+ }
+
+ if(encrLoops) {
+ rtn = encryptTest(cspHand,
+ encrLoops,
+ bsafeDerivePrivKey,
+ &cdsaGenPubKey,
+ &cdsaDerivePrivKey,
+ bsafeGenPubKey,
+ ptext,
+ maxPtextSize,
+ rsaBlinding,
+ quiet,
+ verbose);
+ if(rtn) {
+ return rtn;
+ }
+ }
+
+ /* free all six keys */
+ buFreeKey(bsafeGenPubKey);
+ buFreeKey(bsafeGenPrivKey);
+ buFreeKey(bsafeDerivePrivKey);
+ cspFreeKey(cspHand, &cdsaGenPubKey);
+ cspFreeKey(cspHand, &cdsaGenPrivKey);
+ cspFreeKey(cspHand, &cdsaDerivePrivKey);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int arg;
+ char *argp;
+ unsigned loop;
+ CSSM_DATA ptext;
+ CSSM_CSP_HANDLE cspHand;
+ int i;
+ int rtn = 0;
+
+ /*
+ * User-spec'd params
+ */
+ uint32 keySizeInBits = 0;
+ unsigned oloops = OLOOPS_DEF;
+ unsigned sigLoops = SIG_LOOPS_DEF;
+ unsigned encrLoops = ENC_LOOPS_DEF;
+ CSSM_BOOL verbose = CSSM_FALSE;
+ CSSM_BOOL quiet = CSSM_FALSE;
+ unsigned pauseInterval = 0;
+ CSSM_BOOL bareCsp = CSSM_TRUE;
+ CSSM_BOOL doDSA = CSSM_TRUE;
+ CSSM_BOOL doRSA = CSSM_TRUE;
+ CSSM_BOOL pubRefKeys = CSSM_FALSE;
+ CSSM_BOOL privRefKeys = CSSM_FALSE;
+
+ for(arg=1; arg<argc; arg++) {
+ argp = argv[arg];
+ switch(argp[0]) {
+ case 'a':
+ if(argp[1] != '=') {
+ usage(argv);
+ }
+ switch(argp[2]) {
+ case 'r':
+ doDSA = CSSM_FALSE;
+ break;
+ case 'd':
+ doRSA = CSSM_FALSE;
+ break;
+ default:
+ usage(argv);
+ }
+ break;
+ case 'l':
+ oloops = atoi(&argp[2]);
+ break;
+ case 's':
+ sigLoops = atoi(&argp[2]);
+ break;
+ case 'e':
+ encrLoops = atoi(&argp[2]);
+ break;
+ case 'k':
+ keySizeInBits = atoi(&argp[2]);
+ break;
+ case 'v':
+ verbose = CSSM_TRUE;
+ break;
+ case 'r':
+ privRefKeys = CSSM_TRUE;
+ break;
+ case 'R':
+ pubRefKeys = CSSM_TRUE;
+ break;
+ case 'D':
+ bareCsp = CSSM_FALSE;
+ #if CSPDL_ALL_KEYS_ARE_REF
+ privRefKeys = CSSM_TRUE;
+ pubRefKeys = CSSM_TRUE;
+ #endif
+ break;
+ case 'E':
+ sigLoops = 0;
+ break;
+ case 'S':
+ encrLoops = 0;
+ break;
+ case 'q':
+ quiet = CSSM_TRUE;
+ break;
+ case 'p':
+ pauseInterval = atoi(&argp[2]);;
+ break;
+ case 'h':
+ default:
+ usage(argv);
+ }
+ }
+ ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE);
+ if(ptext.Data == NULL) {
+ printf("Insufficient heap space\n");
+ exit(1);
+ }
+ /* ptext length set in inner test loops */
+
+ printf("Starting asymCompat; 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(loop=1; ; loop++) {
+ if(!quiet) {
+ if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
+ printf("...oloop %d\n", loop);
+ }
+ }
+
+ if(doRSA) {
+ CSSM_ALGORITHMS sigAlg;
+ if(loop & 1) {
+ sigAlg = CSSM_ALGID_SHA1WithRSA;
+ }
+ else {
+ sigAlg = CSSM_ALGID_MD5WithRSA;
+ }
+
+ /* enable RSA blinding on half the loops for RSA */
+ CSSM_BOOL rsaBlinding = CSSM_FALSE;
+ if(loop & 2) {
+ rsaBlinding = CSSM_TRUE;
+ }
+
+ rtn = doTest(cspHand,
+ CSSM_ALGID_RSA,
+ sigAlg,
+ sigLoops,
+ encrLoops,
+ rsaBlinding,
+ &ptext,
+ MAX_TEXT_SIZE,
+ keySizeInBits,
+ pubRefKeys,
+ privRefKeys,
+ bareCsp,
+ quiet,
+ verbose);
+ if(rtn) {
+ break;
+ }
+ }
+ if(doDSA) {
+ rtn = doTest(cspHand,
+ CSSM_ALGID_DSA,
+ CSSM_ALGID_SHA1WithDSA,
+ sigLoops,
+ 0, // encrLoops - none for DSA
+ CSSM_FALSE, // blinding
+ &ptext,
+ MAX_TEXT_SIZE,
+ keySizeInBits,
+ pubRefKeys,
+ privRefKeys,
+ bareCsp,
+ quiet,
+ verbose);
+ if(rtn) {
+ break;
+ }
+ }
+ if(oloops && (loop == oloops)) {
+ break;
+ }
+ if(pauseInterval && (loop % pauseInterval) == 0) {
+ fpurge(stdin);
+ printf("hit CR to proceed: ");
+ getchar();
+ }
+ }
+
+ cspShutdown(cspHand, bareCsp);
+ if(pauseInterval) {
+ fpurge(stdin);
+ printf("ModuleDetach/Unload complete; hit CR to exit: ");
+ getchar();
+ }
+ if((rtn == 0) && !quiet) {
+ printf("%s test complete\n", argv[0]);
+ }
+ CSSM_FREE(ptext.Data);
+ return rtn;
+}
+
+