-/*
- * bsafeUtils.c - common routines for CDSA/BSAFE compatibility testing
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-//#include <security_bsafe/bsafe.h>
-//#include <security_bsafe/aglobal.h>
-#include "bsafeUtils.h"
-#include <Security/cssmerr.h>
-#include "common.h"
-
-/*
- * Convert between BSAFE ITEM and CSSM_DATA
- */
-#if 0
-static inline void buItemToCssmData(
- const ITEM *item,
- CSSM_DATA_PTR cdata)
-{
- cdata->Data = item->data;
- cdata->Length = item->len;
-}
-
-static inline void buCssmDataToItem(
- const CSSM_DATA *cdata,
- ITEM *item)
-{
- item->data = cdata->Data;
- item->len = cdata->Length;
-}
-
-/*
- * BSafe's Chooser table - all we'll ever need.
- */
-/*static*/ B_ALGORITHM_METHOD *BSAFE_ALGORITHM_CHOOSER[] = {
- // digests
- &AM_SHA,
- &AM_MD5,
- &AM_MD2,
-
- // organizational
- &AM_CBC_ENCRYPT,
- &AM_CBC_DECRYPT,
- &AM_ECB_ENCRYPT,
- &AM_ECB_DECRYPT,
- &AM_OFB_ENCRYPT,
- &AM_OFB_DECRYPT,
-
- // DES & variants
- &AM_DES_ENCRYPT,
- &AM_DES_DECRYPT,
- &AM_DESX_ENCRYPT,
- &AM_DESX_DECRYPT,
- &AM_DES_EDE_ENCRYPT,
- &AM_DES_EDE_DECRYPT,
-
- // RCn stuff
- &AM_RC2_CBC_ENCRYPT,
- &AM_RC2_CBC_DECRYPT,
- &AM_RC2_ENCRYPT,
- &AM_RC2_DECRYPT,
- &AM_RC4_ENCRYPT,
- &AM_RC4_DECRYPT,
- &AM_RC5_ENCRYPT,
- &AM_RC5_DECRYPT,
- &AM_RC5_CBC_ENCRYPT,
- &AM_RC5_CBC_DECRYPT,
-
- // RSA
- &AM_RSA_STRONG_KEY_GEN,
- &AM_RSA_KEY_GEN,
- &AM_RSA_CRT_ENCRYPT_BLIND,
- &AM_RSA_CRT_DECRYPT_BLIND,
- &AM_RSA_ENCRYPT,
- &AM_RSA_DECRYPT,
-
- // DSA
- &AM_DSA_PARAM_GEN,
- &AM_DSA_KEY_GEN,
-
- // signatures
- &AM_DSA_SIGN,
- &AM_DSA_VERIFY,
-
- // random number generation
- &AM_MD5_RANDOM,
- &AM_SHA_RANDOM,
-
- // sentinel
- (B_ALGORITHM_METHOD *)NULL_PTR
-};
-
-/*
- * Convert a BSAFE return to a CSSM error and optionally print the error msg with
- * the op in which the error occurred.
- */
-static CSSM_RETURN buBsafeErrToCssm(
- int brtn,
- const char *op)
-{
- const char *errStr = NULL;
- CSSM_RETURN crtn;
-
- switch (brtn) {
- case 0:
- return CSSM_OK;
- case BE_ALLOC:
- crtn = CSSMERR_CSSM_MEMORY_ERROR;
- errStr = "BE_ALLOC";
- break;
- case BE_SIGNATURE:
- crtn = CSSMERR_CSP_VERIFY_FAILED;
- errStr = "BE_SIGNATURE";
- break;
- case BE_OUTPUT_LEN:
- crtn = CSSMERR_CSP_OUTPUT_LENGTH_ERROR;
- errStr = "BE_OUTPUT_LEN";
- break;
- case BE_INPUT_LEN:
- crtn = CSSMERR_CSP_INPUT_LENGTH_ERROR;
- errStr = "BE_INPUT_LEN";
- break;
- case BE_EXPONENT_EVEN:
- crtn = CSSMERR_CSP_INVALID_KEY;
- errStr = "BE_EXPONENT_EVEN";
- break;
- case BE_EXPONENT_LEN:
- crtn = CSSMERR_CSP_INVALID_KEY;
- errStr = "BE_EXPONENT_LEN";
- break;
- case BE_EXPONENT_ONE:
- crtn = CSSMERR_CSP_INVALID_KEY;
- errStr = "BE_EXPONENT_ONE";
- break;
- case BE_DATA:
- crtn = CSSMERR_CSP_INVALID_DATA;
- errStr = "BE_DATA";
- break;
- case BE_INPUT_DATA:
- crtn = CSSMERR_CSP_INVALID_DATA;
- errStr = "BE_INPUT_DATA";
- break;
- case BE_WRONG_KEY_INFO:
- crtn = CSSMERR_CSP_INVALID_KEY;
- errStr = "BE_WRONG_KEY_INFO";
- break;
- default:
- //@@@ translate BSafe errors intelligently
- crtn = CSSM_ERRCODE_INTERNAL_ERROR;
- errStr = "Other BSAFE error";
- break;
- }
- if(op != NULL) {
- printf("%s: BSAFE error %d (%s)\n", op, brtn, errStr);
- }
- return crtn;
-}
-
-/*
- * Non-thread-safe global random B_ALGORITHM_OBJ and a reusable init for it.
- */
-static B_ALGORITHM_OBJ bsafeRng = NULL;
-#define BSAFE_RANDSIZE 64
-
-static B_ALGORITHM_OBJ buGetRng()
-{
- int brtn;
- uint8 seed[BSAFE_RANDSIZE];
-
- if(bsafeRng != NULL) {
- return bsafeRng;
- }
- brtn = B_CreateAlgorithmObject(&bsafeRng);
- if(brtn) {
- buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject(&bsafeRng)");
- return NULL;
- }
- brtn = B_SetAlgorithmInfo(bsafeRng, AI_X962Random_V0, NULL_PTR);
- if(brtn) {
- buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)");
- return NULL;
- }
- brtn = B_RandomInit(bsafeRng, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)");
- return NULL;
- }
- appGetRandomBytes(seed, BSAFE_RANDSIZE);
- brtn = B_RandomUpdate(bsafeRng, seed, BSAFE_RANDSIZE, NULL);
- if(brtn) {
- buBsafeErrToCssm(brtn, "B_RandomUpdate");
- return NULL;
- }
- return bsafeRng;
-}
-#endif
-
-/*
- * Create a symmetric key.
- */
-CSSM_RETURN buGenSymKey(
- uint32 keySizeInBits,
- const CSSM_DATA *keyData,
- BU_KEY *key) // RETURNED
-{
-#if 0
- int brtn;
- B_KEY_OBJ bkey = NULL;
- ITEM item;
- unsigned keyBytes = (keySizeInBits + 7) / 8;
-
- if(keyBytes > keyData->Length) {
- /* note it's OK to give us too much key data */
- printf("***buGenSymKey: Insufficient keyData\n");
- return CSSM_ERRCODE_INTERNAL_ERROR;
- }
-
- /* create a BSAFE key */
- brtn = B_CreateKeyObject(&bkey);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateKeyObject");
- }
-
- /* assign data to the key */
- item.data = keyData->Data;
- item.len = keyBytes;
- brtn = B_SetKeyInfo(bkey, KI_Item, (POINTER)&item);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_SetKeyInfo");
- }
- else {
- *key = bkey;
- return CSSM_OK;
- }
-#endif
- return 0;
-}
-
-/*
- * Create asymmetric key pair.
- * FIXME - additional params (e.g. DSA params, RSA exponent)?
- */
-CSSM_RETURN buGenKeyPair(
- uint32 keySizeInBits,
- CSSM_ALGORITHMS keyAlg, // CSSM_ALGID_{RSA,DSA}
- BU_KEY *pubKey, // RETURNED
- BU_KEY *privKey) // RETURNED
-{
-#if 0 // NO MORE BSAFE
- int brtn;
- B_KEY_OBJ bPubkey = NULL;
- B_KEY_OBJ bPrivkey = NULL;
- B_ALGORITHM_OBJ keypairGen = NULL;
- const char *op = NULL;
- A_RSA_KEY_GEN_PARAMS params;
- unsigned char exp[1] = { 3 };
- B_ALGORITHM_OBJ genDsaAlg = NULL;
- B_ALGORITHM_OBJ dsaResult = NULL;
- B_DSA_PARAM_GEN_PARAMS dsaParams;
- A_DSA_PARAMS *kParams = NULL;
-
- /* create algorithm object */
- brtn = B_CreateAlgorithmObject(&keypairGen);
- if(brtn) {
- return CSSMERR_CSSM_MEMORY_ERROR;
- }
-
- /* create two BSAFE keys */
- brtn = B_CreateKeyObject(&bPubkey);
- if(brtn) {
- op ="B_CreateKeyObject";
- goto abort;
- }
- brtn = B_CreateKeyObject(&bPrivkey);
- if(brtn) {
- op ="B_CreateKeyObject";
- goto abort;
- }
- switch(keyAlg) {
- case CSSM_ALGID_RSA:
- {
- /* set RSA-specific params */
- params.modulusBits = keySizeInBits;
- /* hack - parameterize? */
- params.publicExponent.data = exp;
- params.publicExponent.len = 1;
- brtn = B_SetAlgorithmInfo(keypairGen, AI_RSAKeyGen,
- (POINTER)¶ms);
- if(brtn) {
- op ="B_SetAlgorithmInfo(AI_RSAKeyGen)";
- }
- break;
- }
- case CSSM_ALGID_DSA:
- {
- /* jump through hoops generating parameters */
- brtn = B_CreateAlgorithmObject(&genDsaAlg);
- if(brtn) {
- op ="B_CreateAlgorithmObject";
- break;
- }
- dsaParams.primeBits = keySizeInBits;
- brtn = B_SetAlgorithmInfo(genDsaAlg, AI_DSAParamGen, (POINTER)&dsaParams);
- if(brtn) {
- op = "B_SetAlgorithmInfo(AI_DSAParamGen)";
- break;
- }
- brtn = B_GenerateInit(genDsaAlg, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- op = "B_GenerateInit(AI_DSAParamGen)";
- break;
- }
- brtn = B_CreateAlgorithmObject(&dsaResult);
- if(brtn) {
- op = "B_CreateAlgorithmObject";
- break;
- }
- brtn = B_GenerateParameters(genDsaAlg, dsaResult, buGetRng(), NULL);
- if(brtn) {
- op = "B_GenerateParameters";
- break;
- }
-
- /* dsaResult now has the parameters, which we must extract and then
- * apply to the keypairGen object. Cool, huh? */
- brtn = B_GetAlgorithmInfo((POINTER *)&kParams, dsaResult, AI_DSAKeyGen);
- if(brtn) {
- op = "B_GetAlgorithmInfo(AI_DSAKeyGen)";
- break;
- }
- brtn = B_SetAlgorithmInfo(keypairGen, AI_DSAKeyGen, (POINTER)kParams);
- if(brtn) {
- op ="B_SetAlgorithmInfo(AI_DSAKeyGen)";
- }
- break;
- }
- default:
- printf("buGenKeyPair: algorithm not supported\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
- if(brtn) {
- goto abort;
- }
-
- /* keypairGen all set to go. */
- brtn = B_GenerateInit(keypairGen,
- BSAFE_ALGORITHM_CHOOSER,
- (A_SURRENDER_CTX *)NULL);
- if(brtn) {
- op = "B_GenerateInit";
- goto abort;
- }
- brtn = B_GenerateKeypair(keypairGen,
- bPubkey,
- bPrivkey,
- buGetRng(),
- NULL);
- if(brtn) {
- op = "B_GenerateInit";
- }
-abort:
- B_DestroyAlgorithmObject(&keypairGen);
- B_DestroyAlgorithmObject(&genDsaAlg);
- B_DestroyAlgorithmObject(&dsaResult);
- if(brtn) {
- B_DestroyKeyObject(&bPubkey);
- B_DestroyKeyObject(&bPrivkey);
- return buBsafeErrToCssm(brtn, op);
- }
- else {
- *pubKey = bPubkey;
- *privKey = bPrivkey;
- return CSSM_OK;
- }
-#endif
- return CSSM_OK;
-}
-
-/*
- * Free a key created in buGenSymKey or buGenKeyPair
- */
-CSSM_RETURN buFreeKey(
- BU_KEY key)
-{
-#if 0 // NO MORE BSAFE
- B_KEY_OBJ bkey = (B_KEY_OBJ)key;
- B_DestroyKeyObject(&bkey);
-#endif
- return CSSM_OK;
-}
-
-/*
- * encrypt/decrypt
- */
-CSSM_RETURN buEncryptDecrypt(
- BU_KEY key,
- CSSM_BOOL forEncrypt,
- CSSM_ALGORITHMS encrAlg,
- CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBC, etc.
- const CSSM_DATA *iv, //ĂŠoptional per mode
- uint32 effectiveKeyBits, // optional per key alg (actually just RC2)
- // for RSA, key size in bits
- uint32 rounds, // optional, RC5 only
- const CSSM_DATA *inData,
- CSSM_DATA_PTR outData) // mallocd and RETURNED
-{
-#if 0 // NO MORE BSAFE
- B_ALGORITHM_OBJ alg;
- int brtn;
- char fbCipher = 1;
- uint32 blockSize = 0;
- unsigned outBufLen;
- unsigned bytesMoved;
- CSSM_RETURN crtn;
- char useIv;
-
- // these variables are used in the switch below and need to
- // live until after setAlgorithm()
- ITEM bsIv;
- B_BLK_CIPHER_W_FEEDBACK_PARAMS spec;
- A_RC5_PARAMS rc5Params;
- A_RC2_PARAMS rc2Params;
-
- brtn = B_CreateAlgorithmObject(&alg);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
- }
-
- /* per-alg setup */
- switch(encrAlg) {
- case CSSM_ALGID_RC4:
- /* the easy one */
- brtn = B_SetAlgorithmInfo(alg, AI_RC4, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- fbCipher = 0;
- break;
-
- case CSSM_ALGID_RSA:
- /* assume encrypt via publicm decrypt via private */
- if(forEncrypt) {
- brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPublic, NULL);
- }
- else {
- brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPrivate, NULL);
- }
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(RSA)");
- goto abort;
- }
- blockSize = (effectiveKeyBits + 7) / 8;
- fbCipher = 0;
- break;
-
- /* common code using AI_FeebackCipher */
- case CSSM_ALGID_DES:
- spec.encryptionMethodName = (POINTER)"des";
- blockSize = 8;
- break;
- case CSSM_ALGID_DESX:
- spec.encryptionMethodName = (POINTER)"desx";
- blockSize = 8;
- break;
- case CSSM_ALGID_3DES_3KEY_EDE:
- spec.encryptionMethodName = (POINTER)"des_ede";
- blockSize = 8;
- break;
- case CSSM_ALGID_RC5:
- spec.encryptionMethodName = (POINTER)"rc5";
- spec.encryptionParams = (POINTER)&rc5Params;
- rc5Params.version = 0x10;
- rc5Params.rounds = rounds;
- rc5Params.wordSizeInBits = 32;
- blockSize = 8;
- break;
- case CSSM_ALGID_RC2:
- spec.encryptionMethodName = (POINTER)"rc2";
- spec.encryptionParams = (POINTER)&rc2Params;
- rc2Params.effectiveKeyBits = effectiveKeyBits;
- blockSize = 8;
- break;
- /* add other non-AI_FeebackCipher algorithms here */
- default:
- printf("buEncryptDecrypt: unknown algorithm\n");
- return CSSM_ERRCODE_INTERNAL_ERROR;
- }
- if(fbCipher) {
- useIv = 1; // default, except for ECB
- switch(mode) {
- case CSSM_ALGMODE_CBCPadIV8:
- spec.feedbackMethodName = (POINTER)"cbc";
- spec.paddingMethodName = (POINTER)"pad";
- break;
- case CSSM_ALGMODE_CBC_IV8:
- spec.feedbackMethodName = (POINTER)"cbc";
- spec.paddingMethodName = (POINTER)"nopad";
- break;
- case CSSM_ALGMODE_OFB_IV8:
- spec.feedbackMethodName = (POINTER)"cbc";
- spec.paddingMethodName = (POINTER)"nopad";
- break;
- case CSSM_ALGMODE_ECB:
- /* this does not seem to work yet - need info from
- * RSA. Specify block size as the feedbackParams (per manual)
- * and get a memmove error trying to copy from address 8; specify
- * an IV and get BSAFE error 524 (BE_INPUT_DATA) error on the
- * EncryptInit.
- */
- spec.feedbackMethodName = (POINTER)"ecb";
- spec.paddingMethodName = (POINTER)"nopad";
- //useIv = 0;
- //spec.feedbackParams = (POINTER)8;
- break;
- default:
- printf("buEncryptDecrypt: unknown mode\n");
- return CSSM_ERRCODE_INTERNAL_ERROR;
- }
- if(useIv && (iv != NULL)) {
- buCssmDataToItem(iv, &bsIv);
- spec.feedbackParams = (POINTER)&bsIv;
- }
-
- brtn = B_SetAlgorithmInfo(alg, AI_FeedbackCipher, (POINTER)&spec);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- }
-
- /*
- * OK, one way or another we have an algorithm object. Set up
- * output buffer.
- */
- if(forEncrypt) {
- outBufLen = inData->Length + blockSize;
- }
- else {
- outBufLen = inData->Length;
- }
- outData->Length = 0;
- outData->Data = NULL;
- crtn = appSetupCssmData(outData, outBufLen);
- if(crtn) {
- goto abort;
- }
- if(forEncrypt) {
- brtn = B_EncryptInit(alg,
- (B_KEY_OBJ)key,
- BSAFE_ALGORITHM_CHOOSER,
- (A_SURRENDER_CTX *)NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_EncryptInit");
- goto abort;
- }
- brtn = B_EncryptUpdate(alg,
- outData->Data,
- &bytesMoved,
- outBufLen,
- inData->Data,
- inData->Length,
- buGetRng(), // randAlg
- NULL); // surrender
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_EncryptInit");
- goto abort;
- }
- outData->Length = bytesMoved;
- brtn = B_EncryptFinal(alg,
- outData->Data + bytesMoved,
- &bytesMoved,
- outBufLen - outData->Length,
- buGetRng(), // randAlg
- NULL); // surrender
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_EncryptFinal");
- goto abort;
- }
- outData->Length += bytesMoved;
- crtn = CSSM_OK;
- }
- else {
- brtn = B_DecryptInit(alg,
- (B_KEY_OBJ)key,
- BSAFE_ALGORITHM_CHOOSER,
- (A_SURRENDER_CTX *)NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DecryptInit");
- goto abort;
- }
- brtn = B_DecryptUpdate(alg,
- outData->Data,
- &bytesMoved,
- outBufLen,
- inData->Data,
- inData->Length,
- NULL, // randAlg
- NULL); // surrender
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DecryptUpdate");
- goto abort;
- }
- outData->Length = bytesMoved;
- brtn = B_DecryptFinal(alg,
- outData->Data + bytesMoved,
- &bytesMoved,
- outBufLen - outData->Length,
- NULL, // randAlg
- NULL); // surrender
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DecryptFinal");
- goto abort;
- }
- outData->Length += bytesMoved;
- crtn = CSSM_OK;
- }
-abort:
- B_DestroyAlgorithmObject(&alg);
-#endif
- return 0; //crtn;
-}
-
-#if 0
-/* CSSM sig alg --> B_INFO_TYPE */
-static CSSM_RETURN cssmSigAlgToInfoType(
- CSSM_ALGORITHMS cssmAlg,
- B_INFO_TYPE *infoType)
-{
- switch(cssmAlg) {
- case CSSM_ALGID_SHA1WithRSA:
- *infoType = AI_SHA1WithRSAEncryption;
- break;
- case CSSM_ALGID_MD5WithRSA:
- *infoType = AI_MD5WithRSAEncryption;
- break;
- case CSSM_ALGID_SHA1WithDSA:
- *infoType = AI_DSAWithSHA1;
- break;
- default:
- printf("cssmSigAlgToInfoType: unknown algorithm\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
- return CSSM_OK;
-}
-#endif
-
-/*
- * Sign/verify
- */
-CSSM_RETURN buSign(
- BU_KEY key,
- CSSM_ALGORITHMS sigAlg,
- const CSSM_DATA *ptext,
- uint32 keySizeInBits, // to set up sig
- CSSM_DATA_PTR sig) // mallocd and RETURNED
-{
-#if 0 // NO MORE BSAFE
- B_ALGORITHM_OBJ alg = NULL;
- int brtn;
- B_INFO_TYPE infoType;
- CSSM_RETURN crtn;
- unsigned sigBytes;
-
- brtn = B_CreateAlgorithmObject(&alg);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
- }
- crtn = cssmSigAlgToInfoType(sigAlg, &infoType);
- if(crtn) {
- return crtn;
- }
- brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- brtn = B_SignInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SignInit");
- goto abort;
- }
- brtn = B_SignUpdate(alg, ptext->Data, ptext->Length, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SignUpdate");
- goto abort;
- }
-
- /* prepare for sig, size of key */
- sigBytes = (keySizeInBits + 7) / 8;
- sig->Data = (uint8 *)CSSM_MALLOC(sigBytes);
- sig->Length = sigBytes;
-
- brtn = B_SignFinal(alg, sig->Data, &sigBytes, sigBytes, buGetRng(), NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SignFinal");
- goto abort;
- }
- sig->Length = sigBytes;
- crtn = CSSM_OK;
-abort:
- B_DestroyAlgorithmObject(&alg);
-#endif
- return 0;//;
-}
-
-CSSM_RETURN buVerify(
- BU_KEY key,
- CSSM_ALGORITHMS sigAlg,
- const CSSM_DATA *ptext,
- const CSSM_DATA *sig) // mallocd and RETURNED
-{
-#if 0 // NO MORE BSAFE
- B_ALGORITHM_OBJ alg = NULL;
- int brtn;
- B_INFO_TYPE infoType;
- CSSM_RETURN crtn;
-
- brtn = B_CreateAlgorithmObject(&alg);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
- }
- crtn = cssmSigAlgToInfoType(sigAlg, &infoType);
- if(crtn) {
- return crtn;
- }
- brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- brtn = B_VerifyInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_VerifyInit");
- goto abort;
- }
- brtn = B_VerifyUpdate(alg, ptext->Data, ptext->Length, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_VerifyUpdate");
- goto abort;
- }
- brtn = B_VerifyFinal(alg, sig->Data, sig->Length, buGetRng(), NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_VerifyFinal");
- goto abort;
- }
- crtn = CSSM_OK;
-abort:
- B_DestroyAlgorithmObject(&alg);
- return crtn;
-#endif
- return 0;
-}
-
-/*
- * generate MAC either one update (updateSizes == NULL) or
- * specified set of update sizes.
- */
-#define MAX_MAC_SIZE 20
-
-CSSM_RETURN buGenMac(
- BU_KEY key, // any key, any size
- CSSM_ALGORITHMS macAlg, // only CSSM_ALGID_SHA1HMAC for now
- const CSSM_DATA *ptext,
- unsigned *updateSizes, // NULL --> random updates
- // else null-terminated list of sizes
- CSSM_DATA_PTR mac) // mallocd and RETURNED
-{
-#if 0 // NO MORE BSAFE
- B_ALGORITHM_OBJ alg = NULL;
- int brtn;
- CSSM_RETURN crtn;
- B_DIGEST_SPECIFIER digestInfo;
- B_INFO_TYPE infoType;
- unsigned macBytes;
-
- brtn = B_CreateAlgorithmObject(&alg);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
- }
- switch(macAlg) {
- case CSSM_ALGID_SHA1HMAC:
- case CSSM_ALGID_SHA1HMAC_LEGACY:
- digestInfo.digestInfoType = AI_SHA1;
- infoType = AI_HMAC;
- break;
- default:
- printf("buGenMac: alg not supported\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
- digestInfo.digestInfoParams = NULL;
- brtn = B_SetAlgorithmInfo(alg, infoType, (POINTER)&digestInfo);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- brtn = B_DigestInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestInit");
- goto abort;
- }
- if(updateSizes) {
- uint8 *currData = ptext->Data;
- while(*updateSizes) {
- brtn = B_DigestUpdate(alg, currData, *updateSizes, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
- goto abort;
- }
- currData += *updateSizes;
- updateSizes++;
- }
- }
- else {
- /* one-shot */
- brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
- goto abort;
- }
- }
- /* prepare for mac, magically gleaned max size */
- macBytes = MAX_MAC_SIZE;
- mac->Data = (uint8 *)CSSM_MALLOC(macBytes);
- mac->Length = macBytes;
-
- brtn = B_DigestFinal(alg, mac->Data, &macBytes, macBytes, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestFinal");
- goto abort;
- }
- mac->Length = macBytes;
- crtn = CSSM_OK;
-abort:
- B_DestroyAlgorithmObject(&alg);
- return crtn;
-#endif
- return 0;
-}
-
-/* generate digest */
-#define MAX_DIGEST_SIZE 20
-
-CSSM_RETURN buGenDigest(
- CSSM_ALGORITHMS macAlg, // CSSM_ALGID_SHA1, etc. */
- const CSSM_DATA *ptext,
- CSSM_DATA_PTR digest) // mallocd and RETURNED
-{
-#if 0 // NO MORE BSAFE
- B_ALGORITHM_OBJ alg = NULL;
- int brtn;
- CSSM_RETURN crtn;
- B_INFO_TYPE infoType;
- unsigned hashBytes;
-
- brtn = B_CreateAlgorithmObject(&alg);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
- }
- switch(macAlg) {
- case CSSM_ALGID_SHA1:
- infoType = AI_SHA1;
- break;
- case CSSM_ALGID_MD5:
- infoType = AI_MD5;
- break;
- case CSSM_ALGID_MD2:
- infoType = AI_MD2;
- break;
- default:
- printf("buGenDigest: alg not supported\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
- brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
- goto abort;
- }
- brtn = B_DigestInit(alg, NULL, BSAFE_ALGORITHM_CHOOSER, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestInit");
- goto abort;
- }
- brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
- goto abort;
- }
-
- /* prepare for digest, magically gleaned max size */
- hashBytes = MAX_DIGEST_SIZE;
- digest->Data = (uint8 *)CSSM_MALLOC(hashBytes);
- digest->Length = hashBytes;
-
- brtn = B_DigestFinal(alg, digest->Data, &hashBytes, hashBytes, NULL);
- if(brtn) {
- crtn = buBsafeErrToCssm(brtn, "B_DigestFinal");
- goto abort;
- }
- digest->Length = hashBytes;
- crtn = CSSM_OK;
-abort:
- B_DestroyAlgorithmObject(&alg);
- return crtn;
-#else
- return 0;
-#endif
-}
-
-/*
- * Convert between BSAFE and CDSA private keys
- */
-CSSM_RETURN buBsafePrivKeyToCdsa(
- CSSM_ALGORITHMS keyAlg,
- uint32 keySizeInBits,
- BU_KEY bsafePrivKey,
- CSSM_KEY_PTR cdsaPrivKey)
-{
-#if 0 // NO MORE BSAFE
- B_INFO_TYPE infoType;
- ITEM *keyBlob;
- int brtn;
- CSSM_KEYBLOB_FORMAT format;
- CSSM_KEYHEADER_PTR hdr = &cdsaPrivKey->KeyHeader;
-
- /* what kind of info? */
- switch(keyAlg) {
- case CSSM_ALGID_RSA:
- infoType = KI_PKCS_RSAPrivateBER;
- format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- case CSSM_ALGID_DSA:
- infoType = KI_DSAPrivateBER;
- format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- break;
- default:
- printf("***buBsafePrivKeyToCdsa: bogus keyAlg\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
-
- /* get the blob */
- brtn = B_GetKeyInfo((POINTER *)&keyBlob,
- (B_KEY_OBJ)bsafePrivKey,
- infoType);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_GetKeyInfo");
- }
-
- /* copy blob to CDSA key */
- cdsaPrivKey->KeyData.Data = (uint8 *)CSSM_MALLOC(keyBlob->len);
- cdsaPrivKey->KeyData.Length = keyBlob->len;
- memmove(cdsaPrivKey->KeyData.Data, keyBlob->data, keyBlob->len);
-
- /* set up CSSM key header */
- memset(hdr, 0, sizeof(CSSM_KEYHEADER));
- hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
- hdr->BlobType = CSSM_KEYBLOB_RAW;
- hdr->Format = format;
- hdr->AlgorithmId = keyAlg;
- hdr->KeyClass = CSSM_KEYCLASS_PRIVATE_KEY;
- hdr->LogicalKeySizeInBits = keySizeInBits;
- hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- hdr->KeyUsage = CSSM_KEYUSE_ANY;
-#endif
- return CSSM_OK;
-}
-
-CSSM_RETURN buCdsaPrivKeyToBsafe(
- CSSM_KEY_PTR cdsaPrivKey,
- BU_KEY *bsafePrivKey)
-{
-#if 0 // NO MORE BSAFE
- int brtn;
- B_KEY_OBJ privKey = NULL;
- ITEM keyBlob;
- B_INFO_TYPE infoType;
-
- /* what kind of info? */
- switch(cdsaPrivKey->KeyHeader.AlgorithmId) {
- case CSSM_ALGID_RSA:
- infoType = KI_PKCS_RSAPrivateBER;
- break;
- case CSSM_ALGID_DSA:
- infoType = KI_DSAPrivateBER;
- break;
- default:
- printf("***buCdsaPrivKeyToCssm: bogus keyAlg\n");
- return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
- }
-
- /* create caller's key, assign blob to it */
- brtn = B_CreateKeyObject(&privKey);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_CreateKeyObject");
- }
- buCssmDataToItem(&cdsaPrivKey->KeyData, &keyBlob);
- brtn = B_SetKeyInfo(privKey, infoType, (POINTER)&keyBlob);
- if(brtn) {
- return buBsafeErrToCssm(brtn, "B_SetKeyInfo");
- }
- *bsafePrivKey = privKey;
-#endif
- return CSSM_OK;
-}
-