X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/cspxutils/contextReuse/contextReuse.cpp diff --git a/SecurityTests/cspxutils/contextReuse/contextReuse.cpp b/SecurityTests/cspxutils/contextReuse/contextReuse.cpp deleted file mode 100644 index 993d1799..00000000 --- a/SecurityTests/cspxutils/contextReuse/contextReuse.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/* - * contextReuse.cpp - * - * Verify proper operation of symmetric CSP algorithms when CSSM_CC_HANDLE - * (crypto context) is reused. Tests specifically for Radar 4551700, which - * dealt with a problem with the Gladman AES implementation handling the - * same context for an encrypt followed by a decrypt; other situations - * are tested here (e.g. encrypt followed by another encrypt including CBC) - * as well as all CSP symmetric algorithms. - */ - -#include -#include -#include -#include -#include -#include "cspwrap.h" -#include "common.h" -#include -#include "cspdlTesting.h" - -/* - * Defaults. - */ -#define LOOPS_DEF 200 - -#define MIN_DATA_SIZE 8 -#define MAX_DATA_SIZE 10000 /* bytes */ -#define MAX_KEY_SIZE MAX_KEY_SIZE_RC245_BYTES /* bytes */ -#define LOOP_NOTIFY 20 - -#define RAW_MODE CSSM_ALGMODE_ECB /* doesn't work for BSAFE */ -#define RAW_MODE_STREAM CSSM_ALGMODE_NONE -#define COOKED_MODE CSSM_ALGMODE_CBCPadIV8 - -#define RAW_MODE_STR "ECB" -#define RAW_MODE_STREAM_STR "None" -#define COOKED_MODE_STR "CBC/Pad" - -/* - * Enumerate algs our own way to allow iteration. - */ -typedef enum { - ALG_ASC = 1, // not tested - no reference available - ALG_DES = 1, - ALG_RC2, - ALG_RC4, - ALG_RC5, - ALG_3DES, - ALG_AES, - ALG_AES192, /* 192 bit block */ - ALG_AES256, /* 256 bit block */ - ALG_BFISH, - ALG_CAST -} SymAlg; -#define ALG_FIRST ALG_ASC -#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; s=ASC; default=all)\n"); - printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); - printf(" k=keySizeInBits\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(" D (CSP/DL; default = bare CSP)\n"); - printf(" v(erbose)\n"); - printf(" q(uiet)\n"); - printf(" h(elp)\n"); - exit(1); -} - -#define LOG_STAGED_OPS 0 -#if LOG_STAGED_OPS -#define soprintf(s) printf s -#else -#define soprintf(s) -#endif - -/* - * Multipurpose encrypt. Like cspStagedEncrypt(), but it takes a - * context handle and doesn't have as many options. - */ -static CSSM_RETURN stagedEncrypt( - CSSM_CSP_HANDLE cspHand, - CSSM_CC_HANDLE cryptHand, - uint32 algorithm, // CSSM_ALGID_FEED, etc. - uint32 cipherBlockSizeBytes,// optional - const CSSM_DATA *iv, // init vector, optional - const CSSM_DATA *ptext, - CSSM_DATA_PTR ctext, // mallocd by caller, must be big enough! - CSSM_BOOL multiUpdates) // false:single update, true:multi updates -{ - CSSM_RETURN crtn; - CSSM_SIZE bytesEncrypted; // per update - CSSM_SIZE bytesEncryptedTotal = 0; - CSSM_RETURN ocrtn = CSSM_OK; // 'our' crtn - unsigned toMove; // remaining - unsigned thisMove; // bytes to encrypt on this update - CSSM_DATA thisPtext; // running ptr into ptext - CSSM_DATA thisCtext; // running ptr into ctext - CSSM_BOOL restoreErr = CSSM_FALSE; - CSSM_RETURN savedErr = CSSM_OK; - CSSM_SIZE ctextLen; - - if(cipherBlockSizeBytes) { - crtn = AddContextAttribute(cryptHand, - CSSM_ATTRIBUTE_BLOCK_SIZE, - sizeof(uint32), - CAT_Uint32, - NULL, - cipherBlockSizeBytes); - if(crtn) { - printError("CSSM_UpdateContextAttributes", crtn); - ocrtn = crtn; - goto abort; - } - } - - thisPtext = *ptext; - thisCtext = *ctext; - memset(ctext->Data, 0, ctext->Length); - ctextLen = ctext->Length; - - crtn = CSSM_EncryptDataInit(cryptHand); - if(crtn) { - printError("CSSM_EncryptDataInit", crtn); - ocrtn = crtn; - goto abort; - } - - toMove = ptext->Length; - while(toMove) { - if(multiUpdates) { - thisMove = genRand(1, toMove); - } - else { - /* just do one pass thru this loop */ - thisMove = toMove; - } - thisPtext.Length = thisMove; - crtn = CSSM_EncryptDataUpdate(cryptHand, - &thisPtext, - 1, - &thisCtext, - 1, - &bytesEncrypted); - if(crtn) { - printError("CSSM_EncryptDataUpdate", crtn); - ocrtn = crtn; - goto abort; - } - soprintf(("*** EncryptDataUpdate: ptextLen 0x%x bytesEncrypted 0x%x\n", - (unsigned)thisMove, (unsigned)bytesEncrypted)); - - // NOTE: We return the proper length in ctext.... - ctextLen -= bytesEncrypted; // bump out ptr - thisCtext.Length = ctextLen; - thisCtext.Data += bytesEncrypted; - bytesEncryptedTotal += bytesEncrypted; - thisPtext.Data += thisMove; // bump in ptr - toMove -= thisMove; - } - /* OK, one more */ - crtn = CSSM_EncryptDataFinal(cryptHand, &thisCtext); - if(crtn) { - printError("CSSM_EncryptDataFinal", crtn); - savedErr = crtn; - restoreErr = CSSM_TRUE; - goto abort; - } - soprintf(("*** EncryptDataFinal: bytesEncrypted 0x%x\n", - (unsigned)thisCtext.Length)); - bytesEncryptedTotal += thisCtext.Length; - ctext->Length = bytesEncryptedTotal; -abort: - if(restoreErr) { - /* give caller the error from the encrypt */ - ocrtn = savedErr; - } - return ocrtn; -} - -/* - * Multipurpose decrypt. Like cspStagedDecrypt(), but it takes a - * context handle and doesn't have as many options. - */ -CSSM_RETURN stagedDecrypt( - CSSM_CSP_HANDLE cspHand, - CSSM_CC_HANDLE cryptHand, - uint32 algorithm, // CSSM_ALGID_FEED, etc. - uint32 cipherBlockSizeBytes,// optional - const CSSM_DATA *iv, // init vector, optional - const CSSM_DATA *ctext, - CSSM_DATA_PTR ptext, // mallocd by caller, must be big enough! - CSSM_BOOL multiUpdates) // false:single update, true:multi updates -{ - CSSM_RETURN crtn; - CSSM_SIZE bytesDecrypted; // per update - CSSM_SIZE bytesDecryptedTotal = 0; - CSSM_RETURN ocrtn = CSSM_OK; // 'our' crtn - unsigned toMove; // remaining - unsigned thisMove; // bytes to decrypt on this update - CSSM_DATA thisCtext; // running ptr into ptext - CSSM_DATA thisPtext; // running ptr into ctext - CSSM_SIZE ptextLen; - - if(cipherBlockSizeBytes) { - crtn = AddContextAttribute(cryptHand, - CSSM_ATTRIBUTE_BLOCK_SIZE, - sizeof(uint32), - CAT_Uint32, - NULL, - cipherBlockSizeBytes); - if(crtn) { - printError("CSSM_UpdateContextAttributes", crtn); - ocrtn = crtn; - goto abort; - } - } - - thisCtext = *ctext; - thisPtext = *ptext; - memset(ptext->Data, 0, ptext->Length); - ptextLen = ptext->Length; - - crtn = CSSM_DecryptDataInit(cryptHand); - if(crtn) { - printError("CSSM_DecryptDataInit", crtn); - ocrtn = crtn; - goto abort; - } - - toMove = ctext->Length; - while(toMove) { - if(multiUpdates) { - thisMove = genRand(1, toMove); - } - else { - /* just do one pass thru this loop */ - thisMove = toMove; - } - thisCtext.Length = thisMove; - crtn = CSSM_DecryptDataUpdate(cryptHand, - &thisCtext, - 1, - &thisPtext, - 1, - &bytesDecrypted); - if(crtn) { - printError("CSSM_DecryptDataUpdate", crtn); - ocrtn = crtn; - goto abort; - } - soprintf(("*** DecryptDataUpdate: ctextLen 0x%x bytesDecrypted 0x%x\n", - (unsigned)thisMove, (unsigned)bytesDecrypted)); - - // NOTE: We return the proper length in ptext.... - ptextLen -= bytesDecrypted; // bump out ptr - thisPtext.Length = ptextLen; - thisPtext.Data += bytesDecrypted; - bytesDecryptedTotal += bytesDecrypted; - thisCtext.Data += thisMove; // bump in ptr - toMove -= thisMove; - } - /* OK, one more */ - crtn = CSSM_DecryptDataFinal(cryptHand, &thisPtext); - if(crtn) { - printError("CSSM_DecryptDataFinal", crtn); - ocrtn = crtn; - goto abort; - } - soprintf(("*** DecryptDataFinal: bytesEncrypted 0x%x\n", - (unsigned)thisPtext.Length)); - bytesDecryptedTotal += thisPtext.Length; - ptext->Length = bytesDecryptedTotal; -abort: - return ocrtn; -} - -static int doTest( - CSSM_CSP_HANDLE cspHand, - const CSSM_DATA *ptext, - const CSSM_DATA *ctext1, - const CSSM_DATA *ctext2, - const CSSM_DATA *rptext, - const CSSM_DATA *keyData, - const CSSM_DATA *iv, - uint32 keyAlg, // CSSM_ALGID_xxx of the key - uint32 encrAlg, // encrypt/decrypt - uint32 encrMode, - uint32 padding, - uint32 keySizeInBits, - uint32 cipherBlockSizeBytes, - CSSM_BOOL quiet) -{ - CSSM_DATA lctext1; - CSSM_DATA lctext2; - CSSM_DATA lrptext; - int rtn = 0; - CSSM_RETURN crtn; - CSSM_CC_HANDLE ccHand1 = 0; - CSSM_CC_HANDLE ccHand2 = 0; - CSSM_KEY key1; - CSSM_KEY key2; - uint8 dummy[cipherBlockSizeBytes]; - CSSM_DATA dummyData = {cipherBlockSizeBytes, dummy}; - - /* - * generate two equivalent keys key1 and key2; - * generate two CC handles ccHand1, ccHand2; - * encrypt dummy data with ccHand1 to get it cooked; - * encrypt ptext with ccHand1 ==> ctext1; - * encrypt ptext with ccHand2 ==> ctext2; - * Compare ctext1 and ctext2; - * decrypt ctext1 with ccHand1, compare with ptext; - */ - crtn = cspGenSymKeyWithBits(cspHand, keyAlg, CSSM_KEYUSE_ANY, - keyData, keySizeInBits / 8, &key1); - if(crtn) { - return crtn; - } - crtn = cspGenSymKeyWithBits(cspHand, keyAlg, CSSM_KEYUSE_ANY, - keyData, keySizeInBits / 8, &key2); - if(crtn) { - return crtn; - } - ccHand1 = genCryptHandle(cspHand, - encrAlg, - encrMode, - padding, - &key1, - NULL, // pubKey - iv, - 0, // effectiveKeySizeInBits - 0); // rounds - if(ccHand1 == 0) { - return CSSMERR_CSP_INTERNAL_ERROR; - } - ccHand2 = genCryptHandle(cspHand, - encrAlg, - encrMode, - padding, - &key2, - NULL, // pubKey - iv, - 0, // effectiveKeySizeInBits - 0); // rounds - if(ccHand2 == 0) { - return CSSMERR_CSP_INTERNAL_ERROR; - } - - /* dummy encrypt to heat up ccHand1 */ - appGetRandomBytes(dummy, sizeof(dummy)); - lctext1 = *ctext1; - crtn = stagedEncrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes, - iv, &dummyData, &lctext1, CSSM_FALSE); - if(crtn) { - return crtn; - } - - /* encrypt ptext with ccHand1 and ccHand2, compare ctext */ - lctext1 = *ctext1; - crtn = stagedEncrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes, - iv, ptext, &lctext1, CSSM_TRUE); - if(crtn) { - return crtn; - } - lctext2 = *ctext2; - crtn = stagedEncrypt(cspHand, ccHand2, encrAlg, cipherBlockSizeBytes, - iv, ptext, &lctext2, CSSM_TRUE); - if(crtn) { - return crtn; - } - if(!appCompareCssmData(&lctext1, &lctext2)) { - printf("***Ciphertext miscompare\n"); - if(testError(quiet)) { - return 1; - } - } - - /* decrypt with ccHand1, compare with ptext */ - lrptext = *rptext; - crtn = stagedDecrypt(cspHand, ccHand1, encrAlg, cipherBlockSizeBytes, - iv, &lctext1, &lrptext, CSSM_TRUE); - if(crtn) { - return crtn; - } - if(!appCompareCssmData(&lctext1, &lctext2)) { - printf("***Plaintext miscompare\n"); - if(testError(quiet)) { - return 1; - } - } - - if(ccHand1) { - CSSM_DeleteContext(ccHand1); - } - if(ccHand2) { - CSSM_DeleteContext(ccHand2); - } - return rtn; -} - - -int main(int argc, char **argv) -{ - int arg; - char *argp; - unsigned loop; - CSSM_DATA ptext; - CSSM_DATA ctext1; - CSSM_DATA ctext2; - CSSM_DATA rptext; - CSSM_CSP_HANDLE cspHand; - const char *algStr; - uint32 keyAlg; // CSSM_ALGID_xxx of the key - uint32 encrAlg; // CSSM_ALGID_xxx of encr/decr - unsigned currAlg; // ALG_xxx - uint32 keySizeInBits; - int rtn = 0; - CSSM_DATA keyData; - CSSM_DATA initVector; - uint32 minTextSize; - uint32 rawMode; - uint32 cookedMode; - const char *rawModeStr; - const char *cookedModeStr; - uint32 algBlockSizeBytes; - - /* - * User-spec'd params - */ - CSSM_BOOL keySizeSpec = CSSM_FALSE; // false: use rand key size - 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; - unsigned maxPtextSize = MAX_DATA_SIZE; - unsigned minPtextSize = MIN_DATA_SIZE; - - for(arg=1; arg