]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/pbeTest/pbeTest.c
Security-57740.51.3.tar.gz
[apple/security.git] / SecurityTests / cspxutils / pbeTest / pbeTest.c
diff --git a/SecurityTests/cspxutils/pbeTest/pbeTest.c b/SecurityTests/cspxutils/pbeTest/pbeTest.c
deleted file mode 100644 (file)
index ddce2c7..0000000
+++ /dev/null
@@ -1,1270 +0,0 @@
-/* Copyright (c) 1998,2003-2005,2008 Apple Inc.
- *
- * pbeTest.c - test CSP PBE-style DeriveKey().
- *
- * Revision History
- * ----------------
- *  15 May 2000 Doug Mitchell
- *             Ported to X/CDSA2. 
- *  13 Aug 1998        Doug Mitchell at NeXT
- *             Created.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <Security/cssm.h>
-#include "cspwrap.h"
-#include "common.h"
-#include "cspdlTesting.h"
-
-/* we need to know a little bit about AES for this test.... */
-#define AES_BLOCK_SIZE         16              /* bytes */
-
-/*
- * Defaults.
- */
-#define LOOPS_DEF                      10
-#define MIN_PTEXT_SIZE         AES_BLOCK_SIZE          /* for non-padding tests */
-#define MAX_PTEXT_SIZE         1000
-#define MAX_PASSWORD_SIZE      64
-#define MAX_SALT_SIZE          32
-#define MIN_ITER_COUNT         1000
-#define MAX_ITER_COUNT         2000
-#define MAX_IV_SIZE                    AES_BLOCK_SIZE
-
-/* min values not currently exported by CSP */
-#define APPLE_PBE_MIN_PASSWORD 8
-#define APPLE_PBE_MIN_SALT             8
-
-/* static IV for derive algorithms which don't create one */
-CSSM_DATA staticIv = {MAX_IV_SIZE, (uint8 *)"someIvOrOther..."};
-
-/*
- * Enumerate algs our own way to allow iteration.
- */
-typedef unsigned privAlg;
-enum {
-       /* PBE algs */
-       pbe_pbkdf2 = 1,
-       // other unsupported for now
-       pbe_PKCS12 = 1,
-       pbe_MD5,
-       pbe_MD2,
-       pbe_SHA1,
-       
-       /* key gen algs */
-       pka_ASC,
-       pka_RC4,
-       pka_DES,
-       pka_RC2,
-       pka_RC5,
-       pka_3DES,
-       pka_AES
-};
-
-#define PBE_ALG_FIRST                  pbe_pbkdf2
-#define PBE_ALG_LAST                   pbe_pbkdf2
-#define ENCR_ALG_FIRST                 pka_ASC
-#define ENCR_ALG_LAST                  pka_AES
-#define ENCR_ALG_LAST_EXPORT   pka_RC5
-
-/*
- * Args passed to each test
- */
-typedef struct {
-       CSSM_CSP_HANDLE         cspHand;
-       CSSM_ALGORITHMS         keyAlg;
-       CSSM_ALGORITHMS         encrAlg;
-       uint32                          keySizeInBits;
-       uint32                          effectiveKeySizeInBits; // 0 means not used
-       const char                      *keyAlgStr;
-       CSSM_ENCRYPT_MODE       encrMode;
-       CSSM_PADDING            encrPad;
-       CSSM_ALGORITHMS         deriveAlg;
-       const char                      *deriveAlgStr;
-       CSSM_DATA_PTR           ptext;
-       CSSM_DATA_PTR           password;
-       CSSM_DATA_PTR           salt;
-       uint32                          iterCount;
-       CSSM_BOOL                       useInitVector;          // encrypt needs an IV
-       uint32                          ivSize;
-       CSSM_BOOL                       genInitVector;          // DeriveKey generates an IV
-       CSSM_BOOL                       useRefKey;
-       CSSM_BOOL                       quiet;
-} testArgs;
-
-static void usage(char **argv)
-{
-       printf("usage: %s [options]\n", argv[0]);
-       printf("   Options:\n");
-       printf("   l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
-       printf("   e(xport)\n");
-       printf("   r(epeatOnly)\n");
-       printf("   z(ero length password)\n");
-       printf("   p(ause after each loop)\n");
-       printf("   D (CSP/DL; default = bare CSP)\n");
-       printf("   q(uiet)\n");
-       printf("   h(elp)\n");
-       exit(1);
-}
-
-/*
- * Given a privAlg value, return various associated stuff.
- */
-static void algInfo(privAlg alg,                       // pbe_MD5, etc.
-       CSSM_ALGORITHMS         *cdsaAlg,               // CSSM_ALGID_MD5_PBE, etc. RETURNED
-                                                                               //   key alg for key gen algs
-       CSSM_ALGORITHMS         *encrAlg,               // encrypt/decrypt alg for key 
-                                                                               //   gen algs
-       CSSM_ENCRYPT_MODE       *mode,                  // RETURNED
-       CSSM_PADDING            *padding,               // RETURNED
-       CSSM_BOOL                       *useInitVector, // RETURNED, for encrypt/decrypt
-       uint32                          *ivSize,                // RETURNED, in bytes
-       CSSM_BOOL                       *genInitVector, // RETURNED, for deriveKey
-       const char                      **algStr)               // RETURNED
-{
-       /* default or irrelevant fields */
-       *mode = CSSM_ALGMODE_NONE;
-       *useInitVector = CSSM_FALSE;
-       *genInitVector = CSSM_FALSE;            // DeriveKey doesn't do this now
-       *padding = CSSM_PADDING_PKCS1;
-       *ivSize = 8;                                            // thje usual size, if needed
-       *encrAlg = CSSM_ALGID_NONE;
-       
-       switch(alg) {
-               case pbe_pbkdf2:
-                       *cdsaAlg = CSSM_ALGID_PKCS5_PBKDF2;
-                       *algStr = "PBKDF2";
-                       return;
-               /* these are not supported */
-               #if 0
-               case pbe_PKCS12:
-                       *cdsaAlg = CSSM_ALGID_SHA1_PBE_PKCS12;
-                       *algStr = "PKCS12";
-                       return;
-               case pbe_MD5:
-                       *cdsaAlg = CSSM_ALGID_MD5_PBE;
-                       *algStr = "MD5";
-                       return;
-               case pbe_MD2:
-                       *cdsaAlg = CSSM_ALGID_MD2_PBE;
-                       *algStr = "MD2";
-                       return;
-               case pbe_SHA1:
-                       *cdsaAlg = CSSM_ALGID_SHA1_PBE;
-                       *algStr = "SHA1";
-                       return;
-               case pka_ASC:
-                       *cdsaAlg = CSSM_ALGID_ASC;
-                       *algStr = "ASC";
-                       return;
-               #endif 
-               case pka_DES:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_DES;
-                       *useInitVector = CSSM_TRUE;
-                       *mode = CSSM_ALGMODE_CBCPadIV8;
-                       *algStr = "DES";
-                       return;
-               case pka_3DES:
-                       *cdsaAlg = CSSM_ALGID_3DES_3KEY;
-                       *encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
-                       *useInitVector = CSSM_TRUE;
-                       *mode = CSSM_ALGMODE_CBCPadIV8;
-                       *algStr = "3DES";
-                       return;
-               case pka_AES:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_AES;
-                       *useInitVector = CSSM_TRUE;
-                       *mode = CSSM_ALGMODE_CBCPadIV8;
-                       *padding = CSSM_PADDING_PKCS5;
-                       *ivSize = AES_BLOCK_SIZE;                       // per the default block size
-                       *algStr = "AES";
-                       return;
-               case pka_RC2:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_RC2;
-                       *useInitVector = CSSM_TRUE;
-                       *mode = CSSM_ALGMODE_CBCPadIV8;
-                       *algStr = "RC2";
-                       return;
-               case pka_RC4:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_RC4;
-                       /* initVector false */
-                       *mode = CSSM_ALGMODE_NONE;
-                       *algStr = "RC4";
-                       return;
-               case pka_RC5:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_RC5;
-                       *algStr = "RC5";
-                       *mode = CSSM_ALGMODE_CBCPadIV8;
-                       *useInitVector = CSSM_TRUE;
-                       return;
-               case pka_ASC:
-                       *cdsaAlg = *encrAlg = CSSM_ALGID_ASC;
-                       /* initVector false */
-                       *algStr = "ASC";
-                       *mode = CSSM_ALGMODE_NONE;
-                       return;
-               default:
-                       printf("BRRZZZT! Update algInfo()!\n");
-                       testError(CSSM_TRUE);
-       }
-}
-
-/* a handy "compare two CSSM_DATAs" ditty */
-static CSSM_BOOL compareData(const CSSM_DATA_PTR d1,
-       const CSSM_DATA_PTR d2)
-{
-       if(d1->Length != d2->Length) {
-               return CSSM_FALSE;
-       }
-       if(memcmp(d1->Data, d2->Data, d1->Length)) {
-               return CSSM_FALSE;
-       }
-       return CSSM_TRUE;
-}
-
-/* generate random one-bit byte */
-static uint8 randBit()
-{
-       return 1 << genRand(0, 7);
-}
-
-/*
- * Writer debug - assertion failure when ctext[1].Data is NULL
- * but length is nonzero
- */
-#define SAFE_CTEXT_ARRAY       0
-
-/*
- * Encrypt ptext using specified key, IV, effectiveKeySizeInBits
- */
-static int encryptCom(CSSM_CSP_HANDLE cspHand,
-       const char *testName,
-       CSSM_DATA_PTR ptext,
-       CSSM_KEY_PTR key,
-       CSSM_ALGORITHMS alg,
-       CSSM_ENCRYPT_MODE mode,
-       CSSM_PADDING padding,                   // CSSM_PADDING_PKCS1, etc. 
-       CSSM_DATA_PTR iv,                               // may be NULL
-       uint32 effectiveKeySizeInBits,  // may be 0
-       CSSM_DATA_PTR ctext,                    // RETURNED
-       CSSM_BOOL quiet)
-{
-       CSSM_CC_HANDLE cryptHand;
-       CSSM_RETURN crtn;
-       CSSM_SIZE bytesEncrypted;
-       CSSM_DATA remData;
-       int rtn;
-       #if     SAFE_CTEXT_ARRAY
-       CSSM_DATA safeCtext[2];
-       safeCtext[0] = *ctext;
-       safeCtext[1].Data = NULL;
-       safeCtext[1].Length = 10;               // lie, but shouldn't use this!
-       #else
-       //      printf("+++ ctext[0] = %d:0x%x; ctext[1] = %d:0x%x\n",
-       //              ctext[0].Length, ctext[0].Data,
-       //              ctext[1].Length, ctext[1].Data);
-       #endif
-       
-       cryptHand = genCryptHandle(cspHand,
-               alg,
-               mode,
-               padding,                
-               key,
-               NULL,                   // no 2nd key
-               iv,                             // InitVector
-               effectiveKeySizeInBits,
-               0);                             // rounds
-       if(cryptHand == 0) {
-               return testError(quiet);
-       }
-       
-       remData.Data = NULL;
-       remData.Length = 0;
-       crtn = CSSM_EncryptData(cryptHand,
-               ptext,
-               1,
-               #if     SAFE_CTEXT_ARRAY
-               &safeCtext[0],
-               #else
-               ctext,
-               #endif
-               1,
-               &bytesEncrypted,
-               &remData);
-       #if     SAFE_CTEXT_ARRAY
-       *ctext = safeCtext[0];
-       #endif
-       
-       if(crtn) {
-               printError("CSSM_EncryptData", crtn);
-               rtn = testError(quiet);
-               goto done;
-       }
-       if(remData.Length != 0) {
-               //printf("***WARNING: nonzero remData on encrypt!\n");
-               /* new for CDSA2 - possible remData even if we ask the CSP to 
-                * malloc ctext */
-               ctext->Data = (uint8 *)appRealloc(ctext->Data, bytesEncrypted, NULL);
-               memmove(ctext->Data + ctext->Length, 
-                       remData.Data, 
-                       bytesEncrypted - ctext->Length);
-               appFreeCssmData(&remData, CSSM_FALSE);
-       }
-       /* new for CDSA 2 */
-       ctext->Length = bytesEncrypted;
-       rtn = 0;
-done:
-       if(CSSM_DeleteContext(cryptHand)) {
-               printError("CSSM_DeleteContext", 0);
-               rtn = 1;
-       }
-       return rtn;
-}
-
-/*
- * Decrypt ctext using specified key, IV, effectiveKeySizeInBits
- */
-static int decryptCom(CSSM_CSP_HANDLE cspHand,
-       const char *testName,
-       CSSM_DATA_PTR ctext,
-       CSSM_KEY_PTR key,
-       CSSM_ALGORITHMS alg,
-       CSSM_ENCRYPT_MODE mode,
-       CSSM_PADDING padding,           
-       CSSM_DATA_PTR iv,                               // may be NULL
-       uint32 effectiveKeySizeInBits,  // may be 0
-       CSSM_DATA_PTR ptext,                    // RETURNED
-       CSSM_BOOL quiet)
-{
-       CSSM_CC_HANDLE cryptHand;
-       CSSM_RETURN crtn;
-       CSSM_SIZE bytesDecrypted;
-       CSSM_DATA remData;
-       int rtn;
-
-       cryptHand = genCryptHandle(cspHand,
-               alg,
-               mode,
-               padding,                
-               key,
-               NULL,                   // no 2nd key
-               iv,                             // InitVector
-               effectiveKeySizeInBits,
-               0);                             // rounds
-       if(cryptHand == 0) {
-               return testError(quiet);
-       }
-       remData.Data = NULL;
-       remData.Length = 0;
-       crtn = CSSM_DecryptData(cryptHand,
-               ctext,
-               1,
-               ptext,
-               1,
-               &bytesDecrypted,
-               &remData);
-       if(crtn) {
-               printError("CSSM_DecryptData", crtn);
-               rtn = testError(quiet);
-               goto done;
-       }
-       if(remData.Length != 0) {
-               //printf("***WARNING: nonzero remData on decrypt!\n");
-               /* new for CDSA2 - possible remData even if we ask the CSP to 
-                * malloc ptext */
-               ptext->Data = (uint8 *)appRealloc(ptext->Data, bytesDecrypted, NULL);
-               memmove(ptext->Data + ptext->Length, 
-                       remData.Data, 
-                       bytesDecrypted - ptext->Length);
-               appFreeCssmData(&remData, CSSM_FALSE);
-       }
-       /* new for CDSA 2 */
-       ptext->Length = bytesDecrypted;
-       rtn = 0;
-done:
-       if(CSSM_DeleteContext(cryptHand)) {
-               printError("CSSM_DeleteContext", 0);
-               rtn = 1;
-       }
-       return rtn;
-}
-
-/*
- * Common test portion
- *   encrypt ptext with key1, iv1
- *   encrypt ptext with key2, iv2
- *      compare 2 ctexts; expect failure;
- */
-#define TRAP_WRITER_ERR        1
-
-static int testCommon(CSSM_CSP_HANDLE cspHand,
-       const char *testName,
-       CSSM_ALGORITHMS encrAlg,
-       CSSM_ENCRYPT_MODE encrMode,
-       CSSM_PADDING encrPad,
-       uint32 effectiveKeySizeInBits,
-       CSSM_DATA_PTR ptext,
-       CSSM_KEY_PTR key1,
-       CSSM_DATA_PTR iv1,
-       CSSM_KEY_PTR key2,
-       CSSM_DATA_PTR iv2,
-       CSSM_BOOL quiet)
-{
-       CSSM_DATA               ctext1;
-       CSSM_DATA               ctext2;
-       ctext1.Data = NULL;
-       ctext1.Length = 0;
-       ctext2.Data = NULL;
-       ctext2.Length = 0;
-       if(encryptCom(cspHand,
-                       testName,
-                       ptext,
-                       key1,
-                       encrAlg,
-                       encrMode,
-                       encrPad,
-                       iv1,
-                       effectiveKeySizeInBits,
-                       &ctext1,
-                       quiet)) {
-               return 1;
-       }
-       #if     TRAP_WRITER_ERR
-       if(ctext2.Data != NULL){
-               printf("Hey! encryptCom(ptext, ctext1 modified ctext2!\n");
-               if(testError(quiet)) {
-                       return 1;
-               }
-       }
-       #endif
-       if(encryptCom(cspHand,
-                       testName,
-                       ptext,
-                       key2,
-                       encrAlg,
-                       encrMode,
-                       encrPad,
-                       iv2,
-                       effectiveKeySizeInBits,
-                       &ctext2,
-                       quiet)) {
-               return 1;
-       }
-       if(compareData(&ctext1, &ctext2)) {
-               printf("***%s: Unexpected Data compare!\n", testName);
-               return testError(quiet);
-       }
-       appFreeCssmData(&ctext1, CSSM_FALSE);
-       appFreeCssmData(&ctext2, CSSM_FALSE);
-       return 0;
-}
-
-/**
- ** inidividual tests.
- **/
-#define KEY_LABEL1             "noLabel1"
-#define KEY_LABEL2             "noLabel2"
-#define KEY_LABEL_LEN  strlen(KEY_LABEL1)
-#define REPEAT_ON_ERROR        1
-
-/* test repeatability - the only test here which actually decrypts */
-static int repeatTest(testArgs *targs)
-{
-       /*
-       generate two keys with same params;
-       encrypt ptext with key1;
-       decrypt ctext with key2;
-       compare; expect success;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_KEY_PTR    key2;
-       CSSM_DATA               iv1;
-       CSSM_DATA               iv2;
-       CSSM_DATA_PTR   ivp1;
-       CSSM_DATA_PTR   ivp2;
-       CSSM_DATA               ctext;
-       CSSM_DATA               rptext;
-       CSSM_BOOL               gotErr = CSSM_FALSE;
-       
-       if(targs->useInitVector) {
-               if(targs->genInitVector) {
-                       ivp1 = &iv1;
-                       ivp2 = &iv2;
-               }
-               else {
-                       staticIv.Length = targs->ivSize;
-                       ivp1 = ivp2 = &staticIv;
-               }
-       }
-       else {
-               ivp1 = ivp2 = NULL;
-       }
-       /* these need to be init'd regardless */
-       iv1.Data = NULL;
-       iv1.Length = 0;
-       iv2.Data = NULL;
-       iv2.Length = 0;
-       ctext.Data = NULL;
-       ctext.Length = 0;
-       rptext.Data = NULL;
-       rptext.Length = 0;
-repeatDerive:
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(targs->quiet);
-       }
-       key2 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL2,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_DECRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv2);
-       if(key2 == NULL) {
-               return testError(targs->quiet);
-       }
-repeatEnc:
-       if(encryptCom(targs->cspHand,
-                       "repeatTest",
-                       targs->ptext,
-                       key1,
-                       targs->encrAlg,
-                       targs->encrMode,
-                       targs->encrPad,
-                       ivp1,
-                       targs->effectiveKeySizeInBits,
-                       &ctext,
-                       targs->quiet)) {
-               return 1;
-       }
-       if(decryptCom(targs->cspHand,
-                       "repeatTest",
-                       &ctext,
-                       key2,
-                       targs->encrAlg,
-                       targs->encrMode,
-                       targs->encrPad,
-                       ivp2,
-                       targs->effectiveKeySizeInBits,
-                       &rptext,
-                       targs->quiet)) {
-               return 1;
-       }
-       if(gotErr || !compareData(targs->ptext, &rptext)) {
-               printf("***Data miscompare in repeatTest\n");
-               if(REPEAT_ON_ERROR) {
-                       char str;
-                       
-                       gotErr = CSSM_TRUE;
-                       fpurge(stdin);
-                       printf("Repeat enc/dec (r), repeat derive (d), continue (c), abort (any)? ");
-                       str = getchar();
-                       switch(str) {
-                               case 'r':
-                                       appFreeCssmData(&ctext, CSSM_FALSE);    
-                                       appFreeCssmData(&rptext, CSSM_FALSE);   
-                                       goto repeatEnc;
-                               case 'd':
-                                       appFreeCssmData(&ctext, CSSM_FALSE);    
-                                       appFreeCssmData(&rptext, CSSM_FALSE);   
-                                       appFreeCssmData(&iv1, CSSM_FALSE);
-                                       appFreeCssmData(&iv2, CSSM_FALSE);
-                                       cspFreeKey(targs->cspHand, key1);
-                                       cspFreeKey(targs->cspHand, key2);
-                                       goto repeatDerive;
-                               case 'c':
-                                       break;
-                               default:
-                                       return 1;
-                       }
-               }
-               else {
-                       return testError(targs->quiet);
-               }
-       }
-       appFreeCssmData(&ctext, CSSM_FALSE);
-       appFreeCssmData(&rptext, CSSM_FALSE);
-       appFreeCssmData(&iv1, CSSM_FALSE);
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       cspFreeKey(targs->cspHand, key2);
-       CSSM_FREE(key1);
-       CSSM_FREE(key2);
-       return 0;
-}
-
-/* ensure iterCount alters key */
-static int iterTest(testArgs *targs)
-{
-       /*
-       generate key1(iterCount), key2(iterCount+1);
-       encrypt ptext with key1;
-       encrypt ptext with key2;
-       compare 2 ctexts; expect failure;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_KEY_PTR    key2;
-       CSSM_DATA               iv1;
-       CSSM_DATA               iv2;
-       CSSM_DATA_PTR   ivp1;
-       CSSM_DATA_PTR   ivp2;
-       if(targs->useInitVector) {
-               if(targs->genInitVector) {
-                       ivp1 = &iv1;
-                       ivp2 = &iv2;
-               }
-               else {
-                       staticIv.Length = targs->ivSize;
-                       ivp1 = ivp2 = &staticIv;
-               }
-       }
-       else {
-               ivp1 = ivp2 = NULL;
-       }
-       /* these need to be init'd regardless */
-       iv1.Data = NULL;
-       iv1.Length = 0;
-       iv2.Data = NULL;
-       iv2.Length = 0;
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(targs->quiet);
-       }
-       key2 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL2,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount + 1,           // the changed param
-               &iv2);
-       if(key2 == NULL) {
-               return testError(targs->quiet);
-       }
-       if(testCommon(targs->cspHand,
-                               "iterTest",
-                               targs->encrAlg,
-                               targs->encrMode,
-                               targs->encrPad,
-                               targs->effectiveKeySizeInBits,
-                               targs->ptext,
-                               key1,
-                               ivp1,
-                               key2,
-                               ivp2,
-                               targs->quiet)) {
-               return 1;
-       }
-       appFreeCssmData(&iv1, CSSM_FALSE);
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       cspFreeKey(targs->cspHand, key2);
-       CSSM_FREE(key1);
-       CSSM_FREE(key2);
-       return 0;
-}
-
-/* ensure password alters key */
-static int passwordTest(testArgs *targs)
-{
-       /*
-       generate key1(password), key2(munged password);
-       encrypt ptext with key1;
-       encrypt ptext with key2;
-       compare 2 ctexts; expect failure;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_KEY_PTR    key2;
-       CSSM_DATA               iv1;
-       CSSM_DATA               iv2;
-       CSSM_DATA_PTR   ivp1;
-       CSSM_DATA_PTR   ivp2;
-       uint32                  mungeDex;
-       uint32                  mungeBits;
-       if(targs->useInitVector) {
-               if(targs->genInitVector) {
-                       ivp1 = &iv1;
-                       ivp2 = &iv2;
-               }
-               else {
-                       staticIv.Length = targs->ivSize;
-                       ivp1 = ivp2 = &staticIv;
-               }
-       }
-       else {
-               ivp1 = ivp2 = NULL;
-       }
-       /* these need to be init'd regardless */
-       iv1.Data = NULL;
-       iv1.Length = 0;
-       iv2.Data = NULL;
-       iv2.Length = 0;
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(targs->quiet);
-       }
-       /* munge password */
-       mungeDex = genRand(0, targs->password->Length - 1);
-       mungeBits = randBit();
-       targs->password->Data[mungeDex] ^= mungeBits;
-       key2 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL2,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,                        // the changed param
-               targs->salt,
-               targs->iterCount,
-               &iv2);
-       if(key2 == NULL) {
-               return testError(targs->quiet);
-       }
-       if(testCommon(targs->cspHand,
-                               "passwordTest",
-                               targs->encrAlg,
-                               targs->encrMode,
-                               targs->encrPad,
-                               targs->effectiveKeySizeInBits,
-                               targs->ptext,
-                               key1,
-                               ivp1,
-                               key2,
-                               ivp2,
-                               targs->quiet)) {
-               return 1;
-       }
-       /* restore  */
-       targs->password->Data[mungeDex] ^= mungeBits;
-       appFreeCssmData(&iv1, CSSM_FALSE);
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       cspFreeKey(targs->cspHand, key2);
-       CSSM_FREE(key1);
-       CSSM_FREE(key2);
-       return 0;
-}
-
-/* ensure salt alters key */
-static int saltTest(testArgs *targs)
-{
-       /*
-       generate key1(seed), key2(munged seed);
-       encrypt ptext with key1;
-       encrypt ptext with key2;
-       compare 2 ctexts; expect failure;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_KEY_PTR    key2;
-       CSSM_DATA               iv1;
-       CSSM_DATA               iv2;
-       CSSM_DATA_PTR   ivp1;
-       CSSM_DATA_PTR   ivp2;
-       uint32                  mungeDex;
-       uint32                  mungeBits;
-       if(targs->useInitVector) {
-               if(targs->genInitVector) {
-                       ivp1 = &iv1;
-                       ivp2 = &iv2;
-               }
-               else {
-                       staticIv.Length = targs->ivSize;
-                       ivp1 = ivp2 = &staticIv;
-               }
-       }
-       else {
-               ivp1 = ivp2 = NULL;
-       }
-       /* these need to be init'd regardless */
-       iv1.Data = NULL;
-       iv1.Length = 0;
-       iv2.Data = NULL;
-       iv2.Length = 0;
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(targs->quiet);
-       }
-       /* munge salt */
-       mungeDex = genRand(0, targs->salt->Length - 1);
-       mungeBits = randBit();
-       targs->salt->Data[mungeDex] ^= mungeBits;
-       key2 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL2,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,                            // the changed param
-               targs->iterCount,
-               &iv2);
-       if(key2 == NULL) {
-               return testError(targs->quiet);
-       }
-       if(testCommon(targs->cspHand,
-                               "saltTest",
-                               targs->encrAlg,
-                               targs->encrMode,
-                               targs->encrPad,
-                               targs->effectiveKeySizeInBits,
-                               targs->ptext,
-                               key1,
-                               ivp1,
-                               key2,
-                               ivp2,
-                               targs->quiet)) {
-               return 1;
-       }
-       /* restore  */
-       targs->salt->Data[mungeDex] ^= mungeBits;
-       appFreeCssmData(&iv1, CSSM_FALSE);
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       cspFreeKey(targs->cspHand, key2);
-       CSSM_FREE(key1);
-       CSSM_FREE(key2);
-       return 0;
-}
-
-/* ensure initVector alters ctext. This isn't testing PBE per se, but
- * it's a handy place to verify this function. */
-static int initVectTest(testArgs *targs)
-{
-       /*
-       generate key1;
-       encrypt ptext with key1 and initVector;
-       encrypt ptext with key1 and munged initVector;
-       compare 2 ctexts; expect failure;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_DATA               iv1;
-       CSSM_DATA               iv2;
-       uint32                  mungeDex;
-       uint32                  mungeBits;
-       
-       if(targs->genInitVector) {
-               iv1.Data = NULL;
-               iv1.Length = 0;
-       }
-       else  {
-               iv1 = staticIv;
-       }
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(targs->quiet);
-       }
-       
-       /* get munged copy of iv */
-       iv2.Data = (uint8 *)CSSM_MALLOC(iv1.Length);
-       iv2.Length = iv1.Length;
-       memmove(iv2.Data, iv1.Data, iv1.Length);
-       mungeDex = genRand(0, iv1.Length - 1);
-       mungeBits = randBit();
-       iv2.Data[mungeDex] ^= mungeBits;
-       if(testCommon(targs->cspHand,
-                               "initVectTest",
-                               targs->encrAlg,
-                               targs->encrMode,
-                               targs->encrPad,
-                               targs->effectiveKeySizeInBits,
-                               targs->ptext,
-                               key1,
-                               &iv1,
-                               key1,
-                               &iv2,   // the changed param
-                               targs->quiet)) {        
-               return 1;
-       }
-       if(targs->genInitVector) {
-               appFreeCssmData(&iv1, CSSM_FALSE);
-       }
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       CSSM_FREE(key1);
-       return 0;
-}
-
-#if 0
-/* only one algorithm supported */
-/* ensure deriveAlg alters key */
-static int deriveAlgTest(testArgs *targs)
-{
-       /*
-       generate key1(deriveAlg), key2(some other deriveAlg);
-       encrypt ptext with key1;
-       encrypt ptext with key2;
-       compare 2 ctexts; expect failure;
-       */
-       CSSM_KEY_PTR    key1;
-       CSSM_KEY_PTR    key2;
-       CSSM_DATA       iv1;
-       CSSM_DATA       iv2;
-       CSSM_DATA_PTR   ivp1;
-       CSSM_DATA_PTR   ivp2;
-       uint32          mungeAlg;
-       
-       if(targs->useInitVector) {
-               if(targs->genInitVector) {
-                       ivp1 = &iv1;
-                       ivp2 = &iv2;
-               }
-               else {
-                       staticIv.Length = targs->ivSize;
-                       ivp1 = ivp2 = &staticIv;
-               }
-       }
-       else {
-               ivp1 = ivp2 = NULL;
-       }
-       
-       /* these need to be init'd regardless */
-       iv1.Data = NULL;
-       iv1.Length = 0;
-       iv2.Data = NULL;
-       iv2.Length = 0;
-       key1 = cspDeriveKey(targs->cspHand,
-               targs->deriveAlg,
-               targs->keyAlg,
-               KEY_LABEL1,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,
-               targs->salt,
-               targs->iterCount,
-               &iv1);
-       if(key1 == NULL) {
-               return testError(quiet);
-       }
-       
-       /* munge deriveAlg */
-       switch(targs->deriveAlg) {
-               case CSSM_ALGID_MD5_PBE:
-                       mungeAlg = CSSM_ALGID_MD2_PBE;
-                       break;
-               case CSSM_ALGID_MD2_PBE:
-                       mungeAlg = CSSM_ALGID_SHA1_PBE;
-                       break;
-               case CSSM_ALGID_SHA1_PBE:
-                       mungeAlg = CSSM_ALGID_SHA1_PBE_PKCS12;
-                       break;
-               case CSSM_ALGID_SHA1_PBE_PKCS12:
-                       mungeAlg = CSSM_ALGID_MD5_PBE;
-                       break;
-               default:
-                       printf("BRRRZZZT! Update deriveAlgTest()!\n");
-                       return testError(quiet);
-       }
-       key2 = cspDeriveKey(targs->cspHand,
-               mungeAlg,                               // the changed param
-               targs->keyAlg,
-               KEY_LABEL2,
-               KEY_LABEL_LEN,
-               CSSM_KEYUSE_ENCRYPT,
-               targs->keySizeInBits,
-               targs->useRefKey,
-               targs->password,                        // the changed param
-               targs->salt,
-               targs->iterCount,
-               &iv2);
-       if(key2 == NULL) {
-               return testError(quiet);
-       }
-       if(testCommon(targs->cspHand,
-                       "deriveAlgTest",
-                       targs->encrAlg,
-                       targs->encrMode,
-                       targs->encrPad,
-                       targs->effectiveKeySizeInBits,
-                       targs->ptext,
-                       key1,
-                       ivp1,
-                       key2,
-                       ivp2,
-                       targs->quiet)) {
-               return 1;
-       }
-       appFreeCssmData(&iv1, CSSM_FALSE);
-       appFreeCssmData(&iv2, CSSM_FALSE);
-       cspFreeKey(targs->cspHand, key1);
-       cspFreeKey(targs->cspHand, key2);
-       CSSM_FREE(key1);
-       CSSM_FREE(key2);
-       return 0;
-}
-#endif
-
-int main(int argc, char **argv)
-{
-       int                                     arg;
-       char                            *argp;
-       unsigned                        loop;
-       CSSM_DATA                       ptext;
-       testArgs                        targs;
-       CSSM_DATA                       pwd;
-       CSSM_DATA                       salt;
-       privAlg                         pbeAlg;
-       privAlg                         encrAlg;
-       privAlg                         lastEncrAlg;
-       int                             rtn = 0;
-       CSSM_BOOL                       fooBool;
-       CSSM_BOOL                       refKeysOnly = CSSM_FALSE;
-       int                                     i;
-       
-       /*
-        * User-spec'd params
-        */
-       unsigned        loops = LOOPS_DEF;
-       CSSM_BOOL       quiet = CSSM_FALSE;
-       CSSM_BOOL       doPause = CSSM_FALSE;
-       CSSM_BOOL       doExport = CSSM_FALSE;
-       CSSM_BOOL       repeatOnly = CSSM_FALSE;
-       CSSM_BOOL       bareCsp = CSSM_TRUE;
-       CSSM_BOOL       zeroLenPassword = CSSM_FALSE;
-       
-       #if     macintosh
-       argc = ccommand(&argv);
-       #endif
-       for(arg=1; arg<argc; arg++) {
-               argp = argv[arg];
-               switch(argp[0]) {
-                   case 'l':
-                               loops = atoi(&argp[2]);
-                               break;
-                   case 'q':
-                       quiet = CSSM_TRUE;
-                               break;
-                       case 'D':
-                               bareCsp = CSSM_FALSE;
-                               #if CSPDL_ALL_KEYS_ARE_REF
-                               refKeysOnly = CSSM_TRUE;
-                               #endif
-                               break;
-                   case 'p':
-                       doPause = CSSM_TRUE;
-                               break;
-                       case 'e':
-                               doExport = CSSM_TRUE;
-                               break;
-                       case 'r':
-                               repeatOnly = CSSM_TRUE;
-                               break;
-                       case 'z':
-                               zeroLenPassword = CSSM_TRUE;
-                               break;
-                   case 'h':
-                   default:
-                               usage(argv);
-               }
-       }
-
-       /* statically allocate ptext, password and seed; data and length
-        * change in test loop */
-       pwd.Data = (uint8 *)CSSM_MALLOC(MAX_PASSWORD_SIZE);
-       ptext.Data = (uint8 *)CSSM_MALLOC(MAX_PTEXT_SIZE);
-       salt.Data = (uint8 *)CSSM_MALLOC(MAX_SALT_SIZE);
-       printf("Starting pbeTest; args: ");
-       for(i=1; i<argc; i++) {
-               printf("%s ", argv[i]);
-       }
-       printf("\n");
-       targs.cspHand = cspDlDbStartup(bareCsp, NULL);
-       if(targs.cspHand == 0) {
-               exit(1);
-       }
-       targs.ptext     = &ptext;
-       targs.password  = &pwd;
-       targs.salt              = &salt;
-       targs.quiet     = quiet;
-       if(doExport) {
-               lastEncrAlg = ENCR_ALG_LAST_EXPORT;
-       }
-       else {
-               lastEncrAlg = ENCR_ALG_LAST;
-       }
-       for(loop=1; ; loop++) {
-               if(!quiet) {
-                       printf("...loop %d\n", loop);
-               }
-               /* change once per outer loop */
-               simpleGenData(&ptext, MIN_PTEXT_SIZE, MAX_PTEXT_SIZE);
-               if(zeroLenPassword) {
-                       pwd.Length = 0; // fixed
-               }
-               else {
-                       simpleGenData(&pwd, APPLE_PBE_MIN_PASSWORD, MAX_PASSWORD_SIZE);
-               }
-               simpleGenData(&salt, APPLE_PBE_MIN_SALT, MAX_SALT_SIZE);
-               targs.iterCount = genRand(MIN_ITER_COUNT, MAX_ITER_COUNT);
-               if(refKeysOnly) {
-                       targs.useRefKey = CSSM_TRUE;
-               }
-               else {
-                       targs.useRefKey = (loop & 1) ? CSSM_FALSE : CSSM_TRUE;
-               }
-               
-               for(encrAlg=ENCR_ALG_FIRST; encrAlg<=lastEncrAlg; encrAlg++) {
-                       /* Cook up encryption-related args */
-                       algInfo(encrAlg,
-                               &targs.keyAlg,
-                               &targs.encrAlg,
-                               &targs.encrMode,
-                               &targs.encrPad,
-                               &targs.useInitVector,
-                               &targs.ivSize,
-                               &fooBool,                               // genInitVector
-                               &targs.keyAlgStr);
-                       /* random key size */
-                       targs.effectiveKeySizeInBits = randKeySizeBits(targs.keyAlg, OT_Encrypt);
-                       targs.keySizeInBits = (targs.effectiveKeySizeInBits + 7) & ~7;
-                       if(targs.keySizeInBits == targs.effectiveKeySizeInBits) {
-                               /* same size, ignore effective */
-                               targs.effectiveKeySizeInBits = 0;
-                       }
-                       if(!quiet) {
-                               printf("   ...Encrypt alg %s keySizeInBits %u effectKeySize %u\n",
-                                       targs.keyAlgStr, (unsigned)targs.keySizeInBits,
-                                       (unsigned)targs.effectiveKeySizeInBits);
-                       }
-                       for(pbeAlg=PBE_ALG_FIRST; pbeAlg<=PBE_ALG_LAST; pbeAlg++) {
-                               /* Cook up pbe-related args */
-                               uint32 foo;
-                               algInfo(pbeAlg,
-                                       &targs.deriveAlg,
-                                       &foo,                   // encrAlg
-                                       &foo,                   // mode
-                                       &foo,
-                                       &fooBool,               // useInitVector
-                                       &foo,                   // ivSize
-                                       &targs.genInitVector,
-                                       &targs.deriveAlgStr);
-                               if(!quiet) {
-                                       printf("      ...PBE alg %s\n", targs.deriveAlgStr);
-                               }
-                               /* grind thru the tests */
-                               if(repeatTest(&targs)) {
-                                       rtn = 1;
-                                       goto testDone;
-                               }
-                               if(repeatOnly) {
-                                       continue;
-                               }
-                               if(iterTest(&targs)) {
-                                       rtn = 1;
-                                       goto testDone;
-                               }
-                               #if 0
-                               // not supported yet 
-                               if(deriveAlgTest(&targs)) {
-                                       rtn = 1;
-                                       goto testDone;
-                               }
-                               #endif
-                               if(!zeroLenPassword) {
-                                       /* won't work with zero length password */
-                                       if(passwordTest(&targs)) {
-                                               rtn = 1;
-                                               goto testDone;
-                                       }
-                               }
-                               if(saltTest(&targs)) {
-                                       rtn = 1;
-                                       goto testDone;
-                               }
-                               if(targs.useInitVector) {
-                                       if(initVectTest(&targs)) {
-                                               rtn = 1;
-                                               goto testDone;
-                                       }
-                               }
-                       } /* for pbeAlg */
-               } /* for encrAlg */
-               if(doPause) {
-                       if(testError(quiet)) {
-                               break;
-                       }
-               }
-               if(loops && (loop == loops)) {
-                       break;
-               }
-       } /* for loop */
-       
-testDone:
-       CSSM_ModuleDetach(targs.cspHand);
-       if(!quiet && (rtn == 0)) {
-               printf("%s test complete\n", argv[0]);
-       }
-       return rtn;
-}