/* * Staged init - cook up a CSSM_CC_HANDLE and call the appropriate * init. */ CSSM_RETURN cdsaStagedEncDecrInit( CSSM_CSP_HANDLE cspHandle, // from cdsaCspAttach() const CSSM_KEY *key, // from cdsaDeriveKey() StagedOpType opType, // SO_Encrypt, SO_Decrypt CSSM_CC_HANDLE *ccHandle) // RETURNED { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHand; crtn = genCryptHandle(cspHandle, key, &ivCommon, &ccHand); if(crtn) { return crtn; } switch(opType) { case SO_Encrypt: crtn = CSSM_EncryptDataInit(ccHand); break; case SO_Decrypt: crtn = CSSM_DecryptDataInit(ccHand); break; default: return CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED; } if(crtn) { CSSM_DeleteContext(ccHand); } else { *ccHandle = ccHand; } return CSSM_OK; }
/* * Decrypt. * plainText->Data is allocated by the CSP and must be freed (via * free()) by caller. */ CSSM_RETURN cdsaDecrypt( CSSM_CSP_HANDLE cspHandle, const CSSM_KEY *key, const CSSM_DATA *cipherText, CSSM_DATA_PTR plainText) { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHandle; CSSM_DATA remData = {0, NULL}; uint32 bytesDecrypted; crtn = genCryptHandle(cspHandle, key, &ivCommon, &ccHandle); if(crtn) { return crtn; } plainText->Length = 0; plainText->Data = NULL; crtn = CSSM_DecryptData(ccHandle, cipherText, 1, plainText, 1, &bytesDecrypted, &remData); CSSM_DeleteContext(ccHandle); if(crtn) { return crtn; } plainText->Length = bytesDecrypted; if(remData.Length != 0) { /* append remaining data to plainText */ uint32 newLen = plainText->Length + remData.Length; plainText->Data = (uint8 *)appRealloc(plainText->Data, newLen, NULL); memmove(plainText->Data + plainText->Length, remData.Data, remData.Length); plainText->Length = newLen; appFree(remData.Data, NULL); } return CSSM_OK; }
static int badDecrypt( CSSM_CSP_HANDLE cspHand, CSSM_KEY_PTR key, const char *keyAlgStr, CSSM_ALGORITHMS opAlg, CSSM_RETURN expectRtn, CSSM_BOOL quiet, const char *goodUseStr, const char *badUseStr) { CSSM_CC_HANDLE cryptHand; CSSM_DATA ctext = {4, (uint8 *)"foo"}; CSSM_DATA ptext = {0, NULL}; CSSM_DATA remData = {0, NULL}; CSSM_RETURN crtn; CSSM_SIZE bytesDecrypted; int irtn; cryptHand = genCryptHandle(cspHand, opAlg, CSSM_ALGMODE_NONE, CSSM_PADDING_NONE, key, NULL /* key2 */, NULL /* iv */, 0, 0); if(cryptHand == 0) { return testError(quiet); } crtn = CSSM_DecryptData(cryptHand, &ctext, 1, &ptext, 1, &bytesDecrypted, &remData); if(crtn != expectRtn) { printf("***Testing %s key w/%s during %s:\n", keyAlgStr, goodUseStr, badUseStr); printf(" CSSM_DecryptData: expect %s\n", cssmErrToStr(expectRtn)); printf(" CSSM_DecryptData: got %s\n", cssmErrToStr(crtn)); irtn = testError(quiet); } else { irtn = 0; } /* assume no ptext or remdata - OK? */ CSSM_DeleteContext(cryptHand); return irtn; }
/* * CDSA private key decrypt with blinding option. */ static 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. CSSM_BOOL blinding, const CSSM_KEY *key, // public or session key const CSSM_DATA *ctext, CSSM_DATA_PTR ptext) // RETURNED { CSSM_CC_HANDLE cryptHand; CSSM_RETURN crtn; CSSM_RETURN ocrtn = CSSM_OK; CSSM_SIZE bytesDecrypted; CSSM_DATA remData = {0, NULL}; cryptHand = genCryptHandle(cspHand, algorithm, mode, padding, key, NULL, // pubKey, NULL, // iv, 0, // effectiveKeySizeInBits, 0); // rounds if(cryptHand == 0) { return CSSMERR_CSP_INTERNAL_ERROR; } if(blinding) { CSSM_CONTEXT_ATTRIBUTE newAttr; newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; newAttr.AttributeLength = sizeof(uint32); newAttr.Attribute.Uint32 = 1; crtn = CSSM_UpdateContextAttributes(cryptHand, 1, &newAttr); if(crtn) { printError("CSSM_UpdateContextAttributes", crtn); return crtn; } } crtn = CSSM_DecryptData(cryptHand, ctext, 1, ptext, 1, &bytesDecrypted, &remData); if(crtn == CSSM_OK) { // 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; } crtn = CSSM_DeleteContext(cryptHand); if(crtn) { printError("CSSM_DeleteContext", crtn); ocrtn = crtn; } return ocrtn; }