]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/utilLib/cspwrap.c
Security-57740.51.3.tar.gz
[apple/security.git] / SecurityTests / cspxutils / utilLib / cspwrap.c
diff --git a/SecurityTests/cspxutils/utilLib/cspwrap.c b/SecurityTests/cspxutils/utilLib/cspwrap.c
deleted file mode 100644 (file)
index 0a86659..0000000
+++ /dev/null
@@ -1,3279 +0,0 @@
-/* Copyright (c) 1997,2003-2006,2008,2010,2013 Apple Inc.
- *
- * cspwrap.c - wrappers to simplify access to CDSA
- *
- * Revision History
- * ----------------
- *   3 May 2000 Doug Mitchell
- *             Ported to X/CDSA2.
- *  12 Aug 1997        Doug Mitchell at Apple
- *             Created.
- */
-#include <Security/cssmapple.h>
-#include <Security/cssm.h>
-#include "cspwrap.h"
-#include "common.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-/* MCF hack */
-// #include <CarbonCore/MacTypes.h>
-#include <MacTypes.h>
-/* end MCF */
-
-#ifndef        NULL
-#define NULL ((void *)0)
-#endif /* NULL */
-#ifndef        MAX
-#define MAX(a,b)       ((a > b) ? a : b)
-#define MIN(a,b)       ((a < b) ? a : b)
-#endif
-
-#pragma mark --------- Key Generation ---------
-
-/*
- * Key generation
- */
-#define FEE_PRIV_DATA_SIZE     20
-/*
- * Debug/test only. BsafeCSP only (long since disabled, in Puma).
- * This results in quicker but less secure RSA key generation.
- */
-#define RSA_WEAK_KEYS          0
-
-/*
- * Force bad data in KeyData prior to generating, deriving, or
- * wrapping key to ensure that the CSP ignores incoming
- * KeyData.
- */
-static void setBadKeyData(
-       CSSM_KEY_PTR key)
-{
-       key->KeyData.Data = (uint8 *)0xeaaaeaaa;        // bad ptr
-       key->KeyData.Length = 1;        // no key can fit here
-}
-
-/*
- * Generate key pair of arbitrary algorithm. 
- * FEE keys will have random private data.
- */
-CSSM_RETURN cspGenKeyPair(CSSM_CSP_HANDLE cspHand,
-       uint32 algorithm,
-       const char *keyLabel,
-       unsigned keyLabelLen,
-       uint32 keySize,                                 // in bits
-       CSSM_KEY_PTR pubKey,                    // mallocd by caller
-       CSSM_BOOL pubIsRef,                             // true - reference key, false - data
-       uint32 pubKeyUsage,                             // CSSM_KEYUSE_ENCRYPT, etc.
-       CSSM_KEYBLOB_FORMAT pubFormat,  // Optional. Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE
-                                                                       //   to get the default format. 
-       CSSM_KEY_PTR privKey,                   // mallocd by caller
-       CSSM_BOOL privIsRef,                    // true - reference key, false - data
-       uint32 privKeyUsage,                    // CSSM_KEYUSE_DECRYPT, etc.
-       CSSM_KEYBLOB_FORMAT privFormat, // optional 0 ==> default
-       CSSM_BOOL genSeed)                              // FEE only. True: we generate seed and CSP
-                                                                       // will hash it. False: CSP generates random 
-                                                                       // seed. 
-{
-       CSSM_RETURN                             crtn;
-       CSSM_CC_HANDLE                  ccHand;
-       CSSM_DATA                               privData = {0, NULL};           // mallocd for FEE
-       CSSM_CRYPTO_DATA                privCData;
-       CSSM_CRYPTO_DATA_PTR    privCDataPtr = NULL;
-       CSSM_DATA                               keyLabelData;
-       uint32                                  pubAttr;
-       uint32                                  privAttr;
-       CSSM_RETURN                     ocrtn = CSSM_OK;
-       
-       if(keySize == CSP_KEY_SIZE_DEFAULT) {
-               keySize = cspDefaultKeySize(algorithm);
-       }
-       
-       /* pre-context-create algorithm-specific stuff */
-       switch(algorithm) {
-               case CSSM_ALGID_FEE:
-                       if(genSeed) {
-                               /* cook up random privData */
-                               privData.Data = (uint8 *)CSSM_MALLOC(FEE_PRIV_DATA_SIZE);
-                               privData.Length = FEE_PRIV_DATA_SIZE;
-                               appGetRandomBytes(privData.Data, FEE_PRIV_DATA_SIZE);
-                               privCData.Param = privData;
-                               privCData.Callback = NULL;
-                               privCDataPtr = &privCData;
-                       }
-                       /* else CSP generates random seed/key */
-                       break;
-               case CSSM_ALGID_RSA:
-                       break;
-               case CSSM_ALGID_DSA:
-                       break;
-               case CSSM_ALGID_ECDSA:
-                       break;
-               default:
-                       printf("cspGenKeyPair: Unknown algorithm\n");
-                       /* but what the hey */
-                       privCDataPtr = NULL;
-                       break;
-       }
-       keyLabelData.Data        = (uint8 *)keyLabel,
-       keyLabelData.Length      = keyLabelLen;
-       memset(pubKey, 0, sizeof(CSSM_KEY));
-       memset(privKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(pubKey);
-       setBadKeyData(privKey);
-       
-       crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
-               algorithm,
-               keySize,
-               privCDataPtr,                   // Seed
-               NULL,                                   // Salt
-               NULL,                                   // StartDate
-               NULL,                                   // EndDate
-               NULL,                                   // Params
-               &ccHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateKeyGenContext", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       /* cook up attribute bits */
-       if(pubIsRef) {
-               pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       if(privIsRef) {
-               privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-
-       /* post-context-create algorithm-specific stuff */
-       switch(algorithm) {
-               case CSSM_ALGID_RSA:
-               
-                       #if     RSA_WEAK_KEYS
-                       {
-                               /* for testing, speed up key gen by using the
-                               * undocumented "CUSTOM" key gen mode. This
-                               * results in the CSP using AI_RsaKeyGen instead of
-                               * AI_RSAStrongKeyGen.
-                               */
-                               crtn = AddContextAttribute(ccHand,
-                                       CSSM_ATTRIBUTE_MODE,
-                                       sizeof(uint32),         
-                                       CAT_Uint32,
-                                       NULL,
-                                       CSSM_ALGMODE_CUSTOM);
-                               if(crtn) {
-                                       printError("CSSM_UpdateContextAttributes", crtn);
-                                       return crtn;
-                               }
-                       }
-                       #endif  // RSA_WEAK_KEYS
-                       break;
-                
-                case CSSM_ALGID_DSA:
-                       /* 
-                        * extra step - generate params - this just adds some
-                        * info to the context
-                        */
-                       {
-                               CSSM_DATA dummy = {0, NULL};
-                               crtn = CSSM_GenerateAlgorithmParams(ccHand, 
-                                       keySize, &dummy);
-                               if(crtn) {
-                                       printError("CSSM_GenerateAlgorithmParams", crtn);
-                                       return crtn;
-                               }
-                               appFreeCssmData(&dummy, CSSM_FALSE);
-                       }
-                       break;
-               default:
-                       break;
-       }
-       
-       /* optional format specifiers */
-       if(!pubIsRef && (pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE)) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
-                       sizeof(uint32), 
-                       CAT_Uint32,
-                       NULL,
-                       pubFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-       if(!privIsRef && (privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE)) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT,
-                       sizeof(uint32),                 // currently sizeof CSSM_DATA
-                       CAT_Uint32,
-                       NULL,
-                       privFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-       crtn = CSSM_GenerateKeyPair(ccHand,
-               pubKeyUsage,
-               pubAttr,
-               &keyLabelData,
-               pubKey,
-               privKeyUsage,
-               privAttr,
-               &keyLabelData,                  // same labels
-               NULL,                                   // CredAndAclEntry
-               privKey);
-       if(crtn) {
-               printError("CSSM_GenerateKeyPair", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       /* basic checks...*/
-       if(privIsRef) {
-               if(privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("privKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(privKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("privKey blob type: exp raw, got %u\n",
-                                       (unsigned)privKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-       if(pubIsRef) {
-               if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("pubKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)pubKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(pubKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("pubKey blob type: exp raw or raw_berder, got %u\n",
-                                       (unsigned)pubKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-abort:
-       if(ccHand != 0) {
-               crtn = CSSM_DeleteContext(ccHand);
-               if(crtn) {
-                       printError("CSSM_DeleteContext", crtn);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-               }
-       }
-       if(privData.Data != NULL) {
-               CSSM_FREE(privData.Data);
-       }
-       return ocrtn;
-}
-
-/*
- * Generate FEE key pair with optional primeType, curveType, and seed (password) data.
- */
-CSSM_RETURN cspGenFEEKeyPair(CSSM_CSP_HANDLE cspHand,
-       const char *keyLabel,
-       unsigned keyLabelLen,
-       uint32 keySize,                                 // in bits
-       uint32 primeType,                               // CSSM_FEE_PRIME_TYPE_MERSENNE, etc.
-       uint32 curveType,                               // CSSM_FEE_CURVE_TYPE_MONTGOMERY, etc.
-       CSSM_KEY_PTR pubKey,                    // mallocd by caller
-       CSSM_BOOL pubIsRef,                             // true - reference key, false - data
-       uint32 pubKeyUsage,                             // CSSM_KEYUSE_ENCRYPT, etc.
-       CSSM_KEYBLOB_FORMAT pubFormat,  // Optional. Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE
-                                                                       //   to get the default format. 
-       CSSM_KEY_PTR privKey,                   // mallocd by caller
-       CSSM_BOOL privIsRef,                    // true - reference key, false - data
-       uint32 privKeyUsage,                    // CSSM_KEYUSE_DECRYPT, etc.
-       CSSM_KEYBLOB_FORMAT privFormat, // optional 0 ==> default
-       const CSSM_DATA *seedData)              // Present: CSP will hash this for private data.
-                                                                       // NULL: CSP generates random seed. 
-{
-       CSSM_RETURN                             crtn;
-       CSSM_CC_HANDLE                  ccHand;
-       CSSM_CRYPTO_DATA                privCData;
-       CSSM_CRYPTO_DATA_PTR    privCDataPtr = NULL;
-       CSSM_DATA                               keyLabelData;
-       uint32                                  pubAttr;
-       uint32                                  privAttr;
-       CSSM_RETURN                     ocrtn = CSSM_OK;
-       
-       /* pre-context-create algorithm-specific stuff */
-       if(seedData) {
-               privCData.Param = *((CSSM_DATA_PTR)seedData);
-               privCData.Callback = NULL;
-               privCDataPtr = &privCData;
-       }
-       /* else CSP generates random seed/key */
-       
-       if(keySize == CSP_KEY_SIZE_DEFAULT) {
-               keySize = CSP_FEE_KEY_SIZE_DEFAULT;
-       }
-
-       keyLabelData.Data        = (uint8 *)keyLabel,
-       keyLabelData.Length      = keyLabelLen;
-       memset(pubKey, 0, sizeof(CSSM_KEY));
-       memset(privKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(pubKey);
-       setBadKeyData(privKey);
-       
-       crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
-               CSSM_ALGID_FEE,
-               keySize,
-               privCDataPtr,                   // Seed
-               NULL,                                   // Salt
-               NULL,                                   // StartDate
-               NULL,                                   // EndDate
-               NULL,                                   // Params
-               &ccHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateKeyGenContext", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       /* cook up attribute bits */
-       if(pubIsRef) {
-               pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       if(privIsRef) {
-               privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-
-       /* optional post-context-create stuff */
-       if(primeType != CSSM_FEE_PRIME_TYPE_DEFAULT) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_FEE_PRIME_TYPE,
-                       sizeof(uint32),         
-                       CAT_Uint32,
-                       NULL,
-                       primeType);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_FEE_PRIME_TYPE)", crtn);
-                       return crtn;
-               }
-       }
-       if(curveType != CSSM_FEE_CURVE_TYPE_DEFAULT) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_FEE_CURVE_TYPE,
-                       sizeof(uint32),         
-                       CAT_Uint32,
-                       NULL,
-                       curveType);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_FEE_CURVE_TYPE)", crtn);
-                       return crtn;
-               }
-       }
-       
-       if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
-                       sizeof(uint32),         
-                       CAT_Uint32,
-                       NULL,
-                       pubFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-       if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT,
-                       sizeof(uint32),                 // currently sizeof CSSM_DATA
-                       CAT_Uint32,
-                       NULL,
-                       pubFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-       crtn = CSSM_GenerateKeyPair(ccHand,
-               pubKeyUsage,
-               pubAttr,
-               &keyLabelData,
-               pubKey,
-               privKeyUsage,
-               privAttr,
-               &keyLabelData,                  // same labels
-               NULL,                                   // CredAndAclEntry
-               privKey);
-       if(crtn) {
-               printError("CSSM_GenerateKeyPair", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       /* basic checks...*/
-       if(privIsRef) {
-               if(privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("privKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(privKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("privKey blob type: exp raw, got %u\n",
-                                       (unsigned)privKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-       if(pubIsRef) {
-               if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("pubKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)pubKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(pubKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("pubKey blob type: exp raw or raw_berder, got %u\n",
-                                       (unsigned)pubKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-abort:
-       if(ccHand != 0) {
-               crtn = CSSM_DeleteContext(ccHand);
-               if(crtn) {
-                       printError("CSSM_DeleteContext", crtn);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-               }
-       }
-       return ocrtn;
-}
-
-/*
- * Generate DSA key pair with optional generateAlgParams and optional
- * incoming parameters.
- */
-CSSM_RETURN cspGenDSAKeyPair(CSSM_CSP_HANDLE cspHand,
-       const char *keyLabel,
-       unsigned keyLabelLen,
-       uint32 keySize,                                 // in bits
-       CSSM_KEY_PTR pubKey,                    // mallocd by caller
-       CSSM_BOOL pubIsRef,                             // true - reference key, false - data
-       uint32 pubKeyUsage,                             // CSSM_KEYUSE_ENCRYPT, etc.
-       CSSM_KEYBLOB_FORMAT pubFormat,  // Optional. Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE
-                                                                       //   to get the default format. 
-       CSSM_KEY_PTR privKey,                   // mallocd by caller
-       CSSM_BOOL privIsRef,                    // true - reference key, false - data
-       uint32 privKeyUsage,                    // CSSM_KEYUSE_DECRYPT, etc.
-       CSSM_KEYBLOB_FORMAT privFormat, // Optional. Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE
-                                                                       //   to get the default format. 
-       CSSM_BOOL genParams,
-       CSSM_DATA_PTR paramData)                // optional     
-{
-       CSSM_RETURN                             crtn;
-       CSSM_CC_HANDLE                  ccHand;
-       CSSM_DATA                               keyLabelData;
-       uint32                                  pubAttr;
-       uint32                                  privAttr;
-       CSSM_RETURN                     ocrtn = CSSM_OK;
-       
-       if(keySize == CSP_KEY_SIZE_DEFAULT) {
-               keySize = CSP_DSA_KEY_SIZE_DEFAULT;
-       }
-       keyLabelData.Data        = (uint8 *)keyLabel,
-       keyLabelData.Length      = keyLabelLen;
-       memset(pubKey, 0, sizeof(CSSM_KEY));
-       memset(privKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(pubKey);
-       setBadKeyData(privKey);
-       
-       crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
-               CSSM_ALGID_DSA,
-               keySize,
-               NULL,                                   // Seed
-               NULL,                                   // Salt
-               NULL,                                   // StartDate
-               NULL,                                   // EndDate
-               paramData,
-               &ccHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateKeyGenContext", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       
-       /* cook up attribute bits */
-       if(pubIsRef) {
-               pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       if(privIsRef) {
-               privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-
-       if(genParams) {
-               /* 
-                * extra step - generate params - this just adds some
-                * info to the context
-                */
-               CSSM_DATA dummy = {0, NULL};
-               crtn = CSSM_GenerateAlgorithmParams(ccHand, 
-                       keySize, &dummy);
-               if(crtn) {
-                       printError("CSSM_GenerateAlgorithmParams", crtn);
-                       return crtn;
-               }
-               appFreeCssmData(&dummy, CSSM_FALSE);
-       }
-       
-       /* optional format specifiers */
-       if(!pubIsRef && (pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE)) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
-                       sizeof(uint32), 
-                       CAT_Uint32,
-                       NULL,
-                       pubFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-       if(!privIsRef && (privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE)) {
-               crtn = AddContextAttribute(ccHand,
-                       CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT,
-                       sizeof(uint32),                 // currently sizeof CSSM_DATA
-                       CAT_Uint32,
-                       NULL,
-                       privFormat);
-               if(crtn) {
-                       printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn);
-                       return crtn;
-               }
-       }
-
-       crtn = CSSM_GenerateKeyPair(ccHand,
-               pubKeyUsage,
-               pubAttr,
-               &keyLabelData,
-               pubKey,
-               privKeyUsage,
-               privAttr,
-               &keyLabelData,                  // same labels
-               NULL,                                   // CredAndAclEntry
-               privKey);
-       if(crtn) {
-               printError("CSSM_GenerateKeyPair", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       /* basic checks...*/
-       if(privIsRef) {
-               if(privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("privKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)privKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(privKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("privKey blob type: exp raw, got %u\n",
-                                       (unsigned)privKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-       if(pubIsRef) {
-               if(pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) {
-                       printf("pubKey blob type: exp %u got %u\n",
-                               CSSM_KEYBLOB_REFERENCE, (unsigned)pubKey->KeyHeader.BlobType);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                       goto abort;
-               }
-       }
-       else {
-               switch(pubKey->KeyHeader.BlobType) {
-                       case CSSM_KEYBLOB_RAW:
-                               break;
-                       default:
-                               printf("pubKey blob type: exp raw or raw_berder, got %u\n",
-                                       (unsigned)pubKey->KeyHeader.BlobType);
-                               ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-                               goto abort;
-               }
-       }
-abort:
-       if(ccHand != 0) {
-               crtn = CSSM_DeleteContext(ccHand);
-               if(crtn) {
-                       printError("CSSM_DeleteContext", crtn);
-                       ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
-               }
-       }
-       return ocrtn;
-}
-
-
-uint32 cspDefaultKeySize(uint32 alg)
-{
-       uint32 keySizeInBits;
-       switch(alg) {
-               case CSSM_ALGID_DES:
-                       keySizeInBits = CSP_DES_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_3DES_3KEY:
-               case CSSM_ALGID_DESX:
-                       keySizeInBits = CSP_DES3_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_RC2:
-                       keySizeInBits = CSP_RC2_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_RC4:
-                       keySizeInBits = CSP_RC4_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_RC5:
-                       keySizeInBits = CSP_RC5_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_ASC:
-                       keySizeInBits = CSP_ASC_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_BLOWFISH:
-                       keySizeInBits = CSP_BFISH_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_CAST:
-                       keySizeInBits = CSP_CAST_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_IDEA:
-                       keySizeInBits = CSP_IDEA_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_AES:
-                       keySizeInBits = CSP_AES_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_SHA1HMAC:
-                       keySizeInBits = CSP_HMAC_SHA_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_MD5HMAC:
-                       keySizeInBits = CSP_HMAC_MD5_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_FEE:
-                       keySizeInBits = CSP_FEE_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_RSA:
-                       keySizeInBits = CSP_RSA_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_DSA:
-                       keySizeInBits = CSP_DSA_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_ECDSA:
-                       keySizeInBits = CSP_ECDSA_KEY_SIZE_DEFAULT;
-                       break;
-               case CSSM_ALGID_NONE:
-                       keySizeInBits = CSP_NULL_CRYPT_KEY_SIZE_DEF;
-                       break;
-               default:
-                       printf("***cspDefaultKeySize: Unknown symmetric algorithm\n");
-                       keySizeInBits = 0;
-                       break;
-       }
-       return keySizeInBits;
-}
-
-/*
- * Create a random symmetric key.
- */
-CSSM_KEY_PTR cspGenSymKey(CSSM_CSP_HANDLE cspHand,
-               uint32                          alg,
-               const char                      *keyLabel,
-               unsigned                        keyLabelLen,
-               uint32                          keyUsage,               // CSSM_KEYUSE_ENCRYPT, etc.
-               uint32                          keySizeInBits,
-               CSSM_BOOL                       refKey)
-{
-       CSSM_KEY_PTR            symKey = (CSSM_KEY_PTR)CSSM_MALLOC(sizeof(CSSM_KEY));
-       CSSM_RETURN                     crtn;
-       CSSM_CC_HANDLE          ccHand;
-       uint32                          keyAttr;
-       CSSM_DATA                       dummyLabel;
-       
-       if(symKey == NULL) {
-               printf("Insufficient heap space\n");
-               return NULL;
-       }
-       memset(symKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(symKey);
-       if(keySizeInBits == CSP_KEY_SIZE_DEFAULT) {
-               keySizeInBits = cspDefaultKeySize(alg);
-       }
-       crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
-               alg,
-               keySizeInBits,  // keySizeInBits
-               NULL,                   // Seed
-               NULL,                   // Salt
-               NULL,                   // StartDate
-               NULL,                   // EndDate
-               NULL,                   // Params
-               &ccHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateKeyGenContext", crtn);
-               goto errorOut;
-       }
-       if(refKey) {
-               keyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       else {
-               keyAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE;
-       }
-       dummyLabel.Length = keyLabelLen;
-       dummyLabel.Data = (uint8 *)keyLabel;
-
-       crtn = CSSM_GenerateKey(ccHand,
-               keyUsage,
-               keyAttr,
-               &dummyLabel,
-               NULL,                   // ACL
-               symKey);
-       if(crtn) {
-               printError("CSSM_GenerateKey", crtn);
-               goto errorOut;
-       }
-       crtn = CSSM_DeleteContext(ccHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               goto errorOut;
-       }
-       return symKey;
-errorOut:
-       CSSM_FREE(symKey);
-       return NULL;
-}
-
-/*
- * Derive symmetric key.
- * Note in the X CSP, we never return an IV. 
- */
-CSSM_KEY_PTR cspDeriveKey(CSSM_CSP_HANDLE cspHand,
-               uint32                          deriveAlg,              // CSSM_ALGID_PKCS5_PBKDF2, etc.
-               uint32                          keyAlg,                 // CSSM_ALGID_RC5, etc.
-               const char                      *keyLabel,
-               unsigned                        keyLabelLen,
-               uint32                          keyUsage,               // CSSM_KEYUSE_ENCRYPT, etc.
-               uint32                          keySizeInBits,
-               CSSM_BOOL                       isRefKey,
-               CSSM_DATA_PTR           password,               // in PKCS-5 lingo
-               CSSM_DATA_PTR           salt,                   // ditto
-               uint32                          iterationCnt,   // ditto
-               CSSM_DATA_PTR           initVector)             // mallocd & RETURNED
-{
-       CSSM_KEY_PTR                            symKey = (CSSM_KEY_PTR)
-                                                                       CSSM_MALLOC(sizeof(CSSM_KEY));
-       CSSM_RETURN                                     crtn;
-       CSSM_CC_HANDLE                          ccHand;
-       uint32                                          keyAttr;
-       CSSM_DATA                                       dummyLabel;
-       CSSM_PKCS5_PBKDF2_PARAMS        pbeParams;
-       CSSM_DATA                                       pbeData;
-       CSSM_ACCESS_CREDENTIALS         creds;
-       
-       if(symKey == NULL) {
-               printf("Insufficient heap space\n");
-               return NULL;
-       }
-       memset(symKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(symKey);
-       memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-       if(keySizeInBits == CSP_KEY_SIZE_DEFAULT) {
-               keySizeInBits = cspDefaultKeySize(keyAlg);
-       }
-       crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
-               deriveAlg,
-               keyAlg,
-               keySizeInBits,
-               &creds,
-               NULL,                   // BaseKey
-               iterationCnt,
-               salt,
-               NULL,                   // seed
-               &ccHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateDeriveKeyContext", crtn);
-               goto errorOut;
-       }
-       keyAttr = CSSM_KEYATTR_EXTRACTABLE;
-       if(isRefKey) {
-               keyAttr |= (CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE);
-       }
-       else {
-               keyAttr |= CSSM_KEYATTR_RETURN_DATA;
-       }
-       dummyLabel.Length = keyLabelLen;
-       dummyLabel.Data = (uint8 *)keyLabel;
-       
-       /* passing in password is pretty strange....*/
-       pbeParams.Passphrase = *password;
-       pbeParams.PseudoRandomFunction = 
-                       CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
-       pbeData.Data = (uint8 *)&pbeParams;
-       pbeData.Length = sizeof(pbeParams);
-       crtn = CSSM_DeriveKey(ccHand,
-               &pbeData,
-               keyUsage,
-               keyAttr,
-               &dummyLabel,
-               NULL,                   // cred and acl
-               symKey);
-       if(crtn) {
-               printError("CSSM_DeriveKey", crtn);
-               goto errorOut;
-       }
-       /* copy IV back to caller */
-       /* Nope, not supported */
-       #if 0
-       if(pbeParams.InitVector.Data != NULL) {
-               if(initVector->Data != NULL) {
-                       if(initVector->Length < pbeParams.InitVector.Length) {
-                               printf("***Insufficient InitVector\n");
-                               goto errorOut;
-                       }
-               }
-               else {
-                       initVector->Data = 
-                               (uint8 *)CSSM_MALLOC(pbeParams.InitVector.Length);
-               }
-               memmove(initVector->Data, pbeParams.InitVector.Data,
-                               pbeParams.InitVector.Length);
-               initVector->Length = pbeParams.InitVector.Length;
-               CSSM_FREE(pbeParams.InitVector.Data);
-       }
-       else {
-               printf("***Warning: CSSM_DeriveKey, no InitVector\n");
-       }
-       #endif
-       crtn = CSSM_DeleteContext(ccHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               goto errorOut;
-       }
-       return symKey;
-errorOut:
-       CSSM_FREE(symKey);
-       return NULL;
-}
-
-/*
- * Cook up a symmetric key with specified key bits and other
- * params. Currently the CSPDL can only deal with reference keys except when
- * doing wrap/unwrap, so we manually cook up a raw key, then we null-unwrap it. 
- */
-CSSM_RETURN cspGenSymKeyWithBits(
-       CSSM_CSP_HANDLE         cspHand,
-       CSSM_ALGORITHMS         keyAlg,
-       CSSM_KEYUSE                     keyUsage,
-       const CSSM_DATA         *keyBits,
-       unsigned                        keySizeInBytes,
-       CSSM_KEY_PTR            refKey)                         // init'd and RETURNED
-{
-       CSSM_KEY                        rawKey;
-       CSSM_KEYHEADER_PTR      hdr = &rawKey.KeyHeader;
-       CSSM_RETURN                     crtn;
-       
-       /* set up a raw key the CSP will accept */
-       memset(&rawKey, 0, sizeof(CSSM_KEY));
-       hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
-       hdr->BlobType = CSSM_KEYBLOB_RAW;
-       hdr->Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
-       hdr->AlgorithmId = keyAlg;
-       hdr->KeyClass = CSSM_KEYCLASS_SESSION_KEY;
-       hdr->LogicalKeySizeInBits = keySizeInBytes * 8;
-       hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
-       hdr->KeyUsage = keyUsage;
-       appSetupCssmData(&rawKey.KeyData, keySizeInBytes);
-       memmove(rawKey.KeyData.Data, keyBits->Data, keySizeInBytes);
-       
-       /* convert to a ref key */
-       crtn = cspRawKeyToRef(cspHand, &rawKey, refKey);
-       appFreeCssmData(&rawKey.KeyData, CSSM_FALSE);
-       return crtn;
-}
-
-/*
- * Free a key. This frees a CSP's resources associated with the key if
- * the key is a reference key. It also frees key->KeyData. The CSSM_KEY
- * struct itself is not freed.
- * Note this has no effect on the CSP or DL cached keys unless the incoming
- * key is a reference key.
- */
-CSSM_RETURN    cspFreeKey(CSSM_CSP_HANDLE cspHand,
-       CSSM_KEY_PTR key)
-{
-       CSSM_RETURN crtn;
-       crtn = CSSM_FreeKey(cspHand, 
-               NULL,           // access cred
-               key,
-               CSSM_FALSE);    // delete - OK? maybe should parameterize?
-       if(crtn) {
-               printError("CSSM_FreeKey", crtn);
-       }
-       return crtn;
-}
-
-/* generate a random and reasonable key size in bits for specified CSSM algorithm */
-uint32 randKeySizeBits(uint32 alg, 
-       opType op)                      // OT_Encrypt, etc.
-{
-       uint32 minSize;
-       uint32 maxSize;
-       uint32 size;
-       
-       switch(alg) {
-               case CSSM_ALGID_DES:
-                       return CSP_DES_KEY_SIZE_DEFAULT;
-               case CSSM_ALGID_3DES_3KEY:
-               case CSSM_ALGID_DESX:
-                       return CSP_DES3_KEY_SIZE_DEFAULT;
-               case CSSM_ALGID_ASC:
-               case CSSM_ALGID_RC2:
-               case CSSM_ALGID_RC4:
-               case CSSM_ALGID_RC5:
-                       minSize = 5 * 8;
-                       maxSize = MAX_KEY_SIZE_RC245_BYTES * 8 ;        // somewhat arbitrary
-                       break;
-               case CSSM_ALGID_BLOWFISH:
-                       minSize = 32;
-                       maxSize = 448;
-                       break;
-               case CSSM_ALGID_CAST:
-                       minSize = 40;
-                       maxSize = 128;
-                       break;
-               case CSSM_ALGID_IDEA:
-                       return CSP_IDEA_KEY_SIZE_DEFAULT;
-               case CSSM_ALGID_RSA:
-                       minSize = CSP_RSA_KEY_SIZE_DEFAULT;
-                       maxSize = 1024;
-                       break;
-               case CSSM_ALGID_DSA:
-                       /* signature only, no export restriction */
-                       minSize = 512;
-                       maxSize = 1024;
-                       break;
-               case CSSM_ALGID_SHA1HMAC:
-                       minSize = 20 * 8;
-                       maxSize = 256 * 8;
-                       break;
-               case CSSM_ALGID_MD5HMAC:
-                       minSize = 16 * 8;
-                       maxSize = 256 * 8;
-                       break;
-               case CSSM_ALGID_FEE:
-                       /* FEE requires discrete sizes */
-                       size = genRand(1,4);
-                       switch(size) {
-                               case 1:
-                                       return 31;
-                               case 2:
-                                       if(alg == CSSM_ALGID_FEE) {
-                                               return 127;
-                                       }
-                                       else {
-                                               return 128;
-                                       }
-                               case 3:
-                                       return 161;
-                               case 4:
-                                       return 192;
-                               default:
-                                       printf("randKeySizeBits: internal error\n");
-                                       return 0;
-                       }
-               case CSSM_ALGID_ECDSA:
-               case CSSM_ALGID_SHA1WithECDSA:
-                       /* ECDSA require discrete sizes */
-                       size = genRand(1,4);
-                       switch(size) {
-                               case 1:
-                                       return 192;
-                               case 2:
-                                       return 256;
-                               case 3:
-                                       return 384;
-                               case 4:
-                               default:
-                                       return 521;
-                       }
-               case CSSM_ALGID_AES:
-                       size = genRand(1, 3);
-                       switch(size) {
-                               case 1:
-                                       return 128;
-                               case 2:
-                                       return 192;
-                               case 3:
-                                       return 256;
-                       }
-               case CSSM_ALGID_NONE:
-                       return CSP_NULL_CRYPT_KEY_SIZE_DEF;
-               default:
-                       printf("randKeySizeBits: unknown alg\n");
-                       return CSP_KEY_SIZE_DEFAULT;
-       }
-       size = genRand(minSize, maxSize);
-       
-       /* per-alg postprocessing.... */
-       if(alg != CSSM_ALGID_RC2) {
-               size &= ~0x7;
-       }
-       switch(alg) {
-               case CSSM_ALGID_RSA:
-                       // new for X - strong keys */
-                       size &= ~(16 - 1);
-                       break;
-               case CSSM_ALGID_DSA:
-                       /* size mod 64 == 0 */
-                       size &= ~(64 - 1);
-                       break;
-               default:
-                       break;
-       }
-       return size;
-}
-
-#pragma mark --------- Encrypt/Decrypt ---------
-
-/*
- * Encrypt/Decrypt
- */
-/*
- * Common routine for encrypt/decrypt - cook up an appropriate context handle
- */
-/*
- * When true, effectiveKeySizeInBits is passed down via the Params argument.
- * Otherwise, we add a customized context attribute.
- * Setting this true works with the stock Intel CSSM; this may well change.
- * Note this overloading prevent us from specifying RC5 rounds....
- */
-#define EFFECTIVE_SIZE_VIA_PARAMS              0
-CSSM_CC_HANDLE genCryptHandle(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEED, etc.
-               uint32 mode,                                            // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
-               CSSM_PADDING padding,                           // CSSM_PADDING_PKCS1, etc. 
-               const CSSM_KEY *key0,
-               const CSSM_KEY *key1,                           // for CSSM_ALGID_FEED only - must be the 
-                                                                                       // public key
-               const CSSM_DATA *iv,                            // optional
-               uint32 effectiveKeySizeInBits,          // 0 means skip this attribute
-               uint32 rounds)                                          // ditto
-{
-       CSSM_CC_HANDLE cryptHand = 0;
-       uint32 params;
-       CSSM_RETURN crtn;
-       CSSM_ACCESS_CREDENTIALS creds;
-       
-       memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-       #if     EFFECTIVE_SIZE_VIA_PARAMS
-       params = effectiveKeySizeInBits;
-       #else
-       params = 0;
-       #endif
-       switch(algorithm) {
-               case CSSM_ALGID_DES:
-               case CSSM_ALGID_3DES_3KEY_EDE:
-               case CSSM_ALGID_DESX:
-               case CSSM_ALGID_ASC:
-               case CSSM_ALGID_RC2:
-               case CSSM_ALGID_RC4:
-               case CSSM_ALGID_RC5:
-               case CSSM_ALGID_AES:
-               case CSSM_ALGID_BLOWFISH:
-               case CSSM_ALGID_CAST:
-               case CSSM_ALGID_IDEA:
-               case CSSM_ALGID_NONE:           // used for wrapKey()
-                       crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
-                               algorithm,
-                               mode,
-                               NULL,                   // access cred
-                               key0,
-                               iv,                             // InitVector
-                               padding,        
-                               NULL,                   // Params
-                               &cryptHand);
-                       if(crtn) {
-                               printError("CSSM_CSP_CreateSymmetricContext", crtn);
-                               return 0;
-                       }
-                       break;
-               case CSSM_ALGID_FEED:
-               case CSSM_ALGID_FEEDEXP:
-               case CSSM_ALGID_FEECFILE:
-               case CSSM_ALGID_RSA:
-                        crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
-                               algorithm,
-                               &creds,                 // access
-                               key0,
-                               padding,
-                               &cryptHand);
-                       if(crtn) {
-                               printError("CSSM_CSP_CreateAsymmetricContext", crtn);
-                               return 0;
-                       }
-                       if(key1 != NULL) {
-                               /*
-                                * FEED, some CFILE. Add (non-standard) second key attribute.
-                                */
-                               crtn = AddContextAttribute(cryptHand,
-                                               CSSM_ATTRIBUTE_PUBLIC_KEY,
-                                               sizeof(CSSM_KEY),                       // currently sizeof CSSM_DATA
-                                               CAT_Ptr,
-                                               key1,
-                                               0);
-                               if(crtn) {
-                                       printError("AddContextAttribute", crtn);
-                                       return 0;
-                               }
-                       }
-                       if(mode != CSSM_ALGMODE_NONE) {
-                               /* special case, e.g., CSSM_ALGMODE_PUBLIC_KEY */
-                               crtn = AddContextAttribute(cryptHand,
-                                               CSSM_ATTRIBUTE_MODE,
-                                               sizeof(uint32),
-                                               CAT_Uint32,
-                                               NULL,
-                                               mode);
-                               if(crtn) {
-                                       printError("AddContextAttribute", crtn);
-                                       return 0;
-                               }
-                       }
-                       break;
-               default:
-                       printf("genCryptHandle: bogus algorithm\n");
-                       return 0;
-       }
-       #if             !EFFECTIVE_SIZE_VIA_PARAMS
-       /* add optional EffectiveKeySizeInBits and rounds attributes */
-       if(effectiveKeySizeInBits != 0) {
-               CSSM_CONTEXT_ATTRIBUTE attr;
-               attr.AttributeType = CSSM_ATTRIBUTE_EFFECTIVE_BITS;
-               attr.AttributeLength = sizeof(uint32);
-               attr.Attribute.Uint32 = effectiveKeySizeInBits;
-               crtn = CSSM_UpdateContextAttributes(
-                       cryptHand,
-                       1,
-                       &attr);
-               if(crtn) {
-                       printError("CSSM_UpdateContextAttributes", crtn);
-                       return crtn;
-               }
-       }
-       #endif
-       
-       if(rounds != 0) {
-               CSSM_CONTEXT_ATTRIBUTE attr;
-               attr.AttributeType = CSSM_ATTRIBUTE_ROUNDS;
-               attr.AttributeLength = sizeof(uint32);
-               attr.Attribute.Uint32 = rounds;
-               crtn = CSSM_UpdateContextAttributes(
-                       cryptHand,
-                       1,
-                       &attr);
-               if(crtn) {
-                       printError("CSSM_UpdateContextAttributes", crtn);
-                       return crtn;
-               }
-       }
-
-       return cryptHand;
-}
-
-CSSM_RETURN cspEncrypt(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEED, etc.
-               uint32 mode,                                            // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
-               CSSM_PADDING padding,                           // CSSM_PADDING_PKCS1, etc. 
-               const CSSM_KEY *key,                            // public or session key
-               const CSSM_KEY *pubKey,                         // for CSSM_ALGID_FEED, CSSM_ALGID_FEECFILE only
-               uint32 effectiveKeySizeInBits,          // 0 means skip this attribute
-               uint32 rounds,                                          // ditto
-               const CSSM_DATA *iv,                            // init vector, optional
-               const CSSM_DATA *ptext,
-               CSSM_DATA_PTR ctext,                            // RETURNED
-               CSSM_BOOL mallocCtext)                          // if true, and ctext empty, malloc
-                                                                                       // by getting size from CSP
-{
-       CSSM_CC_HANDLE  cryptHand;
-       CSSM_RETURN             crtn;
-       CSSM_SIZE               bytesEncrypted;
-       CSSM_DATA               remData = {0, NULL};
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                origCtextLen;                   // the amount we malloc, if any
-       CSSM_RETURN             savedErr = CSSM_OK;
-       CSSM_BOOL               restoreErr = CSSM_FALSE;
-       
-       cryptHand = genCryptHandle(cspHand, 
-               algorithm, 
-               mode, 
-               padding,
-               key, 
-               pubKey, 
-               iv, 
-               effectiveKeySizeInBits,
-               rounds);
-       if(cryptHand == 0) {
-               return CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       if(mallocCtext && (ctext->Length == 0)) {
-               CSSM_QUERY_SIZE_DATA querySize;
-               querySize.SizeInputBlock = ptext->Length;
-               crtn = CSSM_QuerySize(cryptHand,
-                       CSSM_TRUE,                                              // encrypt
-                       1,
-                       &querySize);
-               if(crtn) {
-                       printError("CSSM_QuerySize", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(querySize.SizeOutputBlock == 0) {
-                       /* CSP couldn't figure this out; skip our malloc */
-                       printf("***cspEncrypt: warning: cipherTextSize unknown; "
-                               "skipping malloc\n");
-                       origCtextLen = 0;
-               }
-               else {
-                       ctext->Data = (uint8 *)
-                               appMalloc(querySize.SizeOutputBlock, NULL);
-                       if(ctext->Data == NULL) {
-                               printf("Insufficient heap space\n");
-                               ocrtn = CSSM_ERRCODE_MEMORY_ERROR;
-                               goto abort;
-                       }
-                       ctext->Length = origCtextLen = querySize.SizeOutputBlock;
-                       memset(ctext->Data, 0, ctext->Length);
-               }
-       }
-       else {
-               origCtextLen = ctext->Length;
-       }
-       crtn = CSSM_EncryptData(cryptHand,
-               ptext,
-               1,
-               ctext,
-               1,
-               &bytesEncrypted,
-               &remData);
-       if(crtn == CSSM_OK) {
-               /*
-                * Deal with remData - its contents are included in bytesEncrypted.
-                */
-               if((remData.Length != 0) && mallocCtext) {
-                       /* shouldn't happen - right? */
-                       if(bytesEncrypted > origCtextLen) {
-                               /* malloc and copy a new one */
-                               uint8 *newCdata = (uint8 *)appMalloc(bytesEncrypted, NULL);
-                               printf("**Warning: app malloced cipherBuf, but got nonzero "
-                                       "remData!\n");
-                               if(newCdata == NULL) {
-                                       printf("Insufficient heap space\n");
-                                       ocrtn = CSSM_ERRCODE_MEMORY_ERROR;
-                                       goto abort;
-                               }
-                               memmove(newCdata, ctext->Data, ctext->Length);
-                               memmove(newCdata+ctext->Length, remData.Data, remData.Length);
-                               CSSM_FREE(ctext->Data);
-                               ctext->Data = newCdata;
-                       }
-                       else {
-                               /* there's room left over */
-                               memmove(ctext->Data+ctext->Length, remData.Data, remData.Length);
-                       }
-                       ctext->Length = bytesEncrypted;
-               }
-               // NOTE: We return the proper length in ctext....
-               ctext->Length = bytesEncrypted;
-       }
-       else {
-               savedErr = crtn;
-               restoreErr = CSSM_TRUE;
-               printError("CSSM_EncryptData", crtn);
-       }
-abort:
-       crtn = CSSM_DeleteContext(cryptHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       if(restoreErr) {
-               ocrtn = savedErr;
-       }
-       return ocrtn;
-}
-
-#define PAD_IMPLIES_RAND_PTEXTSIZE     1
-#define LOG_STAGED_OPS                         0
-#if            LOG_STAGED_OPS
-#define soprintf(s)    printf s
-#else
-#define soprintf(s)
-#endif
-
-CSSM_RETURN cspStagedEncrypt(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEED, etc.
-               uint32 mode,                                            // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
-               CSSM_PADDING padding,                           // CSSM_PADDING_PKCS1, etc. 
-               const CSSM_KEY *key,                            // public or session key
-               const CSSM_KEY *pubKey,                         // for CSSM_ALGID_FEED, CSSM_ALGID_FEECFILE only
-               uint32 effectiveKeySizeInBits,          // 0 means skip this attribute
-               uint32 cipherBlockSize,                         // ditto
-               uint32 rounds,                                          // ditto
-               const CSSM_DATA *iv,                            // init vector, optional
-               const CSSM_DATA *ptext,
-               CSSM_DATA_PTR ctext,                            // RETURNED, we malloc
-               CSSM_BOOL multiUpdates)                         // false:single update, true:multi updates
-{
-       CSSM_CC_HANDLE  cryptHand;
-       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               ctextWork;                              // per update, mallocd by CSP
-       CSSM_QUERY_SIZE_DATA querySize;
-       uint8                   *origCtext;                             // initial ctext->Data
-       unsigned                origCtextLen;                   // amount we mallocd
-       CSSM_BOOL               restoreErr = CSSM_FALSE;
-       CSSM_RETURN             savedErr = CSSM_OK;
-       
-       
-       cryptHand = genCryptHandle(cspHand, 
-               algorithm, 
-               mode, 
-               padding,
-               key, 
-               pubKey, 
-               iv,
-               effectiveKeySizeInBits,
-               rounds);
-       if(cryptHand == 0) {
-               return CSSMERR_CSP_INTERNAL_ERROR;
-       }
-       if(cipherBlockSize) {
-               crtn = AddContextAttribute(cryptHand,
-                       CSSM_ATTRIBUTE_BLOCK_SIZE,
-                       sizeof(uint32),
-                       CAT_Uint32,
-                       NULL,
-                       cipherBlockSize);
-               if(crtn) {
-                       printError("CSSM_UpdateContextAttributes", crtn);
-                       goto abort;
-               }
-       }
-       
-       /* obtain total required ciphertext size and block size */
-       querySize.SizeInputBlock = ptext->Length;
-       crtn = CSSM_QuerySize(cryptHand,
-               CSSM_TRUE,                                              // encrypt
-               1,
-               &querySize);
-       if(crtn) {
-               printError("CSSM_QuerySize(1)", crtn);
-               ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-               goto abort;
-       }
-       if(querySize.SizeOutputBlock == 0) {
-               /* CSP couldn't figure this out; skip our malloc - caller is taking its
-                * chances */
-               printf("***cspStagedEncrypt: warning: cipherTextSize unknown; aborting\n");
-               ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-               goto abort;
-       }
-       else {
-               origCtextLen = querySize.SizeOutputBlock;
-               if(algorithm == CSSM_ALGID_ASC) {
-                       /* ASC is weird - the more chunks we do, the bigger the
-                        * resulting ctext...*/
-                       origCtextLen *= 2;
-               }
-               ctext->Length = origCtextLen;
-               ctext->Data   = origCtext = (uint8 *)appMalloc(origCtextLen, NULL);
-               if(ctext->Data == NULL) {
-                       printf("Insufficient heap space\n");
-                       ocrtn = CSSMERR_CSP_MEMORY_ERROR;
-                       goto abort;
-               }
-               memset(ctext->Data, 0, ctext->Length);
-       }
-
-       crtn = CSSM_EncryptDataInit(cryptHand);
-       if(crtn) {
-               printError("CSSM_EncryptDataInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       
-       toMove = ptext->Length;
-       thisPtext.Data = ptext->Data;
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       /* just do one pass thru this loop */
-                       thisMove = toMove;
-               }
-               thisPtext.Length = thisMove;
-               /* let CSP do the individual mallocs */
-               ctextWork.Data = NULL;
-               ctextWork.Length = 0;
-               soprintf(("*** EncryptDataUpdate: ptextLen 0x%x\n", thisMove));
-               crtn = CSSM_EncryptDataUpdate(cryptHand,
-                       &thisPtext,
-                       1,
-                       &ctextWork,
-                       1,
-                       &bytesEncrypted);
-               if(crtn) {
-                       printError("CSSM_EncryptDataUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               // NOTE: We return the proper length in ctext....
-               ctextWork.Length = bytesEncrypted;
-               soprintf(("*** EncryptDataUpdate: ptextLen 0x%x  bytesEncrypted 0x%x\n",
-                       thisMove, bytesEncrypted));
-               thisPtext.Data += thisMove;
-               toMove         -= thisMove;
-               if(bytesEncrypted > ctext->Length) {
-                       printf("cspStagedEncrypt: ctext overflow!\n");
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(bytesEncrypted != 0) {
-                       memmove(ctext->Data, ctextWork.Data, bytesEncrypted);
-                       bytesEncryptedTotal += bytesEncrypted;
-                       ctext->Data         += bytesEncrypted;
-                       ctext->Length       -= bytesEncrypted;
-               }
-               if(ctextWork.Data != NULL) {
-                       CSSM_FREE(ctextWork.Data);
-               }
-       }
-       /* OK, one more */
-       ctextWork.Data = NULL;
-       ctextWork.Length = 0;
-       crtn = CSSM_EncryptDataFinal(cryptHand, &ctextWork);
-       if(crtn) {
-               printError("CSSM_EncryptDataFinal", crtn);
-               savedErr = crtn;
-               restoreErr = CSSM_TRUE;
-               goto abort;
-       }
-       if(ctextWork.Length != 0) {
-               bytesEncryptedTotal += ctextWork.Length;
-               if(ctextWork.Length > ctext->Length) {
-                       printf("cspStagedEncrypt: ctext overflow (2)!\n");
-                       ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-                       goto abort;
-               }
-               memmove(ctext->Data, ctextWork.Data, ctextWork.Length);
-       }
-       if(ctextWork.Data) {
-               /* this could have gotten mallocd and Length still be zero */
-               CSSM_FREE(ctextWork.Data);
-       }
-
-       /* retweeze ctext */
-       ctext->Data   = origCtext;
-       ctext->Length = bytesEncryptedTotal;
-abort:
-       crtn = CSSM_DeleteContext(cryptHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       if(restoreErr) {
-               /* give caller the error from the encrypt */
-               ocrtn = savedErr;
-       }
-       return ocrtn;
-}
-
-CSSM_RETURN cspDecrypt(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEED, etc.
-               uint32 mode,                                            // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
-               CSSM_PADDING padding,                           // CSSM_PADDING_PKCS1, etc. 
-               const CSSM_KEY *key,                            // public or session key
-               const CSSM_KEY *pubKey,                         // for CSSM_ALGID_FEED, CSSM_ALGID_FEECFILE only
-               uint32 effectiveKeySizeInBits,          // 0 means skip this attribute
-               uint32 rounds,                                          // ditto
-               const CSSM_DATA *iv,                            // init vector, optional
-               const CSSM_DATA *ctext,
-               CSSM_DATA_PTR ptext,                            // RETURNED
-               CSSM_BOOL mallocPtext)                          // if true and ptext->Length = 0,
-                                                                                       //   we'll malloc
-{
-       CSSM_CC_HANDLE  cryptHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       CSSM_SIZE               bytesDecrypted;
-       CSSM_DATA               remData = {0, NULL};
-       unsigned                origPtextLen;                   // the amount we malloc, if any
-
-       cryptHand = genCryptHandle(cspHand, 
-               algorithm, 
-               mode, 
-               padding,
-               key, 
-               pubKey, 
-               iv,
-               effectiveKeySizeInBits,
-               rounds);
-       if(cryptHand == 0) {
-               return CSSMERR_CSP_INTERNAL_ERROR;
-       }
-       if(mallocPtext && (ptext->Length == 0)) {
-               CSSM_QUERY_SIZE_DATA querySize;
-               querySize.SizeInputBlock = ctext->Length;
-               crtn = CSSM_QuerySize(cryptHand,
-                       CSSM_FALSE,                                             // encrypt
-                       1,
-                       &querySize);
-               if(crtn) {
-                       printError("CSSM_QuerySize", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(querySize.SizeOutputBlock == 0) {
-                       /* CSP couldn't figure this one out; skip our malloc */
-                       printf("***cspDecrypt: warning: plainTextSize unknown; "
-                               "skipping malloc\n");
-                       origPtextLen = 0;
-               }
-               else {
-                       ptext->Data = 
-                               (uint8 *)appMalloc(querySize.SizeOutputBlock, NULL);
-                       if(ptext->Data == NULL) {
-                               printf("Insufficient heap space\n");
-                               ocrtn = CSSMERR_CSP_MEMORY_ERROR;
-                               goto abort;
-                       }
-                       ptext->Length = origPtextLen = querySize.SizeOutputBlock;
-                       memset(ptext->Data, 0, ptext->Length);
-               }
-       }
-       else {
-               origPtextLen = ptext->Length;
-       }
-       crtn = CSSM_DecryptData(cryptHand,
-               ctext,
-               1,
-               ptext,
-               1,
-               &bytesDecrypted,
-               &remData);
-       if(crtn == CSSM_OK) {
-               /*
-                * Deal with remData - its contents are included in bytesDecrypted.
-                */
-               if((remData.Length != 0) && mallocPtext) {
-                       /* shouldn't happen - right? */
-                       if(bytesDecrypted > origPtextLen) {
-                               /* malloc and copy a new one */
-                               uint8 *newPdata = (uint8 *)appMalloc(bytesDecrypted, NULL);
-                               printf("**Warning: app malloced ClearBuf, but got nonzero "
-                                       "remData!\n");
-                               if(newPdata == NULL) {
-                                       printf("Insufficient heap space\n");
-                                       ocrtn = CSSMERR_CSP_MEMORY_ERROR;
-                                       goto abort;
-                               }
-                               memmove(newPdata, ptext->Data, ptext->Length);
-                               memmove(newPdata + ptext->Length,
-                                       remData.Data, remData.Length);
-                               CSSM_FREE(ptext->Data);
-                               ptext->Data = newPdata;
-                       }
-                       else {
-                               /* there's room left over */
-                               memmove(ptext->Data + ptext->Length,
-                                       remData.Data, remData.Length);
-                       }
-                       ptext->Length = bytesDecrypted;
-               }
-               // NOTE: We return the proper length in ptext....
-               ptext->Length = bytesDecrypted;
-               
-               // FIXME - sometimes get mallocd RemData here, but never any valid data
-               // there...side effect of CSPFullPluginSession's buffer handling logic;
-               // but will we ever actually see valid data in RemData? So far we never
-               // have....
-               if(remData.Data != NULL) {
-                       appFree(remData.Data, NULL);
-               }
-       }
-       else {
-               printError("CSSM_DecryptData", crtn);
-               ocrtn = crtn;
-       }
-abort:
-       crtn = CSSM_DeleteContext(cryptHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-CSSM_RETURN cspStagedDecrypt(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEED, etc.
-               uint32 mode,                                            // CSSM_ALGMODE_CBC, etc. - only for symmetric algs
-               CSSM_PADDING padding,                           // CSSM_PADDING_PKCS1, etc. 
-               const CSSM_KEY *key,                            // public or session key
-               const CSSM_KEY *pubKey,                         // for CSSM_ALGID_FEED, CSSM_ALGID_FEECFILE only
-               uint32 effectiveKeySizeInBits,          // 0 means skip this attribute
-               uint32 cipherBlockSize,                         // ditto
-               uint32 rounds,                                          // ditto
-               const CSSM_DATA *iv,                            // init vector, optional
-               const CSSM_DATA *ctext,
-               CSSM_DATA_PTR ptext,                            // RETURNED, we malloc
-               CSSM_BOOL multiUpdates)                         // false:single update, true:multi updates
-{
-       CSSM_CC_HANDLE  cryptHand;
-       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 encrypt on this update
-       CSSM_DATA               thisCtext;                              // running ptr into ptext
-       CSSM_DATA               ptextWork;                              // per update, mallocd by CSP
-       CSSM_QUERY_SIZE_DATA querySize;
-       uint8                   *origPtext;                             // initial ptext->Data
-       unsigned                origPtextLen;                   // amount we mallocd
-       
-       cryptHand = genCryptHandle(cspHand, 
-               algorithm, 
-               mode, 
-               padding,
-               key, 
-               pubKey, 
-               iv,
-               effectiveKeySizeInBits,
-               rounds);
-       if(cryptHand == 0) {
-               return CSSMERR_CSP_INTERNAL_ERROR;
-       }
-       if(cipherBlockSize) {
-               crtn = AddContextAttribute(cryptHand,
-                       CSSM_ATTRIBUTE_BLOCK_SIZE,
-                       sizeof(uint32),
-                       CAT_Uint32,
-                       NULL,
-                       cipherBlockSize);
-               if(crtn) {
-                       printError("CSSM_UpdateContextAttributes", crtn);
-                       goto abort;
-               }
-       }
-       
-       /* obtain total required ciphertext size and block size */
-       querySize.SizeInputBlock = ctext->Length;
-       crtn = CSSM_QuerySize(cryptHand,
-               CSSM_FALSE,                                             // encrypt
-               1,
-               &querySize);
-       if(crtn) {
-               printError("CSSM_QuerySize(1)", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       
-       /* required ptext size should be independent of number of chunks */
-       if(querySize.SizeOutputBlock == 0) {
-               printf("***warning: cspStagedDecrypt: plainTextSize unknown; aborting\n");
-               ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-               goto abort;
-       }
-       else {
-               // until exit, ptext->Length indicates remaining bytes of usable data in
-               // ptext->Data
-               ptext->Length = origPtextLen = querySize.SizeOutputBlock;
-               ptext->Data   = origPtext    = 
-                       (uint8 *)appMalloc(origPtextLen, NULL);
-               if(ptext->Data == NULL) {
-                       printf("Insufficient heap space\n");
-                       ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-                       goto abort;
-               }
-               memset(ptext->Data, 0, ptext->Length);
-       }
-       
-       crtn = CSSM_DecryptDataInit(cryptHand);
-       if(crtn) {
-               printError("CSSM_DecryptDataInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = ctext->Length;
-       thisCtext.Data = ctext->Data;
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       /* just do one pass thru this loop */
-                       thisMove = toMove;
-               }
-               thisCtext.Length = thisMove;
-               /* let CSP do the individual mallocs */
-               ptextWork.Data = NULL;
-               ptextWork.Length = 0;
-               soprintf(("*** DecryptDataUpdate: ctextLen 0x%x\n", thisMove));
-               crtn = CSSM_DecryptDataUpdate(cryptHand,
-                       &thisCtext,
-                       1,
-                       &ptextWork,
-                       1,
-                       &bytesDecrypted);
-               if(crtn) {
-                       printError("CSSM_DecryptDataUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               //
-               // NOTE: We return the proper length in ptext....
-               ptextWork.Length = bytesDecrypted;
-               thisCtext.Data += thisMove;
-               toMove         -= thisMove;
-               if(bytesDecrypted > ptext->Length) {
-                       printf("cspStagedDecrypt: ptext overflow!\n");
-                       ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-                       goto abort;
-               }
-               if(bytesDecrypted != 0) {
-                       memmove(ptext->Data, ptextWork.Data, bytesDecrypted);
-                       bytesDecryptedTotal += bytesDecrypted;
-                       ptext->Data         += bytesDecrypted;
-                       ptext->Length       -= bytesDecrypted;
-               }
-               if(ptextWork.Data != NULL) {
-                       CSSM_FREE(ptextWork.Data);
-               }
-       }
-       /* OK, one more */
-       ptextWork.Data = NULL;
-       ptextWork.Length = 0;
-       crtn = CSSM_DecryptDataFinal(cryptHand, &ptextWork);
-       if(crtn) {
-               printError("CSSM_DecryptDataFinal", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       if(ptextWork.Length != 0) {
-               bytesDecryptedTotal += ptextWork.Length;
-               if(ptextWork.Length > ptext->Length) {
-                       printf("cspStagedDecrypt: ptext overflow (2)!\n");
-                       ocrtn = CSSMERR_CSP_INTERNAL_ERROR;
-                       goto abort;
-               }
-               memmove(ptext->Data, ptextWork.Data, ptextWork.Length);
-       }
-       if(ptextWork.Data) {
-               /* this could have gotten mallocd and Length still be zero */
-               CSSM_FREE(ptextWork.Data);
-       }
-       
-       /* retweeze ptext */
-       ptext->Data   = origPtext;
-       ptext->Length = bytesDecryptedTotal;
-abort:
-       crtn = CSSM_DeleteContext(cryptHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-#pragma mark --------- sign/verify/MAC ---------
-
-/*
- * Signature routines
- * This all-in-one sign op has a special case for RSA keys. If the requested
- * alg is MD5 or SHA1, we'll do a manual digest op followed by raw RSA sign. 
- * Likewise, if it's CSSM_ALGID_DSA, we'll do manual SHA1 digest followed by 
- * raw DSA sign.
- */
-
-CSSM_RETURN cspSign(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // private key
-               const CSSM_DATA *text,
-               CSSM_DATA_PTR sig)                                      // RETURNED
-{
-       CSSM_CC_HANDLE  sigHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       const CSSM_DATA *ptext;
-       CSSM_DATA               digest = {0, NULL};
-       CSSM_ALGORITHMS digestAlg = CSSM_ALGID_NONE;
-
-       /* handle special cases for raw sign */
-       switch(algorithm) {
-               case CSSM_ALGID_SHA1:
-                       digestAlg = CSSM_ALGID_SHA1;
-                       algorithm = CSSM_ALGID_RSA;
-                       break;
-               case CSSM_ALGID_MD5:
-                       digestAlg = CSSM_ALGID_MD5;
-                       algorithm = CSSM_ALGID_RSA;
-                       break;
-               case CSSM_ALGID_DSA:
-                       digestAlg = CSSM_ALGID_SHA1;
-                       algorithm = CSSM_ALGID_DSA;
-                       break;
-               default:
-                       break;
-       }
-       if(digestAlg != CSSM_ALGID_NONE) {
-               crtn = cspDigest(cspHand,
-                       digestAlg,
-                       CSSM_FALSE,                     // mallocDigest
-                       text,
-                       &digest);
-               if(crtn) {
-                       return crtn;
-               }       
-               /* sign digest with raw RSA/DSA */
-               ptext = &digest;
-       }
-       else {
-               ptext = text;
-       }
-       crtn = CSSM_CSP_CreateSignatureContext(cspHand,
-               algorithm,
-               NULL,                           // passPhrase
-               key,
-               &sigHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_SignData(sigHand,
-               ptext,
-               1,
-               digestAlg,
-               sig);
-       if(crtn) {
-               printError("CSSM_SignData", crtn);
-               ocrtn = crtn;
-       }
-       crtn = CSSM_DeleteContext(sigHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       if(digest.Data != NULL) {
-               CSSM_FREE(digest.Data);
-       }
-       return ocrtn;
-}
-
-/*
- * Staged sign. Each update does a random number of bytes 'till through.
- */
-CSSM_RETURN cspStagedSign(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // private key
-               const CSSM_DATA *text,
-               CSSM_BOOL multiUpdates,                         // false:single update, true:multi updates
-               CSSM_DATA_PTR sig)                                      // RETURNED
-{
-       CSSM_CC_HANDLE  sigHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                thisMove;                               // this update
-       unsigned                toMove;                                 // total to go
-       CSSM_DATA               thisText;                               // actaully passed to update
-       crtn = CSSM_CSP_CreateSignatureContext(cspHand,
-               algorithm,
-               NULL,                           // passPhrase
-               key,
-               &sigHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_SignDataInit(sigHand);
-       if(crtn) {
-               printError("CSSM_SignDataInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = text->Length;
-       thisText.Data = text->Data;
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       thisMove = toMove;
-               }
-               thisText.Length = thisMove;
-               crtn = CSSM_SignDataUpdate(sigHand,
-                       &thisText,
-                       1);
-               if(crtn) {
-                       printError("CSSM_SignDataUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               thisText.Data += thisMove;
-               toMove -= thisMove;
-       }
-       crtn = CSSM_SignDataFinal(sigHand, sig);
-       if(crtn) {
-               printError("CSSM_SignDataFinal", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-abort:
-       crtn = CSSM_DeleteContext(sigHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-/*
- * This all-in-one verify op has a special case for RSA keys. If the requested
- * alg is MD5 or SHA1, we'll do a manual digest op followed by raw RSA verify.
- * Likewise, if it's CSSM_ALGID_DSA, we'll do manual SHA1 digest followed by 
- * raw DSA sign.
- */ 
-CSSM_RETURN cspSigVerify(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // public key
-               const CSSM_DATA *text,
-               const CSSM_DATA *sig,
-               CSSM_RETURN expectResult)                       // expected result is verify failure
-                                                                                       // CSSM_OK - expect success
-{
-       CSSM_CC_HANDLE  sigHand;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       CSSM_RETURN             crtn;
-       const CSSM_DATA *ptext;
-       CSSM_DATA               digest = {0, NULL};
-       CSSM_ALGORITHMS digestAlg = CSSM_ALGID_NONE;
-       
-       /* handle special cases for raw sign */
-       switch(algorithm) {
-               case CSSM_ALGID_SHA1:
-                       digestAlg = CSSM_ALGID_SHA1;
-                       algorithm = CSSM_ALGID_RSA;
-                       break;
-               case CSSM_ALGID_MD5:
-                       digestAlg = CSSM_ALGID_MD5;
-                       algorithm = CSSM_ALGID_RSA;
-                       break;
-               case CSSM_ALGID_DSA:
-                       digestAlg = CSSM_ALGID_SHA1;
-                       algorithm = CSSM_ALGID_DSA;
-                       break;
-               default:
-                       break;
-       }
-       if(digestAlg != CSSM_ALGID_NONE) {
-               crtn = cspDigest(cspHand,
-                       digestAlg,
-                       CSSM_FALSE,                     // mallocDigest
-                       text,
-                       &digest);
-               if(crtn) {
-                       return crtn;
-               }       
-               /* sign digest with raw RSA/DSA */
-               ptext = &digest;
-       }
-       else {
-               ptext = text;
-       }
-       crtn = CSSM_CSP_CreateSignatureContext(cspHand,
-               algorithm,
-               NULL,                           // passPhrase
-               key,
-               &sigHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateSignatureContext (3)", crtn);
-               return crtn;
-       }
-       
-       crtn = CSSM_VerifyData(sigHand,
-               ptext,
-               1,
-               digestAlg,
-               sig);
-       if(crtn != expectResult) {
-               if(!crtn) {
-                       printf("Unexpected good Sig Verify\n");
-               }
-               else {
-                       printError("CSSM_VerifyData", crtn);
-               }
-               ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       crtn = CSSM_DeleteContext(sigHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       if(digest.Data != NULL) {
-               CSSM_FREE(digest.Data);
-       }
-       return ocrtn;
-}
-
-/*
- * Staged verify. Each update does a random number of bytes 'till through.
- */
-CSSM_RETURN cspStagedSigVerify(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // private key
-               const CSSM_DATA *text,
-               const CSSM_DATA *sig,
-               CSSM_BOOL multiUpdates,                         // false:single update, true:multi updates
-               CSSM_RETURN expectResult)                       // expected result is verify failure
-                                                                                       // CSSM_TRUE - expect success
-{
-       CSSM_CC_HANDLE  sigHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                thisMove;                               // this update
-       unsigned                toMove;                                 // total to go
-       CSSM_DATA               thisText;                               // actaully passed to update
-       crtn = CSSM_CSP_CreateSignatureContext(cspHand,
-               algorithm,
-               NULL,                           // passPhrase
-               key,
-               &sigHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateSignatureContext (4)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_VerifyDataInit(sigHand);
-       if(crtn) {
-               printError("CSSM_VerifyDataInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = text->Length;
-       thisText.Data = text->Data;
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       thisMove = toMove;
-               }
-               thisText.Length = thisMove;
-               crtn = CSSM_VerifyDataUpdate(sigHand,
-                       &thisText,
-                       1);
-               if(crtn) {
-                       printError("CSSM_VerifyDataUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               thisText.Data += thisMove;
-               toMove -= thisMove;
-       }
-       crtn = CSSM_VerifyDataFinal(sigHand, sig);
-       if(crtn != expectResult) {
-               if(crtn) {
-                       printError("CSSM_VerifyDataFinal", crtn);
-               }
-               else {
-                       printf("Unexpected good Staged Sig Verify\n");
-               }
-               ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-abort:
-       crtn = CSSM_DeleteContext(sigHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-/*
- * MAC routines
- */
-CSSM_RETURN cspGenMac(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // session key
-               const CSSM_DATA *text,
-               CSSM_DATA_PTR mac)                                      // RETURNED
-{
-       CSSM_CC_HANDLE  macHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       crtn = CSSM_CSP_CreateMacContext(cspHand,
-               algorithm,
-               key,
-               &macHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateMacContext (1)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_GenerateMac(macHand,
-               text,
-               1,
-               mac);
-       if(crtn) {
-               printError("CSSM_GenerateMac", crtn);
-               ocrtn = crtn;
-       }
-       crtn = CSSM_DeleteContext(macHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-/*
- * Staged generate mac. 
- */
-CSSM_RETURN cspStagedGenMac(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // private key
-               const CSSM_DATA *text,
-               CSSM_BOOL mallocMac,                            // if true and digest->Length = 0, we'll 
-                                                                                       //              malloc
-               CSSM_BOOL multiUpdates,                         // false:single update, true:multi updates
-               CSSM_DATA_PTR mac)                                      // RETURNED
-{
-       CSSM_CC_HANDLE  macHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                thisMove;                               // this update
-       unsigned                toMove;                                 // total to go
-       CSSM_DATA               thisText;                               // actaully passed to update
-       
-       crtn = CSSM_CSP_CreateMacContext(cspHand,
-               algorithm,
-               key,
-               &macHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateMacContext (2)", crtn);
-               return crtn;
-       }
-
-       if(mallocMac && (mac->Length == 0)) {
-               /* malloc mac - ask CSP for size */
-               CSSM_QUERY_SIZE_DATA    querySize = {0, 0};
-               crtn = CSSM_QuerySize(macHand,
-                       CSSM_TRUE,                                              // encrypt
-                       1,
-                       &querySize);
-               if(crtn) {
-                       printError("CSSM_QuerySize(mac)", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(querySize.SizeOutputBlock == 0) {
-                       printf("Unknown mac size\n");
-                       ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-                       goto abort;
-               }
-               mac->Data = (uint8 *)appMalloc(querySize.SizeOutputBlock, NULL);
-               if(mac->Data == NULL) {
-                       printf("malloc failure\n");
-                       ocrtn = CSSMERR_CSSM_MEMORY_ERROR;
-                       goto abort;
-               }
-               mac->Length = querySize.SizeOutputBlock;
-       }
-
-       crtn = CSSM_GenerateMacInit(macHand);
-       if(crtn) {
-               printError("CSSM_GenerateMacInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = text->Length;
-       thisText.Data = text->Data;
-       
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       thisMove = toMove;
-               }
-               thisText.Length = thisMove;
-               crtn = CSSM_GenerateMacUpdate(macHand,
-                       &thisText,
-                       1);
-               if(crtn) {
-                       printError("CSSM_GenerateMacUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               thisText.Data += thisMove;
-               toMove -= thisMove;
-       }
-       crtn = CSSM_GenerateMacFinal(macHand, mac);
-       if(crtn) {
-               printError("CSSM_GenerateMacFinal", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-abort:
-       crtn = CSSM_DeleteContext(macHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-CSSM_RETURN cspMacVerify(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // public key
-               const CSSM_DATA *text,
-               const CSSM_DATA_PTR mac,
-               CSSM_RETURN expectResult)                       // expected result 
-                                                                                       // CSSM_OK - expect success
-{
-       CSSM_CC_HANDLE  macHand;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       CSSM_RETURN             crtn;
-       crtn = CSSM_CSP_CreateMacContext(cspHand,
-               algorithm,
-               key,
-               &macHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateMacContext (3)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_VerifyMac(macHand,
-               text,
-               1,
-               mac);
-       if(crtn != expectResult) {
-               if(crtn) {
-                       printError("CSSM_VerifyMac", crtn);
-               }
-               else {
-                       printf("Unexpected good Mac Verify\n");
-               }
-               ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       crtn = CSSM_DeleteContext(macHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-/*
- * Staged mac verify. Each update does a random number of bytes 'till through.
- */
-CSSM_RETURN cspStagedMacVerify(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_FEE_MD5, etc.
-               CSSM_KEY_PTR key,                                       // private key
-               const CSSM_DATA *text,
-               const CSSM_DATA_PTR mac,
-               CSSM_BOOL multiUpdates,                         // false:single update, true:multi updates
-               CSSM_RETURN expectResult)                       // expected result is verify failure
-                                                                                       // CSSM_OK - expect success
-{
-       CSSM_CC_HANDLE  macHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                thisMove;                               // this update
-       unsigned                toMove;                                 // total to go
-       CSSM_DATA               thisText;                               // actaully passed to update
-
-       crtn = CSSM_CSP_CreateMacContext(cspHand,
-               algorithm,
-               key,
-               &macHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateMacContext (4)", crtn);
-               return crtn;
-       }
-       crtn = CSSM_VerifyMacInit(macHand);
-       if(crtn) {
-               printError("CSSM_VerifyMacInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = text->Length;
-       thisText.Data = text->Data;
-       
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       thisMove = toMove;
-               }
-               thisText.Length = thisMove;
-               crtn = CSSM_VerifyMacUpdate(macHand,
-                       &thisText,
-                       1);
-               if(crtn) {
-                       printError("CSSM_VerifyMacUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               thisText.Data += thisMove;
-               toMove -= thisMove;
-       }
-       crtn = CSSM_VerifyMacFinal(macHand, mac);
-       if(crtn != expectResult) {
-               if(crtn) {
-                       printError("CSSM_VerifyMacFinal", crtn);
-               }
-               else {
-                       printf("Unexpected good Staged Mac Verify\n");
-               }
-               ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-abort:
-       crtn = CSSM_DeleteContext(macHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-#pragma mark --------- Digest ---------
-
-/*
- * Digest functions
- */
-CSSM_RETURN cspDigest(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_MD5, etc.
-               CSSM_BOOL mallocDigest,                         // if true and digest->Length = 0, we'll malloc
-               const CSSM_DATA *text,
-               CSSM_DATA_PTR digest)
-{
-       CSSM_CC_HANDLE  digestHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       
-       crtn = CSSM_CSP_CreateDigestContext(cspHand,
-               algorithm,
-               &digestHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateDIgestContext (1)", crtn);
-               return crtn;
-       }
-       if(mallocDigest && (digest->Length == 0)) {
-               /* malloc digest - ask CSP for size */
-               CSSM_QUERY_SIZE_DATA    querySize = {0, 0};
-               crtn = CSSM_QuerySize(digestHand,
-                       CSSM_FALSE,                                             // encrypt
-                       1,
-                       &querySize);
-               if(crtn) {
-                       printError("CSSM_QuerySize(3)", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(querySize.SizeOutputBlock == 0) {
-                       printf("Unknown digest size\n");
-                       ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-                       goto abort;
-               }
-               digest->Data = (uint8 *)appMalloc(querySize.SizeOutputBlock, NULL);
-               if(digest->Data == NULL) {
-                       printf("malloc failure\n");
-                       ocrtn = CSSMERR_CSSM_MEMORY_ERROR;
-                       goto abort;
-               }
-               digest->Length = querySize.SizeOutputBlock;
-       }
-       crtn = CSSM_DigestData(digestHand,
-               text,
-               1,
-               digest);
-       if(crtn) {
-               printError("CSSM_DigestData", crtn);
-               ocrtn = crtn;
-       }
-abort:
-       crtn = CSSM_DeleteContext(digestHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-CSSM_RETURN cspStagedDigest(CSSM_CSP_HANDLE cspHand,
-               uint32 algorithm,                                       // CSSM_ALGID_MD5, etc.
-               CSSM_BOOL mallocDigest,                         // if true and digest->Length = 0, we'll 
-                                                                                       //              malloc
-               CSSM_BOOL multiUpdates,                         // false:single update, true:multi updates
-               const CSSM_DATA *text,
-               CSSM_DATA_PTR digest)
-{
-       CSSM_CC_HANDLE  digestHand;
-       CSSM_RETURN             crtn;
-       CSSM_RETURN             ocrtn = CSSM_OK;
-       unsigned                thisMove;                               // this update
-       unsigned                toMove;                                 // total to go
-       CSSM_DATA               thisText;                               // actually passed to update
-       
-       crtn = CSSM_CSP_CreateDigestContext(cspHand,
-               algorithm,
-               &digestHand);
-       if(crtn) {
-               printError("CSSM_CSP_CreateDigestContext (2)", crtn);
-               return crtn;
-       }
-       if(mallocDigest && (digest->Length == 0)) {
-               /* malloc digest - ask CSP for size */
-               CSSM_QUERY_SIZE_DATA    querySize = {0, 0};
-               crtn = CSSM_QuerySize(digestHand,
-                       CSSM_FALSE,                                             // encrypt
-                       1,
-                       &querySize);
-               if(crtn) {
-                       printError("CSSM_QuerySize(4)", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               if(querySize.SizeOutputBlock == 0) {
-                       printf("Unknown digest size\n");
-                       ocrtn = CSSMERR_CSSM_INTERNAL_ERROR;
-                       goto abort;
-               }
-               digest->Data = (uint8 *)appMalloc(querySize.SizeOutputBlock, NULL);
-               if(digest->Data == NULL) {
-                       printf("malloc failure\n");
-                       ocrtn = CSSMERR_CSSM_MEMORY_ERROR;
-                       goto abort;
-               }
-               digest->Length = querySize.SizeOutputBlock;
-       }
-       crtn = CSSM_DigestDataInit(digestHand);
-       if(crtn) {
-               printError("CSSM_DigestDataInit", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-       toMove = text->Length;
-       thisText.Data = text->Data;
-       while(toMove) {
-               if(multiUpdates) {
-                       thisMove = genRand(1, toMove);
-               }
-               else {
-                       thisMove = toMove;
-               }
-               thisText.Length = thisMove;
-               crtn = CSSM_DigestDataUpdate(digestHand,
-                       &thisText,
-                       1);
-               if(crtn) {
-                       printError("CSSM_DigestDataUpdate", crtn);
-                       ocrtn = crtn;
-                       goto abort;
-               }
-               thisText.Data += thisMove;
-               toMove -= thisMove;
-       }
-       crtn = CSSM_DigestDataFinal(digestHand, digest);
-       if(crtn) {
-               printError("CSSM_DigestDataFinal", crtn);
-               ocrtn = crtn;
-               goto abort;
-       }
-abort:
-       crtn = CSSM_DeleteContext(digestHand);
-       if(crtn) {
-               printError("CSSM_DeleteContext", crtn);
-               ocrtn = crtn;
-       }
-       return ocrtn;
-}
-
-#pragma mark --------- wrap/unwrap ---------
-
-/* wrap key function. */
-CSSM_RETURN cspWrapKey(CSSM_CSP_HANDLE cspHand,
-       const CSSM_KEY                  *unwrappedKey,  
-       const CSSM_KEY                  *wrappingKey,
-       CSSM_ALGORITHMS                 wrapAlg,
-       CSSM_ENCRYPT_MODE               wrapMode,
-       CSSM_KEYBLOB_FORMAT             wrapFormat,                     // NONE, PKCS7, PKCS8
-       CSSM_PADDING                    wrapPad,
-       CSSM_DATA_PTR                   initVector,                     // for some wrapping algs
-       CSSM_DATA_PTR                   descrData,                      // optional 
-       CSSM_KEY_PTR                    wrappedKey)                     // RETURNED
-{
-       CSSM_CC_HANDLE          ccHand;
-       CSSM_RETURN                     crtn;
-       CSSM_ACCESS_CREDENTIALS creds;
-       
-       memset(wrappedKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(wrappedKey);
-       memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-       /* special case for NULL wrap - no wrapping key */
-       if((wrappingKey == NULL) ||
-          (wrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) {
-               crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
-                               wrapAlg,
-                               wrapMode,
-                               &creds,                 // passPhrase,
-                               wrappingKey,
-                               initVector,
-                               wrapPad,                // Padding
-                               0,                              // Params
-                               &ccHand);
-       }
-       else {
-               crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
-                               wrapAlg,
-                               &creds, 
-                               wrappingKey,
-                               wrapPad,                // padding
-                               &ccHand);
-               if(crtn) {
-                       printError("cspWrapKey/CreateContext", crtn);
-                       return crtn;
-               }
-               if(initVector) {
-                       /* manually add IV for CMS. The actual low-level encrypt doesn't
-                        * use it (and must ignore it). */
-                       crtn = AddContextAttribute(ccHand,
-                               CSSM_ATTRIBUTE_INIT_VECTOR,
-                               sizeof(CSSM_DATA),
-                               CAT_Ptr,
-                               initVector,
-                               0);
-                       if(crtn) {
-                               printError("CSSM_UpdateContextAttributes", crtn);
-                               return crtn;
-                       }
-               }
-       }
-       if(crtn) {
-               printError("cspWrapKey/CreateContext", crtn);
-               return crtn;
-       }
-       if(wrapFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {
-               /* only add this attribute if it's not the default */
-               CSSM_CONTEXT_ATTRIBUTE attr;
-               attr.AttributeType = CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT;
-               attr.AttributeLength = sizeof(uint32);
-               attr.Attribute.Uint32 = wrapFormat;
-               crtn = CSSM_UpdateContextAttributes(
-                       ccHand,
-                       1,
-                       &attr);
-               if(crtn) {
-                       printError("CSSM_UpdateContextAttributes", crtn);
-                       return crtn;
-               }
-       }
-       crtn = CSSM_WrapKey(ccHand,
-               &creds,
-               unwrappedKey,
-               descrData,                      // DescriptiveData
-               wrappedKey);
-       if(crtn != CSSM_OK) {
-               printError("CSSM_WrapKey", crtn);
-       }
-       if(CSSM_DeleteContext(ccHand)) {
-               printf("CSSM_DeleteContext failure\n");
-       }
-       return crtn;
-}
-
-/* unwrap key function. */
-CSSM_RETURN cspUnwrapKey(CSSM_CSP_HANDLE cspHand,
-       const CSSM_KEY                  *wrappedKey,
-       const CSSM_KEY                  *unwrappingKey,
-       CSSM_ALGORITHMS                 unwrapAlg,
-       CSSM_ENCRYPT_MODE               unwrapMode,
-       CSSM_PADDING                    unwrapPad,
-       CSSM_DATA_PTR                   initVector,                     // for some wrapping algs
-       CSSM_KEY_PTR                    unwrappedKey,           // RETURNED
-       CSSM_DATA_PTR                   descrData,                      // required
-       const char                              *keyLabel,
-       unsigned                                keyLabelLen)
-{
-       CSSM_CC_HANDLE          ccHand;
-       CSSM_RETURN                     crtn;
-       CSSM_DATA                       labelData;
-       uint32                          keyAttr;
-       CSSM_ACCESS_CREDENTIALS creds;
-       
-       memset(unwrappedKey, 0, sizeof(CSSM_KEY));
-       setBadKeyData(unwrappedKey);
-       memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-       if((unwrappingKey == NULL) ||
-          (unwrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) {
-               crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
-                               unwrapAlg,
-                               unwrapMode,
-                               &creds,
-                               unwrappingKey,
-                               initVector,
-                               unwrapPad,
-                               0,                              // Params
-                               &ccHand);
-       }
-       else {
-               crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
-                               unwrapAlg,
-                               &creds,                 // passPhrase,
-                               unwrappingKey,
-                               unwrapPad,              // Padding
-                               &ccHand);
-               if(crtn) {
-                       printError("cspUnwrapKey/CreateContext", crtn);
-                       return crtn;
-               }
-               if(initVector) {
-                       /* manually add IV for CMS. The actual low-level encrypt doesn't
-                        * use it (and must ignore it). */
-                       crtn = AddContextAttribute(ccHand,
-                               CSSM_ATTRIBUTE_INIT_VECTOR,
-                               sizeof(CSSM_DATA),
-                               CAT_Ptr,
-                               initVector,
-                               0);
-                       if(crtn) {
-                               printError("CSSM_UpdateContextAttributes", crtn);
-                               return crtn;
-                       }
-               }
-       }
-       if(crtn) {
-               printError("cspUnwrapKey/CreateContext", crtn);
-               return crtn;
-       }
-       labelData.Data = (uint8 *)keyLabel;
-       labelData.Length = keyLabelLen;
-       
-       /*
-        * New keyAttr - clear some old bits, make sure we ask for ref key
-        */
-       keyAttr = wrappedKey->KeyHeader.KeyAttr;
-       keyAttr &= ~(CSSM_KEYATTR_ALWAYS_SENSITIVE | CSSM_KEYATTR_NEVER_EXTRACTABLE);
-       keyAttr |= CSSM_KEYATTR_RETURN_REF;
-       crtn = CSSM_UnwrapKey(ccHand,
-               NULL,                           // PublicKey
-               wrappedKey,
-               wrappedKey->KeyHeader.KeyUsage,
-               keyAttr,
-               &labelData,
-               NULL,                           // CredAndAclEntry
-               unwrappedKey,
-               descrData);                     // required
-       if(crtn != CSSM_OK) {
-               printError("CSSM_UnwrapKey", crtn);
-       }
-       if(CSSM_DeleteContext(ccHand)) {
-               printf("CSSM_DeleteContext failure\n");
-       }
-       return crtn;
-}
-
-/*
- * Simple NULL wrap to convert a reference key to a raw key.
- */
-CSSM_RETURN cspRefKeyToRaw(
-       CSSM_CSP_HANDLE cspHand,
-       const CSSM_KEY *refKey,
-       CSSM_KEY_PTR rawKey)            // init'd and RETURNED
-{
-       CSSM_DATA descData = {0, 0};
-       
-       memset(rawKey, 0, sizeof(CSSM_KEY));
-       return cspWrapKey(cspHand,
-               refKey,
-               NULL,                                   // unwrappingKey
-               CSSM_ALGID_NONE,
-               CSSM_ALGMODE_NONE,
-               CSSM_KEYBLOB_WRAPPED_FORMAT_NONE,
-               CSSM_PADDING_NONE,
-               NULL,                                   // IV
-               &descData,
-               rawKey);
-}
-
-/* 
- * Convert ref key to raw key with specified format.
- */
-CSSM_RETURN cspRefKeyToRawWithFormat(
-       CSSM_CSP_HANDLE cspHand,
-       const CSSM_KEY *refKey,
-       CSSM_KEYBLOB_FORMAT format,
-       CSSM_KEY_PTR rawKey)            // init'd and RETURNED
-{
-       memset(rawKey, 0, sizeof(CSSM_KEY));
-       CSSM_ATTRIBUTE_TYPE attrType;   
-       
-       switch(refKey->KeyHeader.KeyClass) {
-               case CSSM_KEYCLASS_PUBLIC_KEY:
-                       attrType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT;
-                       break;
-               case CSSM_KEYCLASS_PRIVATE_KEY:
-                       attrType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT;
-                       break;
-               case CSSM_KEYCLASS_SESSION_KEY:
-                       attrType = CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT;
-                       break;
-               default:
-                       printf("***Unknown key class\n");
-                       return CSSMERR_CSP_INVALID_KEY;
-       }
-       
-       CSSM_DATA descData = {0, 0};
-       CSSM_CC_HANDLE          ccHand;
-       CSSM_RETURN                     crtn;
-//     uint32                          keyAttr;
-       CSSM_ACCESS_CREDENTIALS creds;
-       
-       memset(rawKey, 0, sizeof(CSSM_KEY));
-       memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
-       crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
-                               CSSM_ALGID_NONE,
-                               CSSM_ALGMODE_NONE,
-                               &creds,
-                               NULL,                   // unwrappingKey
-                               NULL,                   // initVector
-                               CSSM_PADDING_NONE,
-                               NULL,                   // Reserved
-                               &ccHand);
-       if(crtn) {
-               printError("cspRefKeyToRawWithFormat/CreateContext", crtn);
-               return crtn;
-       }
-       
-       /* Add the spec for the resulting format */
-       crtn = AddContextAttribute(ccHand,
-               attrType,
-               sizeof(uint32),         
-               CAT_Uint32,
-               NULL,
-               format);
-
-       crtn = CSSM_WrapKey(ccHand,
-               &creds,
-               refKey,
-               &descData,                      // DescriptiveData
-               rawKey);
-       if(crtn != CSSM_OK) {
-               printError("CSSM_WrapKey", crtn);
-       }
-       if(rawKey->KeyHeader.Format != format) {
-               printf("***cspRefKeyToRawWithFormat format scewup\n");
-               crtn = CSSMERR_CSP_INTERNAL_ERROR;
-       }
-       if(CSSM_DeleteContext(ccHand)) {
-               printf("CSSM_DeleteContext failure\n");
-       }
-       return crtn;
-}
-
-/* unwrap raw key --> ref */
-CSSM_RETURN cspRawKeyToRef(
-       CSSM_CSP_HANDLE cspHand,
-       const CSSM_KEY *rawKey,
-       CSSM_KEY_PTR refKey)                            // init'd and RETURNED
-{
-       CSSM_DATA descData = {0, 0};
-
-       memset(refKey, 0, sizeof(CSSM_KEY));
-       return cspUnwrapKey(cspHand,
-               rawKey,
-               NULL,           // unwrappingKey
-               CSSM_ALGID_NONE,
-               CSSM_ALGMODE_NONE,
-               CSSM_PADDING_NONE,
-               NULL,           // init vector
-               refKey,
-               &descData,
-               "noLabel",
-               7);
-}
-
-
-#pragma mark --------- FEE key/curve support ---------
-
-/*
- * Generate random key size, primeType, curveType for FEE key for specified op.
- *
- * First just enumerate the curves we know about, with ECDSA-INcapable first
- */
-typedef struct {
-       uint32  keySizeInBits;
-       uint32  primeType;                              // CSSM_FEE_PRIME_TYPE_xxx
-       uint32  curveType;                              // CSSM_FEE_CURVE_TYPE_xxx
-} feeCurveParams;
-
-#define FEE_PROTOTYPE_CURVES   0
-#if    FEE_PROTOTYPE_CURVES
-/* obsolete as of 4/9/2001 */
-static feeCurveParams feeCurves[] = {
-       {       31,             CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_MONTGOMERY },
-       {       127,    CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_MONTGOMERY },
-       {       127,    CSSM_FEE_PRIME_TYPE_GENERAL,    CSSM_FEE_CURVE_TYPE_MONTGOMERY },
-       #define NUM_NON_ECDSA_CURVES    3
-       
-       /* start of Weierstrass, IEEE P1363-capable curves */
-       {       31,             CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       40,             CSSM_FEE_PRIME_TYPE_FEE,                CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       127,    CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       160,    CSSM_FEE_PRIME_TYPE_FEE,                CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       160,    CSSM_FEE_PRIME_TYPE_GENERAL,    CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       192,    CSSM_FEE_PRIME_TYPE_FEE,                CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-};
-#else  /* FEE_PROTOTYPE_CURVES */
-static feeCurveParams feeCurves[] = {
-       {       31,             CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_MONTGOMERY },
-       {       127,    CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_MONTGOMERY },
-       #define NUM_NON_ECDSA_CURVES    2
-       
-       /* start of Weierstrass, IEEE P1363-capable curves */
-       {       31,             CSSM_FEE_PRIME_TYPE_MERSENNE,   CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       128,    CSSM_FEE_PRIME_TYPE_FEE,                CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       161,    CSSM_FEE_PRIME_TYPE_FEE,                CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       161,    CSSM_FEE_PRIME_TYPE_GENERAL,    CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-       {       192,    CSSM_FEE_PRIME_TYPE_GENERAL,    CSSM_FEE_CURVE_TYPE_WEIERSTRASS },
-};
-#endif /* FEE_PROTOTYPE_CURVES */
-#define NUM_FEE_CURVES (sizeof(feeCurves) / sizeof(feeCurveParams))
-
-void randFeeKeyParams(
-       CSSM_ALGORITHMS alg,                    // ALGID_FEED, CSSM_ALGID_FEE_MD5, etc.
-       uint32                  *keySizeInBits, // RETURNED
-       uint32                  *primeType,             // CSSM_FEE_PRIME_TYPE_xxx, RETURNED
-       uint32                  *curveType)             // CSSM_FEE_CURVE_TYPE_xxx, RETURNED
-{
-       unsigned minParams;
-       unsigned die;
-       feeCurveParams *feeParams;
-       
-       switch(alg) {
-               case CSSM_ALGID_SHA1WithECDSA:
-                       minParams = NUM_NON_ECDSA_CURVES;
-                       break;
-               default:
-                       minParams = 0;
-                       break;
-       }
-       die = genRand(minParams, (NUM_FEE_CURVES - 1));
-       feeParams = &feeCurves[die];
-       *keySizeInBits = feeParams->keySizeInBits;
-       *primeType = feeParams->primeType;
-       *curveType = feeParams->curveType;
-}
-
-/*
- * Obtain strings for primeType and curveType.
- */
-const char *primeTypeStr(uint32 primeType)
-{
-       const char *p;
-       switch(primeType) {
-               case CSSM_FEE_PRIME_TYPE_MERSENNE:
-                       p = "Mersenne";
-                       break;
-               case CSSM_FEE_PRIME_TYPE_FEE:
-                       p = "FEE";
-                       break;
-               case CSSM_FEE_PRIME_TYPE_GENERAL:
-                       p = "General";
-                       break;
-               case CSSM_FEE_PRIME_TYPE_DEFAULT:
-                       p = "Default";
-                       break;
-               default:
-                       p = "***UNKNOWN***";
-                       break;
-       }
-       return p;
-}
-
-const char *curveTypeStr(uint32 curveType)
-{
-       const char *c;
-       switch(curveType) {
-               case CSSM_FEE_CURVE_TYPE_DEFAULT:
-                       c = "Default";
-                       break;
-               case CSSM_FEE_CURVE_TYPE_MONTGOMERY:
-                       c = "Montgomery";
-                       break;
-               case CSSM_FEE_CURVE_TYPE_WEIERSTRASS:
-                       c = "Weierstrass";
-                       break;
-               default:
-                       c = "***UNKNOWN***";
-                       break;
-       }
-       return c;
-}
-
-/*
- * Perform FEE Key exchange via CSSM_DeriveKey. 
- */
-#if 0
-/* Not implemented in OS X */
-CSSM_RETURN cspFeeKeyExchange(CSSM_CSP_HANDLE cspHand,
-       CSSM_KEY_PTR    privKey,
-       CSSM_KEY_PTR    pubKey,
-       CSSM_KEY_PTR    derivedKey,             // mallocd by caller
-       
-       /* remaining fields apply to derivedKey */
-       uint32                  keyAlg,
-       const char              *keyLabel,
-       unsigned                keyLabelLen,
-       uint32                  keyUsage,               // CSSM_KEYUSE_ENCRYPT, etc.
-       uint32                  keySizeInBits)
-{
-       CSSM_CC_HANDLE  dkHand;
-       CSSM_RETURN     crtn;
-       CSSM_DATA               labelData;
-       
-       if(derivedKey == NULL) {
-               printf("cspFeeKeyExchange: no derivedKey\n");
-               return CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       if((pubKey == NULL) ||
-          (pubKey->KeyHeader.KeyClass != CSSM_KEYCLASS_PUBLIC_KEY) ||
-          (pubKey->KeyHeader.BlobType != CSSM_KEYBLOB_RAW)) {
-               printf("cspFeeKeyExchange: bad pubKey\n");
-               return CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       if((privKey == NULL) ||
-          (privKey->KeyHeader.KeyClass != CSSM_KEYCLASS_PRIVATE_KEY) ||
-          (privKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE)) {
-               printf("cspFeeKeyExchange: bad privKey\n");
-               return CSSMERR_CSSM_INTERNAL_ERROR;
-       }
-       memset(derivedKey, 0, sizeof(CSSM_KEY));
-       
-       crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
-               CSSM_ALGID_FEE_KEYEXCH,                 // AlgorithmID
-               keyAlg,                                                 // alg of the derived key
-               keySizeInBits,
-               NULL,                                                   // access creds
-               // FIXME
-               0,                                                              // IterationCount
-               NULL,                                                   // Salt
-               NULL,                                                   // Seed
-               NULL);                                                  // PassPhrase
-       if(dkHand == 0) {
-               printError("CSSM_CSP_CreateDeriveKeyContext");
-               return CSSM_FAIL;
-       } 
-       labelData.Length = keyLabelLen;
-       labelData.Data = (uint8 *)keyLabel;
-       crtn = CSSM_DeriveKey(dkHand,
-               privKey,
-               &pubKey->KeyData,               // Param - pub key blob
-               keyUsage,
-               CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE |
-                                 CSSM_KEYATTR_SENSITIVE,
-               &labelData,
-               derivedKey);
-       
-       /* FIXME - save/restore error */
-       CSSM_DeleteContext(dkHand);
-       if(crtn) {
-               printError("CSSM_DeriveKey");
-       }
-       return crtn;
-}
-#endif
-
-#pragma mark --------- Key/DL/DB support ---------
-
-/*
- * Add a DL/DB handle to a crypto context.
- */
-CSSM_RETURN cspAddDlDbToContext(
-       CSSM_CC_HANDLE ccHand,
-       CSSM_DL_HANDLE dlHand,
-       CSSM_DB_HANDLE dbHand)
-{
-       CSSM_DL_DB_HANDLE dlDb = { dlHand, dbHand };
-       return AddContextAttribute(ccHand, 
-               CSSM_ATTRIBUTE_DL_DB_HANDLE,
-               sizeof(CSSM_ATTRIBUTE_DL_DB_HANDLE),
-               CAT_Ptr,
-               &dlDb,
-               0);
-}
-       
-/* 
- * Common routine to do a basic DB lookup by label and key type.
- * Query is aborted prior to exit.
- */
-static CSSM_DB_UNIQUE_RECORD_PTR dlLookup(
-       CSSM_DL_DB_HANDLE       dlDbHand,
-       const CSSM_DATA         *keyLabel,
-       CT_KeyType                      keyType,
-       CSSM_HANDLE             *resultHand,                    // RETURNED
-       CSSM_DATA_PTR           theData,                                // RETURED
-       CSSM_DB_RECORDTYPE      *recordType)                    // RETURNED
-{
-       CSSM_QUERY                                              query;
-       CSSM_SELECTION_PREDICATE                predicate;
-       CSSM_DB_UNIQUE_RECORD_PTR               record = NULL;
-       CSSM_RETURN                                             crtn;
-       
-       switch(keyType) {
-               case CKT_Public:
-                       query.RecordType = *recordType = CSSM_DL_DB_RECORD_PUBLIC_KEY;
-                       break;
-               case CKT_Private:
-                       query.RecordType = *recordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
-                       break;
-               case CKT_Session:
-                       query.RecordType = *recordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY;
-                       break;
-               default:
-                       printf("Hey bozo! Give me a valid key type!\n");
-                       return NULL;
-       }
-       query.Conjunctive = CSSM_DB_NONE;
-       query.NumSelectionPredicates = 1;
-       predicate.DbOperator = CSSM_DB_EQUAL;
-       
-       predicate.Attribute.Info.AttributeNameFormat = 
-               CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
-       predicate.Attribute.Info.Label.AttributeName = (char *) "Label";
-       predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-       /* hope this cast is OK */
-       predicate.Attribute.Value = (CSSM_DATA_PTR)keyLabel;
-       query.SelectionPredicate = &predicate;
-       
-       query.QueryLimits.TimeLimit = 0;        // FIXME - meaningful?
-       query.QueryLimits.SizeLimit = 1;        // FIXME - meaningful?
-       query.QueryFlags = CSSM_QUERY_RETURN_DATA;      // FIXME - used?
-       
-       crtn = CSSM_DL_DataGetFirst(dlDbHand,
-               &query,
-               resultHand,
-               NULL,
-               theData,
-               &record);
-       /* abort only on success */
-       if(crtn == CSSM_OK) {
-               crtn = CSSM_DL_DataAbortQuery(dlDbHand, *resultHand);
-               if(crtn) {
-                       printError("CSSM_DL_AbortQuery", crtn);
-                       return NULL;
-               }
-       }
-       return record;
-}
-
-/*
- * Look up a key by label and type.
- */
-CSSM_KEY_PTR cspLookUpKeyByLabel(
-       CSSM_DL_HANDLE dlHand, 
-       CSSM_DB_HANDLE dbHand, 
-       const CSSM_DATA *labelData, 
-       CT_KeyType keyType)
-{
-       CSSM_DB_UNIQUE_RECORD_PTR       record;
-       CSSM_HANDLE                                     resultHand;
-       CSSM_DATA                                       theData;
-       CSSM_KEY_PTR                            key;
-       CSSM_DB_RECORDTYPE                      recordType;
-       CSSM_DL_DB_HANDLE                       dlDbHand;
-       
-       dlDbHand.DLHandle = dlHand;
-       dlDbHand.DBHandle = dbHand;
-       
-       theData.Length = 0;
-       theData.Data = NULL;
-       
-       record = dlLookup(dlDbHand,
-               labelData,
-               keyType,
-               &resultHand,
-               &theData,
-               &recordType);
-       if(record == NULL) {
-               //printf("cspLookUpKeyByLabel: key not found\n");
-               return NULL;
-       }
-       key = (CSSM_KEY_PTR)theData.Data;
-       CSSM_DL_FreeUniqueRecord(dlDbHand, record);
-       return key;
-}
-
-/*
- * Delete and free a key 
- */
-CSSM_RETURN cspDeleteKey(
-       CSSM_CSP_HANDLE         cspHand,                // for free
-       CSSM_DL_HANDLE          dlHand,                 // for delete
-       CSSM_DB_HANDLE          dbHand,                 // ditto
-       const CSSM_DATA         *labelData, 
-       CSSM_KEY_PTR            key)
-{
-       CSSM_DB_UNIQUE_RECORD_PTR       record;
-       CSSM_HANDLE                                     resultHand;
-       CT_KeyType                                      keyType;
-       CSSM_RETURN                                     crtn = CSSM_OK;
-       CSSM_DB_RECORDTYPE                      recordType;
-       CSSM_DL_DB_HANDLE                       dlDbHand;
-       
-       if(key->KeyHeader.KeyAttr & CSSM_KEYATTR_PERMANENT) {
-               /* first do a lookup based in this key's fields */
-               switch(key->KeyHeader.KeyClass) {
-                       case CSSM_KEYCLASS_PUBLIC_KEY:
-                               keyType = CKT_Public;
-                               break;
-                       case CSSM_KEYCLASS_PRIVATE_KEY:
-                               keyType = CKT_Private;
-                               break;
-                       case CSSM_KEYCLASS_SESSION_KEY:
-                               keyType = CKT_Session;
-                               break;
-                       default:
-                               printf("Hey bozo! Give me a valid key type!\n");
-                               return -1;
-               }
-
-               dlDbHand.DLHandle = dlHand;
-               dlDbHand.DBHandle = dbHand;
-               
-               record = dlLookup(dlDbHand,
-                       labelData,
-                       keyType,
-                       &resultHand,
-                       NULL,                   // don't want actual data
-                       &recordType);
-               if(record == NULL) {
-                       printf("cspDeleteKey: key not found in DL\n");
-                       return CSSMERR_DL_RECORD_NOT_FOUND;
-               }
-               
-               /* OK, nuke it */
-               crtn = CSSM_DL_DataDelete(dlDbHand, record);
-               if(crtn) {
-                       printError("CSSM_DL_DataDelete", crtn);
-               }
-               CSSM_DL_FreeUniqueRecord(dlDbHand, record);
-       }
-               
-       /* CSSM_FreeKey() should fail due to the delete, but it will
-        * still free KeyData....
-        * FIXME - we should be able to do this in this one single call - right?
-        */
-       CSSM_FreeKey(cspHand, NULL, key, CSSM_FALSE);
-
-       return crtn;
-}
-
-/*
- * Given any key in either blob or reference format,
- * obtain the associated SHA-1 hash. 
- */
-CSSM_RETURN cspKeyHash(
-       CSSM_CSP_HANDLE         cspHand,        
-       const CSSM_KEY_PTR      key,                    /* public key */
-       CSSM_DATA_PTR           *hashData)              /* hash mallocd and RETURNED here */
-{
-       CSSM_CC_HANDLE          ccHand;
-       CSSM_RETURN                     crtn;
-       CSSM_DATA_PTR           dp;
-       
-       *hashData = NULL;
-       
-       /* validate input params */
-       if((key == NULL) ||
-          (hashData == NULL)) {
-               printf("cspKeyHash: bogus args\n");
-               return CSSMERR_CSSM_INTERNAL_ERROR;                             
-       }
-       
-       /* cook up a context for a passthrough op */
-       crtn = CSSM_CSP_CreatePassThroughContext(cspHand,
-               key,
-               &ccHand);
-       if(ccHand == 0) {
-               printError("CSSM_CSP_CreatePassThroughContext", crtn);
-               return crtn;
-       }
-       
-       /* now it's up to the CSP */
-       crtn = CSSM_CSP_PassThrough(ccHand,
-               CSSM_APPLECSP_KEYDIGEST,
-               NULL,
-               (void **)&dp);
-       if(crtn) {
-               printError("CSSM_CSP_PassThrough(PUBKEYHASH)", crtn);
-       }
-       else {
-               *hashData = dp;
-               crtn = CSSM_OK;
-       }
-       CSSM_DeleteContext(ccHand);
-       return crtn;
-}
-