#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 "ssleayUtils.h"
#include "rijndaelApi.h"
#include <string.h>
#include "cspdlTesting.h"
#define LOOPS_DEF 200
#define MIN_DATA_SIZE 8
#define MAX_DATA_SIZE 10000
#define MAX_KEY_SIZE MAX_KEY_SIZE_RC245_BYTES
#define LOOP_NOTIFY 20
#define RAW_MODE CSSM_ALGMODE_ECB
#define RAW_MODE_BSAFE CSSM_ALGMODE_CBC_IV8
#define COOKED_MODE CSSM_ALGMODE_CBCPadIV8
#define RAW_MODE_STREAM CSSM_ALGMODE_NONE
#define RAW_MODE_STR "ECB"
#define RAW_MODE_BSAFE_STR "CBC/noPad"
#define COOKED_MODE_STR "CBC/Pad"
#define RAW_MODE_STREAM_STR "None"
typedef enum {
ALG_DES = 1,
ALG_RC2,
ALG_RC4,
ALG_RC5,
ALG_3DES,
ALG_AES,
ALG_AES192,
ALG_AES256,
ALG_BFISH,
ALG_CAST
} SymAlg;
#define ALG_FIRST ALG_DES
#define ALG_LAST ALG_CAST
static void usage(char **argv)
{
printf("usage: %s [options]\n", argv[0]);
printf(" Options:\n");
printf(" a=algorithm (d=DES; 3=3DES3; 2=RC2; 4=RC4; 5=RC5; a=AES; A=AES192; \n");
printf(" 6=AES256; b=Blowfish; c=CAST; default=all)\n");
printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
printf(" k=keySizeInBits\n");
printf(" e(ncrypt only)\n");
printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE);
printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE);
printf(" p=pauseInterval (default=0, no pause)\n");
printf(" s (all ops single-shot, not staged)\n");
printf(" o (raw - no padding or CBC if possible)\n");
printf(" O (cooked - padding and CBC if possible)\n");
printf(" z (keys and plaintext all zeroes)\n");
printf(" D (CSP/DL; default = bare CSP)\n");
printf(" y (use ssleay EVP; AES128 only)\n");
printf(" v(erbose)\n");
printf(" q(uiet)\n");
printf(" h(elp)\n");
exit(1);
}
static CSSM_RETURN encryptDecryptBSAFE(
CSSM_BOOL forEncrypt,
CSSM_ALGORITHMS encrAlg,
CSSM_ENCRYPT_MODE encrMode,
const CSSM_DATA *iv, uint32 keySizeInBits,
uint32 effectiveKeyBits, uint32 rounds, const CSSM_DATA *key, const CSSM_DATA *inText,
CSSM_DATA_PTR outText) {
CSSM_RETURN crtn;
BU_KEY buKey;
crtn = buGenSymKey(keySizeInBits, key, &buKey);
if(crtn) {
return crtn;
}
crtn = buEncryptDecrypt(buKey,
forEncrypt, encrAlg,
encrMode,
iv,
effectiveKeyBits,
rounds,
inText,
outText);
buFreeKey(buKey);
return crtn;
}
static CSSM_RETURN encryptDecryptEAY(
CSSM_BOOL forEncrypt,
CSSM_ALGORITHMS encrAlg,
CSSM_ENCRYPT_MODE encrMode,
const CSSM_DATA *iv, uint32 keySizeInBits,
const CSSM_DATA *key, const CSSM_DATA *inText,
CSSM_DATA_PTR outText) {
CSSM_RETURN crtn;
EAY_KEY eayKey;
CSSM_DATA ckey = *key;
ckey.Length = keySizeInBits / 8;
crtn = eayGenSymKey(encrAlg, forEncrypt, &ckey, &eayKey);
if(crtn) {
return crtn;
}
crtn = eayEncryptDecrypt(eayKey,
forEncrypt,
encrAlg,
encrMode,
iv,
inText,
outText);
eayFreeKey(eayKey);
return crtn;
}
static CSSM_RETURN encryptDecryptAES(
CSSM_BOOL forEncrypt,
CSSM_ALGORITHMS encrAlg,
CSSM_ENCRYPT_MODE encrMode,
const CSSM_DATA *iv, uint32 keySizeInBits,
uint32 effectiveKeyBits, uint32 cipherBlockSize,
uint32 rounds, const CSSM_DATA *key, const CSSM_DATA *inText,
CSSM_DATA_PTR outText) {
keyInstance aesKey;
cipherInstance aesCipher;
BYTE mode;
int artn;
BYTE *ivPtr;
if(cipherBlockSize == 0) {
cipherBlockSize = MIN_AES_BLOCK_BITS;
}
switch(encrMode) {
case CSSM_ALGMODE_CBC_IV8:
mode = MODE_CBC;
ivPtr = iv->Data;
break;
case CSSM_ALGMODE_ECB:
mode = MODE_ECB;
ivPtr = NULL;
break;
default:
printf("***AES reference implementation doesn't do padding (yet)\n");
return CSSM_OK;
}
outText->Data = (uint8 *)CSSM_MALLOC(inText->Length);
outText->Length = inText->Length;
artn = _makeKey(&aesKey,
forEncrypt ? DIR_ENCRYPT : DIR_DECRYPT,
keySizeInBits,
cipherBlockSize,
key->Data);
if(artn <= 0) {
printf("***AES makeKey returned %d\n", artn);
return CSSM_ERRCODE_INTERNAL_ERROR;
}
artn = _cipherInit(&aesCipher,
mode,
cipherBlockSize,
ivPtr);
if(artn <= 0) {
printf("***AES cipherInit returned %d\n", artn);
return CSSM_ERRCODE_INTERNAL_ERROR;
}
if(forEncrypt) {
artn = _blockEncrypt(&aesCipher,
&aesKey,
(BYTE *)inText->Data,
inText->Length * 8,
(BYTE *)outText->Data);
}
else {
artn = _blockDecrypt(&aesCipher,
&aesKey,
(BYTE *)inText->Data,
inText->Length * 8,
(BYTE *)outText->Data);
}
if(artn <= 0) {
printf("***AES encrypt/decrypt returned %d\n", artn);
return CSSM_ERRCODE_INTERNAL_ERROR;
}
return CSSM_OK;
}
static CSSM_RETURN encryptDecryptRef(
CSSM_BOOL forEncrypt,
CSSM_ALGORITHMS encrAlg,
CSSM_ENCRYPT_MODE encrMode,
const CSSM_DATA *iv, uint32 keySizeInBits,
uint32 effectiveKeyBits, uint32 cipherBlockSize,
uint32 rounds, CSSM_BOOL useEvp, const CSSM_DATA *key, const CSSM_DATA *inText,
CSSM_DATA_PTR outText) {
switch(encrAlg) {
case CSSM_ALGID_AES:
if(useEvp && (cipherBlockSize == 128)) {
return (CSSM_RETURN)evpEncryptDecrypt(encrAlg, forEncrypt,
key, keySizeInBits, encrMode, iv, inText, outText);
}
else {
return encryptDecryptAES(
forEncrypt,
encrAlg,
encrMode,
iv,
keySizeInBits,
effectiveKeyBits,
cipherBlockSize,
rounds,
key,
inText,
outText);
}
case CSSM_ALGID_BLOWFISH:
case CSSM_ALGID_CAST:
return encryptDecryptEAY(
forEncrypt,
encrAlg,
encrMode,
iv,
keySizeInBits,
key,
inText,
outText);
default:
if(useEvp && (encrAlg == CSSM_ALGID_DES)) {
return (CSSM_RETURN)evpEncryptDecrypt(encrAlg, forEncrypt,
key, keySizeInBits, encrMode, iv, inText, outText);
}
else {
return encryptDecryptBSAFE(
forEncrypt,
encrAlg,
encrMode,
iv,
keySizeInBits,
effectiveKeyBits,
rounds,
key,
inText,
outText);
}
}
}
static CSSM_RETURN encryptDecryptCSSM(
CSSM_CSP_HANDLE cspHand,
CSSM_BOOL forEncrypt,
CSSM_ALGORITHMS keyAlg,
CSSM_ALGORITHMS encrAlg,
CSSM_ENCRYPT_MODE encrMode,
CSSM_PADDING padding,
CSSM_BOOL multiUpdates, const CSSM_DATA *iv, uint32 keySizeInBits,
uint32 effectiveKeyBits, uint32 cipherBlockSize,
uint32 rounds, const CSSM_DATA *key, const CSSM_DATA *inText,
CSSM_BOOL genRaw, CSSM_DATA_PTR outText) {
CSSM_KEY_PTR symKey; CSSM_KEY refKey; CSSM_BOOL refKeyGenerated = CSSM_FALSE;
unsigned keyBytes = (keySizeInBits + 7) / 8;
CSSM_RETURN crtn;
if(genRaw) {
crtn = cspGenSymKeyWithBits(cspHand,
keyAlg,
CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
key,
keyBytes,
&refKey);
if(crtn) {
return crtn;
}
symKey = &refKey;
refKeyGenerated = CSSM_TRUE;
}
else {
symKey = cspGenSymKey(cspHand,
keyAlg,
"noLabel",
8,
CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
keySizeInBits,
CSSM_FALSE); if(symKey == NULL) {
return CSSM_ERRCODE_INTERNAL_ERROR;
}
if(symKey->KeyData.Length != keyBytes) {
printf("***Generated key size error (exp %d, got %lu)\n",
keyBytes, symKey->KeyData.Length);
return CSSM_ERRCODE_INTERNAL_ERROR;
}
memmove(symKey->KeyData.Data, key->Data, keyBytes);
}
outText->Data = NULL;
outText->Length = 0;
if(keySizeInBits == effectiveKeyBits) {
effectiveKeyBits = 0;
}
if(forEncrypt) {
crtn = cspStagedEncrypt(cspHand,
encrAlg,
encrMode,
padding,
symKey,
NULL, effectiveKeyBits,
cipherBlockSize / 8,
rounds,
iv,
inText,
outText,
multiUpdates);
}
else {
crtn = cspStagedDecrypt(cspHand,
encrAlg,
encrMode,
padding,
symKey,
NULL, effectiveKeyBits,
cipherBlockSize / 8,
rounds,
iv,
inText,
outText,
multiUpdates);
}
cspFreeKey(cspHand, symKey);
if(!refKeyGenerated) {
CSSM_FREE(symKey);
}
return crtn;
}
#define LOG_FREQ 20
static int doTest(CSSM_CSP_HANDLE cspHand,
const CSSM_DATA *ptext,
const CSSM_DATA *keyData,
const CSSM_DATA *iv,
uint32 keyAlg, uint32 encrAlg, uint32 encrMode,
uint32 padding,
uint32 keySizeInBits,
uint32 efectiveKeySizeInBits,
uint32 cipherBlockSize,
CSSM_BOOL useEvp, CSSM_BOOL stagedEncr,
CSSM_BOOL stagedDecr,
CSSM_BOOL quiet,
CSSM_BOOL encryptOnly,
CSSM_BOOL genRaw) {
CSSM_DATA ctextRef = {0, NULL}; CSSM_DATA ctextTest = {0, NULL}; CSSM_DATA rptext = {0, NULL}; int rtn = 0;
CSSM_RETURN crtn;
uint32 rounds = 0;
if(encrAlg == CSSM_ALGID_RC5) {
unsigned die = genRand(1,3);
switch(die) {
case 1:
rounds = 8;
break;
case 2:
rounds = 12;
break;
case 3:
rounds = 16;
break;
}
}
crtn = encryptDecryptRef(CSSM_TRUE,
encrAlg,
encrMode,
iv,
keySizeInBits,
efectiveKeySizeInBits,
cipherBlockSize,
rounds,
useEvp,
keyData,
ptext,
&ctextRef);
if(crtn) {
return testError(quiet);
}
crtn = encryptDecryptCSSM(cspHand,
CSSM_TRUE,
keyAlg,
encrAlg,
encrMode,
padding,
stagedEncr,
iv,
keySizeInBits,
efectiveKeySizeInBits,
cipherBlockSize,
rounds,
keyData,
ptext,
genRaw,
&ctextTest);
if(crtn) {
return testError(quiet);
}
if(ctextRef.Length != ctextTest.Length) {
printf("Ctext length mismatch (1)\n");
rtn = testError(quiet);
if(rtn) {
goto abort;
}
}
if(memcmp(ctextRef.Data, ctextTest.Data, ctextTest.Length)) {
printf("Ctext miscompare\n");
rtn = testError(quiet);
if(rtn) {
goto abort;
}
}
if(encryptOnly) {
rtn = 0;
goto abort;
}
crtn = encryptDecryptCSSM(cspHand,
CSSM_FALSE,
keyAlg,
encrAlg,
encrMode,
padding,
stagedDecr,
iv,
keySizeInBits,
efectiveKeySizeInBits,
cipherBlockSize,
rounds,
keyData,
&ctextTest,
genRaw,
&rptext);
if(crtn) {
return testError(quiet);
}
if(rptext.Length != ptext->Length) {
printf("ptext length mismatch (1)\n");
rtn = testError(quiet);
if(rtn) {
goto abort;
}
}
if(memcmp(rptext.Data, ptext->Data, ptext->Length)) {
printf("ptext miscompare\n");
rtn = testError(quiet);
}
else {
rtn = 0;
}
abort:
if(ctextTest.Length) {
CSSM_FREE(ctextTest.Data);
}
if(ctextRef.Length) {
CSSM_FREE(ctextRef.Data);
}
if(rptext.Length) {
CSSM_FREE(rptext.Data);
}
return rtn;
}
int main(int argc, char **argv)
{
int arg;
char *argp;
unsigned loop;
CSSM_DATA ptext;
CSSM_CSP_HANDLE cspHand;
CSSM_BOOL stagedEncr;
CSSM_BOOL stagedDecr;
const char *algStr;
uint32 keyAlg; uint32 encrAlg; int i;
unsigned currAlg; uint32 actKeySizeInBits;
uint32 effectKeySizeInBits;
int rtn = 0;
CSSM_DATA keyData;
CSSM_DATA initVector;
CSSM_BOOL genRaw = CSSM_FALSE; uint32 minTextSize;
uint32 rawMode;
uint32 cookedMode;
const char *rawModeStr;
const char *cookedModeStr;
uint32 algBlockSize;
CSSM_BOOL keySizeSpec = CSSM_FALSE; unsigned minAlg = ALG_FIRST;
unsigned maxAlg = ALG_LAST;
unsigned loops = LOOPS_DEF;
CSSM_BOOL verbose = CSSM_FALSE;
CSSM_BOOL quiet = CSSM_FALSE;
unsigned pauseInterval = 0;
uint32 padding;
CSSM_BOOL bareCsp = CSSM_TRUE;
CSSM_BOOL encryptOnly = CSSM_FALSE;
unsigned maxPtextSize = MAX_DATA_SIZE;
unsigned minPtextSize = MIN_DATA_SIZE;
CSSM_BOOL oneShotOnly = CSSM_FALSE;
CSSM_BOOL allZeroes = CSSM_FALSE;
CSSM_BOOL rawCookedSpecd = CSSM_FALSE; CSSM_BOOL allRaw = CSSM_FALSE;
CSSM_BOOL useEvp = 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 '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;
break;
case 'A':
minAlg = maxAlg = ALG_AES192;
break;
case '6':
minAlg = maxAlg = ALG_AES256;
break;
case 'b':
minAlg = maxAlg = ALG_BFISH;
break;
case 'c':
minAlg = maxAlg = ALG_CAST;
break;
default:
usage(argv);
}
break;
case 'l':
loops = atoi(&argp[2]);
break;
case 'k':
actKeySizeInBits = effectKeySizeInBits = atoi(&argp[2]);
keySizeSpec = CSSM_TRUE;
break;
case 'v':
verbose = CSSM_TRUE;
break;
case 'D':
bareCsp = CSSM_FALSE;
#if CSPDL_ALL_KEYS_ARE_REF
genRaw = CSSM_TRUE;
#endif
break;
case 'e':
encryptOnly = CSSM_TRUE;
break;
case 'm':
maxPtextSize = atoi(&argp[2]);
break;
case 'n':
minPtextSize = atoi(&argp[2]);
break;
case 'z':
allZeroes = CSSM_TRUE;
break;
case 's':
oneShotOnly = CSSM_TRUE;
break;
case 'q':
quiet = CSSM_TRUE;
break;
case 'p':
pauseInterval = atoi(&argp[2]);;
break;
case 'o':
rawCookedSpecd = CSSM_TRUE;
allRaw = CSSM_TRUE;
break;
case 'O':
rawCookedSpecd = CSSM_TRUE;
allRaw = CSSM_FALSE; break;
case 'y':
useEvp = CSSM_TRUE;
break;
case 'h':
default:
usage(argv);
}
}
ptext.Data = (uint8 *)CSSM_MALLOC(maxPtextSize);
if(ptext.Data == NULL) {
printf("Insufficient heap space\n");
exit(1);
}
keyData.Data = (uint8 *)CSSM_MALLOC(MAX_KEY_SIZE);
if(keyData.Data == NULL) {
printf("Insufficient heap space\n");
exit(1);
}
keyData.Length = MAX_KEY_SIZE;
initVector.Data = (uint8 *)"someStrangeInitVect";
printf("Starting symCompat; 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++) {
padding = CSSM_PADDING_PKCS1;
switch(currAlg) {
case ALG_DES:
encrAlg = keyAlg = CSSM_ALGID_DES;
algStr = "DES";
algBlockSize = 8;
if(useEvp) {
rawMode = RAW_MODE;
cookedMode = COOKED_MODE;
rawModeStr = RAW_MODE_STR;
cookedModeStr = COOKED_MODE_STR;
padding = CSSM_PADDING_PKCS5;
}
else {
rawMode = RAW_MODE_BSAFE;
cookedMode = CSSM_ALGMODE_CBCPadIV8;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = COOKED_MODE_STR;
}
break;
case ALG_3DES:
keyAlg = CSSM_ALGID_3DES_3KEY;
encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
algStr = "3DES";
algBlockSize = 8;
rawMode = RAW_MODE_BSAFE;
cookedMode = CSSM_ALGMODE_CBCPadIV8;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = COOKED_MODE_STR;
break;
case ALG_RC2:
encrAlg = keyAlg = CSSM_ALGID_RC2;
algStr = "RC2";
algBlockSize = 8;
rawMode = RAW_MODE_BSAFE;
cookedMode = CSSM_ALGMODE_CBCPadIV8;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = COOKED_MODE_STR;
break;
case ALG_RC4:
encrAlg = keyAlg = CSSM_ALGID_RC4;
algStr = "RC4";
algBlockSize = 0;
rawMode = RAW_MODE_STREAM;
cookedMode = RAW_MODE_STREAM;
rawModeStr = RAW_MODE_STREAM_STR;
cookedModeStr = RAW_MODE_STREAM_STR;
break;
case ALG_RC5:
encrAlg = keyAlg = CSSM_ALGID_RC5;
algStr = "RC5";
algBlockSize = 8;
rawMode = RAW_MODE_BSAFE;
cookedMode = CSSM_ALGMODE_CBCPadIV8;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = COOKED_MODE_STR;
break;
case ALG_AES:
encrAlg = keyAlg = CSSM_ALGID_AES;
algStr = "AES";
algBlockSize = 16;
if(useEvp) {
rawMode = RAW_MODE;
cookedMode = COOKED_MODE;
rawModeStr = RAW_MODE_STR;
cookedModeStr = COOKED_MODE_STR;
padding = CSSM_PADDING_PKCS7;
}
else {
rawMode = RAW_MODE;
cookedMode = RAW_MODE_BSAFE;
rawModeStr = RAW_MODE_STR;
cookedModeStr = RAW_MODE_BSAFE_STR;
}
break;
case ALG_AES192:
encrAlg = keyAlg = CSSM_ALGID_AES;
algStr = "AES192";
algBlockSize = 24;
rawMode = RAW_MODE;
cookedMode = RAW_MODE_BSAFE;
rawModeStr = RAW_MODE_STR;
cookedModeStr = RAW_MODE_BSAFE_STR;
break;
case ALG_AES256:
encrAlg = keyAlg = CSSM_ALGID_AES;
algStr = "AES";
algBlockSize = 32;
rawMode = RAW_MODE;
cookedMode = RAW_MODE_BSAFE;
rawModeStr = RAW_MODE_STR;
cookedModeStr = RAW_MODE_BSAFE_STR;
break;
case ALG_BFISH:
encrAlg = keyAlg = CSSM_ALGID_BLOWFISH;
algStr = "Blowfish";
algBlockSize = 8;
rawMode = RAW_MODE_BSAFE;
cookedMode = RAW_MODE_BSAFE;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = RAW_MODE_BSAFE_STR;
break;
case ALG_CAST:
encrAlg = keyAlg = CSSM_ALGID_CAST;
algStr = "CAST";
algBlockSize = 8;
rawMode = RAW_MODE_BSAFE;
cookedMode = RAW_MODE_BSAFE;
rawModeStr = RAW_MODE_BSAFE_STR;
cookedModeStr = RAW_MODE_BSAFE_STR;
break;
}
initVector.Length = algBlockSize ? algBlockSize : 8;
if(!quiet || verbose) {
printf("Testing alg %s\n", algStr);
}
for(loop=1; ; loop++) {
uint32 mode;
const char *modeStr;
CSSM_BOOL paddingEnabled;
if(rawCookedSpecd) {
if(allRaw) {
mode = rawMode;
modeStr = rawModeStr;
}
else {
mode = cookedMode;
modeStr = cookedModeStr;
}
}
else {
if(loop & 1) {
mode = rawMode;
modeStr = rawModeStr;
}
else {
mode = cookedMode;
modeStr = cookedModeStr;
}
}
switch(mode) {
case CSSM_ALGMODE_CBCPadIV8:
paddingEnabled = CSSM_TRUE;
break;
default:
paddingEnabled = CSSM_FALSE;
break;
}
minTextSize = minPtextSize; if(!paddingEnabled && algBlockSize && (minTextSize < algBlockSize)) {
minTextSize = algBlockSize;
}
simpleGenData(&ptext, minTextSize, maxPtextSize);
if(!paddingEnabled && algBlockSize) {
ptext.Length = (ptext.Length / algBlockSize) * algBlockSize;
}
if(oneShotOnly) {
stagedEncr = CSSM_FALSE;
stagedDecr = CSSM_FALSE;
}
else {
stagedEncr = (loop & 2) ? CSSM_TRUE : CSSM_FALSE;
stagedDecr = (loop & 4) ? CSSM_TRUE : CSSM_FALSE;
}
if(allZeroes) {
memset(ptext.Data, 0, ptext.Length);
memset(keyData.Data, 0, MAX_KEY_SIZE);
keyData.Length = MAX_KEY_SIZE;
}
else {
simpleGenData(&keyData, MAX_KEY_SIZE, MAX_KEY_SIZE);
}
if(!keySizeSpec) {
effectKeySizeInBits = randKeySizeBits(keyAlg, OT_Encrypt);
actKeySizeInBits = (effectKeySizeInBits + 7) & ~7;
}
if(!quiet) {
if(verbose || ((loop % LOOP_NOTIFY) == 0)) {
if(algBlockSize) {
printf("..loop %d text size %lu keySizeBits %u"
" blockSize %u stageEncr %d stageDecr %d mode %s\n",
loop, (unsigned long)ptext.Length, (unsigned)effectKeySizeInBits,
(unsigned)algBlockSize, (int)stagedEncr, (int)stagedDecr,
modeStr);
}
else {
printf("..loop %d text size %lu keySizeBits %u"
" stageEncr %d stageDecr %d mode %s\n",
loop, (unsigned long)ptext.Length, (unsigned)effectKeySizeInBits,
(int)stagedEncr, (int)stagedDecr, modeStr);
}
}
}
if(doTest(cspHand,
&ptext,
&keyData,
&initVector,
keyAlg,
encrAlg,
mode,
padding,
actKeySizeInBits,
actKeySizeInBits, algBlockSize * 8,
useEvp,
stagedEncr,
stagedDecr,
quiet,
encryptOnly,
genRaw)) {
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;
}
}
if(rtn) {
break;
}
}
testDone:
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);
CSSM_FREE(keyData.Data);
return rtn;
}