--- /dev/null
+/* Copyright (c) 2006,2008 Apple Inc.
+ *
+ * ccSymTest.c - test CommonCrypto symmetric encrypt/decrypt.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <CommonCrypto/CommonCryptor.h>
+#include "common.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+/*
+ * Defaults.
+ */
+#define LOOPS_DEF 500
+#define MIN_DATA_SIZE 8
+#define MAX_DATA_SIZE 10000 /* bytes */
+#define MAX_KEY_SIZE kCCKeySizeMaxRC4 /* bytes */
+#define MAX_BLOCK_SIZE kCCBlockSizeAES128 /* bytes */
+#define LOOP_NOTIFY 250
+
+/*
+ * Enumerate algs our own way to allow iteration.
+ */
+typedef enum {
+ ALG_AES_128 = 1, /* 128 bit block, 128 bit key */
+ ALG_AES_192, /* 128 bit block, 192 bit key */
+ ALG_AES_256, /* 128 bit block, 256 bit key */
+ ALG_DES,
+ ALG_3DES,
+ ALG_CAST,
+ ALG_RC4,
+ /* these aren't in CommonCrypto (yet?) */
+ ALG_RC2,
+ ALG_RC5,
+ ALG_BFISH,
+ ALG_ASC,
+ ALG_NULL /* normally not used */
+} SymAlg;
+#define ALG_FIRST ALG_AES_128
+#define ALG_LAST ALG_RC4
+
+
+#define LOG_SIZE 0
+#if LOG_SIZE
+#define logSize(s) printf s
+#else
+#define logSize(s)
+#endif
+
+static void usage(char **argv)
+{
+ printf("usage: %s [options]\n", argv[0]);
+ printf(" Options:\n");
+ printf(" a=algorithm (d=DES; 3=3DES; a=AES128; n=AES192; A=AES256; \n");
+ printf(" c=CAST; 4=RC4; default=all)\n");
+ printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
+ printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE);
+ printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE);
+ printf(" k=keySizeInBytes\n");
+ printf(" p=pauseInterval (default=0, no pause)\n");
+ printf(" o (no padding, well-aligned plaintext)\n");
+ printf(" e (ECB only)\n");
+ printf(" E (CBC only, no ECB)\n");
+ printf(" u (no multi-update ops)\n");
+ printf(" U (only multi-update ops)\n");
+ printf(" x (always allocate context)\n");
+ printf(" X (never allocate context)\n");
+ printf(" v(erbose)\n");
+ printf(" q(uiet)\n");
+ printf(" h(elp)\n");
+ exit(1);
+}
+
+static void printCCError(const char *str, CCCryptorStatus crtn)
+{
+ const char *errStr;
+ char unknownStr[200];
+
+ switch(crtn) {
+ case kCCSuccess: errStr = "kCCSuccess"; break;
+ case kCCParamError: errStr = "kCCParamError"; break;
+ case kCCBufferTooSmall: errStr = "kCCBufferTooSmall"; break;
+ case kCCMemoryFailure: errStr = "kCCMemoryFailure"; break;
+ case kCCAlignmentError: errStr = "kCCAlignmentError"; break;
+ case kCCDecodeError: errStr = "kCCDecodeError"; break;
+ case kCCUnimplemented: errStr = "kCCUnimplemented"; break;
+ default:
+ sprintf(unknownStr, "Unknown(%ld)\n", (long)crtn);
+ errStr = unknownStr;
+ break;
+ }
+ printf("***%s returned %s\n", str, errStr);
+}
+
+/* max context size */
+#define CC_MAX_CTX_SIZE kCCContextSizeRC4
+
+/*
+ * We write a marker at end of expected output and at end of caller-allocated
+ * CCCryptorRef, and check at the end to make sure they weren't written
+ */
+#define MARKER_LENGTH 8
+#define MARKER_BYTE 0x7e
+
+/*
+ * Test harness for CCCryptor with lots of options.
+ */
+CCCryptorStatus doCCCrypt(
+ bool forEncrypt,
+ CCAlgorithm encrAlg,
+ bool doCbc,
+ bool doPadding,
+ const void *keyBytes, size_t keyLen,
+ const void *iv,
+ bool randUpdates,
+ bool inPlace, /* !doPadding only */
+ size_t ctxSize, /* if nonzero, we allocate ctx */
+ bool askOutSize,
+ const uint8_t *inText, size_t inTextLen,
+ uint8_t **outText, size_t *outTextLen) /* both returned, WE malloc */
+{
+ CCCryptorRef cryptor = NULL;
+ CCCryptorStatus crtn;
+ CCOperation op = forEncrypt ? kCCEncrypt : kCCDecrypt;
+ CCOptions options = 0;
+ uint8_t *outBuf = NULL; /* mallocd output buffer */
+ uint8_t *outp; /* running ptr into outBuf */
+ const uint8 *inp; /* running ptr into inText */
+ size_t outLen; /* bytes remaining in outBuf */
+ size_t toMove; /* bytes remaining in inText */
+ size_t thisMoveOut; /* output from CCCryptUpdate()/CCCryptFinal() */
+ size_t outBytes; /* total bytes actually produced in outBuf */
+ char ctx[CC_MAX_CTX_SIZE]; /* for CCCryptorCreateFromData() */
+ uint8_t *textMarker = NULL; /* 8 bytes of marker here after expected end of
+ * output */
+ char *ctxMarker = NULL; /* ditto for caller-provided context */
+ unsigned dex;
+ size_t askedOutSize; /* from the lib */
+ size_t thisOutLen; /* dataOutAvailable we use */
+
+ if(ctxSize > CC_MAX_CTX_SIZE) {
+ printf("***HEY! Adjust CC_MAX_CTX_SIZE!\n");
+ exit(1);
+ }
+ if(!doCbc) {
+ options |= kCCOptionECBMode;
+ }
+ if(doPadding) {
+ options |= kCCOptionPKCS7Padding;
+ }
+
+ /* just hack this one */
+ outLen = inTextLen;
+ if(forEncrypt) {
+ outLen += MAX_BLOCK_SIZE;
+ }
+
+ outBuf = (uint8_t *)malloc(outLen + MARKER_LENGTH);
+
+ /* library should not touch this memory */
+ textMarker = outBuf + outLen;
+ memset(textMarker, MARKER_BYTE, MARKER_LENGTH);
+
+ /* subsequent errors to errOut: */
+
+ if(inPlace) {
+ memmove(outBuf, inText, inTextLen);
+ inp = outBuf;
+ }
+ else {
+ inp = inText;
+ }
+
+ if(!randUpdates) {
+ /* one shot */
+ if(askOutSize) {
+ crtn = CCCrypt(op, encrAlg, options,
+ keyBytes, keyLen, iv,
+ inp, inTextLen,
+ outBuf, 0, &askedOutSize);
+ if(crtn != kCCBufferTooSmall) {
+ printf("***Did not get kCCBufferTooSmall as expected\n");
+ printf(" alg %d inTextLen %lu cbc %d padding %d keyLen %lu\n",
+ (int)encrAlg, (unsigned long)inTextLen, (int)doCbc, (int)doPadding,
+ (unsigned long)keyLen);
+ printCCError("CCCrypt", crtn);
+ crtn = -1;
+ goto errOut;
+ }
+ outLen = askedOutSize;
+ }
+ crtn = CCCrypt(op, encrAlg, options,
+ keyBytes, keyLen, iv,
+ inp, inTextLen,
+ outBuf, outLen, &outLen);
+ if(crtn) {
+ printCCError("CCCrypt", crtn);
+ goto errOut;
+ }
+ *outText = outBuf;
+ *outTextLen = outLen;
+ goto errOut;
+ }
+
+ /* random multi updates */
+ if(ctxSize) {
+ size_t ctxSizeCreated;
+
+ if(askOutSize) {
+ crtn = CCCryptorCreateFromData(op, encrAlg, options,
+ keyBytes, keyLen, iv,
+ ctx, 0 /* ctxSize */,
+ &cryptor, &askedOutSize);
+ if(crtn != kCCBufferTooSmall) {
+ printf("***Did not get kCCBufferTooSmall as expected\n");
+ printCCError("CCCryptorCreateFromData", crtn);
+ crtn = -1;
+ goto errOut;
+ }
+ ctxSize = askedOutSize;
+ }
+ crtn = CCCryptorCreateFromData(op, encrAlg, options,
+ keyBytes, keyLen, iv,
+ ctx, ctxSize, &cryptor, &ctxSizeCreated);
+ if(crtn) {
+ printCCError("CCCryptorCreateFromData", crtn);
+ return crtn;
+ }
+ ctxMarker = ctx + ctxSizeCreated;
+ memset(ctxMarker, MARKER_BYTE, MARKER_LENGTH);
+ }
+ else {
+ crtn = CCCryptorCreate(op, encrAlg, options,
+ keyBytes, keyLen, iv,
+ &cryptor);
+ if(crtn) {
+ printCCError("CCCryptorCreate", crtn);
+ return crtn;
+ }
+ }
+
+ toMove = inTextLen; /* total to go */
+ outp = outBuf;
+ outBytes = 0; /* bytes actually produced in outBuf */
+
+ while(toMove) {
+ uint32 thisMoveIn; /* input to CCryptUpdate() */
+
+ thisMoveIn = genRand(1, toMove);
+ logSize(("###ptext segment len %lu\n", (unsigned long)thisMoveIn));
+ if(askOutSize) {
+ thisOutLen = CCCryptorGetOutputLength(cryptor, thisMoveIn, false);
+ }
+ else {
+ thisOutLen = outLen;
+ }
+ crtn = CCCryptorUpdate(cryptor, inp, thisMoveIn,
+ outp, thisOutLen, &thisMoveOut);
+ if(crtn) {
+ printCCError("CCCryptorUpdate", crtn);
+ goto errOut;
+ }
+ inp += thisMoveIn;
+ toMove -= thisMoveIn;
+ outp += thisMoveOut;
+ outLen -= thisMoveOut;
+ outBytes += thisMoveOut;
+ }
+
+ if(doPadding) {
+ /* Final is not needed if padding is disabled */
+ if(askOutSize) {
+ thisOutLen = CCCryptorGetOutputLength(cryptor, 0, true);
+ }
+ else {
+ thisOutLen = outLen;
+ }
+ crtn = CCCryptorFinal(cryptor, outp, thisOutLen, &thisMoveOut);
+ }
+ else {
+ thisMoveOut = 0;
+ crtn = kCCSuccess;
+ }
+
+ if(crtn) {
+ printCCError("CCCryptorFinal", crtn);
+ goto errOut;
+ }
+
+ outBytes += thisMoveOut;
+ *outText = outBuf;
+ *outTextLen = outBytes;
+ crtn = kCCSuccess;
+
+ for(dex=0; dex<MARKER_LENGTH; dex++) {
+ if(textMarker[dex] != MARKER_BYTE) {
+ printf("***lib scribbled on our textMarker memory (op=%s)!\n",
+ forEncrypt ? "encrypt" : "decrypt");
+ crtn = (CCCryptorStatus)-1;
+ }
+ }
+ if(ctxSize) {
+ for(dex=0; dex<MARKER_LENGTH; dex++) {
+ if(ctxMarker[dex] != MARKER_BYTE) {
+ printf("***lib scribbled on our ctxMarker memory (op=%s)!\n",
+ forEncrypt ? "encrypt" : "decrypt");
+ crtn = (CCCryptorStatus)-1;
+ }
+ }
+ }
+
+errOut:
+ if(crtn) {
+ if(outBuf) {
+ free(outBuf);
+ }
+ }
+ if(cryptor) {
+ CCCryptorRelease(cryptor);
+ }
+ return crtn;
+}
+
+static int doTest(const uint8_t *ptext,
+ size_t ptextLen,
+ CCAlgorithm encrAlg,
+ bool doCbc,
+ bool doPadding,
+ bool nullIV, /* if CBC, use NULL IV */
+ uint32 keySizeInBytes,
+ bool stagedEncr,
+ bool stagedDecr,
+ bool inPlace,
+ size_t ctxSize,
+ bool askOutSize,
+ bool quiet)
+{
+ uint8_t keyBytes[MAX_KEY_SIZE];
+ uint8_t iv[MAX_BLOCK_SIZE];
+ uint8_t *ivPtrEncrypt;
+ uint8_t *ivPtrDecrypt;
+ uint8_t *ctext = NULL; /* mallocd by doCCCrypt */
+ size_t ctextLen = 0;
+ uint8_t *rptext = NULL; /* mallocd by doCCCrypt */
+ size_t rptextLen;
+ CCCryptorStatus crtn;
+ int rtn = 0;
+
+ /* random key */
+ appGetRandomBytes(keyBytes, keySizeInBytes);
+
+ /* random IV if needed */
+ if(doCbc) {
+ if(nullIV) {
+ memset(iv, 0, MAX_BLOCK_SIZE);
+
+ /* flip a coin, give one side NULL, the other size zeroes */
+ if(genRand(1,2) == 1) {
+ ivPtrEncrypt = NULL;
+ ivPtrDecrypt = iv;
+ }
+ else {
+ ivPtrEncrypt = iv;
+ ivPtrDecrypt = NULL;
+ }
+ }
+ else {
+ appGetRandomBytes(iv, MAX_BLOCK_SIZE);
+ ivPtrEncrypt = iv;
+ ivPtrDecrypt = iv;
+ }
+ }
+ else {
+ ivPtrEncrypt = NULL;
+ ivPtrDecrypt = NULL;
+ }
+
+ crtn = doCCCrypt(true, encrAlg, doCbc, doPadding,
+ keyBytes, keySizeInBytes, ivPtrEncrypt,
+ stagedEncr, inPlace, ctxSize, askOutSize,
+ ptext, ptextLen,
+ &ctext, &ctextLen);
+ if(crtn) {
+ rtn = testError(quiet);
+ if(rtn) {
+ goto abort;
+ }
+ }
+
+ logSize(("###ctext len %lu\n", ctextLen));
+
+ crtn = doCCCrypt(false, encrAlg, doCbc, doPadding,
+ keyBytes, keySizeInBytes, ivPtrDecrypt,
+ stagedDecr, inPlace, ctxSize, askOutSize,
+ ctext, ctextLen,
+ &rptext, &rptextLen);
+ if(crtn) {
+ rtn = testError(quiet);
+ if(rtn) {
+ goto abort;
+ }
+ }
+
+ logSize(("###rptext len %lu\n", rptextLen));
+
+ /* compare ptext, rptext */
+ if(ptextLen != rptextLen) {
+ printf("Ptext length mismatch: expect %lu, got %lu\n", ptextLen, rptextLen);
+ rtn = testError(quiet);
+ if(rtn) {
+ goto abort;
+ }
+ }
+ if(memcmp(ptext, rptext, ptextLen)) {
+ printf("***data miscompare\n");
+ rtn = testError(quiet);
+ }
+abort:
+ if(ctext) {
+ free(ctext);
+ }
+ if(rptext) {
+ free(rptext);
+ }
+ return rtn;
+}
+
+bool isBitSet(unsigned bit, unsigned word)
+{
+ if(bit > 31) {
+ printf("We don't have that many bits\n");
+ exit(1);
+ }
+ unsigned mask = 1 << bit;
+ return (word & mask) ? true : false;
+}
+
+int main(int argc, char **argv)
+{
+ int arg;
+ char *argp;
+ unsigned loop;
+ uint8 *ptext;
+ size_t ptextLen;
+ bool stagedEncr;
+ bool stagedDecr;
+ bool doPadding;
+ bool doCbc;
+ bool nullIV;
+ const char *algStr;
+ CCAlgorithm encrAlg;
+ int i;
+ int currAlg; // ALG_xxx
+ uint32 minKeySizeInBytes;
+ uint32 maxKeySizeInBytes;
+ uint32 keySizeInBytes;
+ int rtn = 0;
+ uint32 blockSize; // for noPadding case
+ size_t ctxSize; // always set per alg
+ size_t ctxSizeUsed; // passed to doTest
+ bool askOutSize; // inquire output size each op
+
+ /*
+ * User-spec'd params
+ */
+ bool keySizeSpec = false; // false: use rand key size
+ SymAlg minAlg = ALG_FIRST;
+ SymAlg maxAlg = ALG_LAST;
+ unsigned loops = LOOPS_DEF;
+ bool verbose = false;
+ size_t minPtextSize = MIN_DATA_SIZE;
+ size_t maxPtextSize = MAX_DATA_SIZE;
+ bool quiet = false;
+ unsigned pauseInterval = 0;
+ bool paddingSpec = false; // true: user calls doPadding, const
+ bool cbcSpec = false; // ditto for doCbc
+ bool stagedSpec = false; // ditto for stagedEncr and stagedDecr
+ bool inPlace = false; // en/decrypt in place for ECB
+ bool allocCtxSpec = false; // use allocCtx
+ bool allocCtx = false; // allocate context ourself
+
+ 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_ASC;
+ break;
+ case 'd':
+ minAlg = maxAlg = ALG_DES;
+ break;
+ case '3':
+ minAlg = maxAlg = ALG_3DES;
+ break;
+ case '2':
+ minAlg = maxAlg = ALG_RC2;
+ break;
+ case '4':
+ minAlg = maxAlg = ALG_RC4;
+ break;
+ case '5':
+ minAlg = maxAlg = ALG_RC5;
+ break;
+ case 'a':
+ minAlg = maxAlg = ALG_AES_128;
+ break;
+ case 'n':
+ minAlg = maxAlg = ALG_AES_192;
+ break;
+ case 'A':
+ minAlg = maxAlg = ALG_AES_256;
+ break;
+ case 'b':
+ minAlg = maxAlg = ALG_BFISH;
+ break;
+ case 'c':
+ minAlg = maxAlg = ALG_CAST;
+ break;
+ default:
+ usage(argv);
+ }
+ if(maxAlg > ALG_LAST) {
+ /* we left them in the switch but we can't use them */
+ usage(argv);
+ }
+ break;
+ case 'l':
+ loops = atoi(&argp[2]);
+ break;
+ case 'n':
+ minPtextSize = atoi(&argp[2]);
+ break;
+ case 'm':
+ maxPtextSize = atoi(&argp[2]);
+ break;
+ case 'k':
+ minKeySizeInBytes = maxKeySizeInBytes = atoi(&argp[2]);
+ keySizeSpec = true;
+ break;
+ case 'x':
+ allocCtxSpec = true;
+ allocCtx = true;
+ break;
+ case 'X':
+ allocCtxSpec = true;
+ allocCtx = false;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case 'q':
+ quiet = true;
+ break;
+ case 'p':
+ pauseInterval = atoi(&argp[2]);;
+ break;
+ case 'o':
+ doPadding = false;
+ paddingSpec = true;
+ break;
+ case 'e':
+ doCbc = false;
+ cbcSpec = true;
+ break;
+ case 'E':
+ doCbc = true;
+ cbcSpec = true;
+ break;
+ case 'u':
+ stagedEncr = false;
+ stagedDecr = false;
+ stagedSpec = true;
+ break;
+ case 'U':
+ stagedEncr = true;
+ stagedDecr = true;
+ stagedSpec = true;
+ break;
+ case 'h':
+ default:
+ usage(argv);
+ }
+ }
+ ptext = (uint8 *)malloc(maxPtextSize);
+ if(ptext == NULL) {
+ printf("Insufficient heap space\n");
+ exit(1);
+ }
+ /* ptext length set in test loop */
+
+ printf("Starting ccSymTest; args: ");
+ for(i=1; i<argc; i++) {
+ printf("%s ", argv[i]);
+ }
+ printf("\n");
+
+ if(pauseInterval) {
+ fpurge(stdin);
+ printf("Top of test; hit CR to proceed: ");
+ getchar();
+ }
+
+ for(currAlg=minAlg; currAlg<=maxAlg; currAlg++) {
+ switch(currAlg) {
+ case ALG_DES:
+ encrAlg = kCCAlgorithmDES;
+ blockSize = kCCBlockSizeDES;
+ minKeySizeInBytes = kCCKeySizeDES;
+ maxKeySizeInBytes = minKeySizeInBytes;
+ ctxSize = kCCContextSizeDES;
+ algStr = "DES";
+ break;
+ case ALG_3DES:
+ encrAlg = kCCAlgorithm3DES;
+ blockSize = kCCBlockSize3DES;
+ minKeySizeInBytes = kCCKeySize3DES;
+ maxKeySizeInBytes = minKeySizeInBytes;
+ ctxSize = kCCContextSize3DES;
+ algStr = "3DES";
+ break;
+ case ALG_AES_128:
+ encrAlg = kCCAlgorithmAES128;
+ blockSize = kCCBlockSizeAES128;
+ minKeySizeInBytes = kCCKeySizeAES128;
+ maxKeySizeInBytes = minKeySizeInBytes;
+ ctxSize = kCCContextSizeAES128;
+ algStr = "AES128";
+ break;
+ case ALG_AES_192:
+ encrAlg = kCCAlgorithmAES128;
+ blockSize = kCCBlockSizeAES128;
+ minKeySizeInBytes = kCCKeySizeAES192;
+ maxKeySizeInBytes = minKeySizeInBytes;
+ ctxSize = kCCContextSizeAES128;
+ algStr = "AES192";
+ break;
+ case ALG_AES_256:
+ encrAlg = kCCAlgorithmAES128;
+ blockSize = kCCBlockSizeAES128;
+ minKeySizeInBytes = kCCKeySizeAES256;
+ maxKeySizeInBytes = minKeySizeInBytes;
+ ctxSize = kCCContextSizeAES128;
+ algStr = "AES256";
+ break;
+ case ALG_CAST:
+ encrAlg = kCCAlgorithmCAST;
+ blockSize = kCCBlockSizeCAST;
+ minKeySizeInBytes = kCCKeySizeMinCAST;
+ maxKeySizeInBytes = kCCKeySizeMaxCAST;
+ ctxSize = kCCContextSizeCAST;
+ algStr = "CAST";
+ break;
+ case ALG_RC4:
+ encrAlg = kCCAlgorithmRC4;
+ blockSize = 0;
+ minKeySizeInBytes = kCCKeySizeMinRC4;
+ maxKeySizeInBytes = kCCKeySizeMaxRC4;
+ ctxSize = kCCContextSizeRC4;
+ algStr = "RC4";
+ break;
+ default:
+ printf("***BRRZAP!\n");
+ exit(1);
+ }
+ if(!quiet || verbose) {
+ printf("Testing alg %s\n", algStr);
+ }
+ for(loop=1; ; loop++) {
+ ptextLen = genRand(minPtextSize, maxPtextSize);
+ appGetRandomBytes(ptext, ptextLen);
+
+ /* per-loop settings */
+ if(!keySizeSpec) {
+ if(minKeySizeInBytes == maxKeySizeInBytes) {
+ keySizeInBytes = minKeySizeInBytes;
+ }
+ else {
+ keySizeInBytes = genRand(minKeySizeInBytes, maxKeySizeInBytes);
+ }
+ }
+ if(blockSize == 0) {
+ /* stream cipher */
+ doCbc = false;
+ doPadding = false;
+ }
+ else {
+ if(!cbcSpec) {
+ doCbc = isBitSet(0, loop);
+ }
+ if(!paddingSpec) {
+ doPadding = isBitSet(1, loop);
+ }
+ }
+ if(!doPadding && (blockSize != 0)) {
+ /* align plaintext */
+ ptextLen = (ptextLen / blockSize) * blockSize;
+ if(ptextLen == 0) {
+ ptextLen = blockSize;
+ }
+ }
+ if(!stagedSpec) {
+ stagedEncr = isBitSet(2, loop);
+ stagedDecr = isBitSet(3, loop);
+ }
+ if(doCbc) {
+ nullIV = isBitSet(4, loop);
+ }
+ else {
+ nullIV = false;
+ }
+ inPlace = isBitSet(5, loop);
+ if(allocCtxSpec) {
+ ctxSizeUsed = allocCtx ? ctxSize : 0;
+ }
+ else if(isBitSet(6, loop)) {
+ ctxSizeUsed = ctxSize;
+ }
+ else {
+ ctxSizeUsed = 0;
+ }
+ askOutSize = isBitSet(7, loop);
+ if(!quiet) {
+ if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
+ printf("..loop %3d ptextLen %lu keyLen %d cbc=%d padding=%d stagedEncr=%d "
+ "stagedDecr=%d\n",
+ loop, (unsigned long)ptextLen, (int)keySizeInBytes,
+ (int)doCbc, (int)doPadding,
+ (int)stagedEncr, (int)stagedDecr);
+ printf(" nullIV %d inPlace %d ctxSize %d askOutSize %d\n",
+ (int)nullIV, (int)inPlace, (int)ctxSizeUsed, (int)askOutSize);
+ }
+ }
+
+ if(doTest(ptext, ptextLen,
+ encrAlg, doCbc, doPadding, nullIV,
+ keySizeInBytes,
+ stagedEncr, stagedDecr, inPlace, ctxSizeUsed, askOutSize,
+ 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:
+ if(pauseInterval) {
+ fpurge(stdin);
+ printf("ModuleDetach/Unload complete; hit CR to exit: ");
+ getchar();
+ }
+ if((rtn == 0) && !quiet) {
+ printf("%s test complete\n", argv[0]);
+ }
+ free(ptext);
+ return rtn;
+}