FEEAsymmetricContext.cpp [plain text]
#ifdef CRYPTKIT_CSP_ENABLE
#include "FEEAsymmetricContext.h"
#include "FEECSPUtils.h"
#include <Security/utilities.h>
static void validateFeedContext(
const Context &context)
{
uint32 blockSize = context.getInt(CSSM_ATTRIBUTE_BLOCK_SIZE);
if(blockSize != 0) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_BLOCK_SIZE);
}
CSSM_ENCRYPT_MODE cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE);
if(cssmMode != 0) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
}
#if 0
CssmData *iv = context.get<CssmData>(CSSM_ATTRIBUTE_INIT_VECTOR);
if(iv != NULL) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR);
}
#endif
CSSM_PADDING padding = context.getInt(CSSM_ATTRIBUTE_PADDING);
if(padding != 0) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
}
}
CryptKit::FEEDContext::~FEEDContext()
{
if(mFeeFeed) {
feeFEEDFree(mFeeFeed);
mFeeFeed = NULL;
}
if(mPrivKey && mAllocdPrivKey) {
feePubKeyFree(mPrivKey);
}
if(mPubKey && mAllocdPubKey) {
feePubKeyFree(mPubKey);
}
mPrivKey = NULL;
mPubKey = NULL;
mInitFlag = false;
}
void CryptKit::FEEDContext::init(
const Context &context,
bool encoding)
{
if(mInitFlag && !opStarted()) {
return;
}
if(mPrivKey == NULL) {
assert(!opStarted());
mPrivKey = contextToFeeKey(context,
session(),
CSSM_ATTRIBUTE_KEY,
CSSM_KEYCLASS_PRIVATE_KEY,
CSSM_KEYUSE_ANY,
mAllocdPrivKey);
}
else {
assert(opStarted());
}
if(mPubKey == NULL) {
assert(!opStarted());
mPubKey = contextToFeeKey(context,
session(),
CSSM_ATTRIBUTE_PUBLIC_KEY,
CSSM_KEYCLASS_PUBLIC_KEY,
CSSM_KEYUSE_ANY,
mAllocdPubKey);
}
else {
assert(opStarted());
}
validateFeedContext(context);
if(mFeeFeed != NULL) {
assert(opStarted());
feeFEEDFree(mFeeFeed);
mFeeFeed = NULL;
}
mFeeFeed = feeFEEDNewWithPubKey(mPrivKey,
mPubKey,
encoding ? 1 : 0,
feeRandCallback,
&session());
if(mFeeFeed == NULL) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
unsigned plainBlockSize = feeFEEDPlainBlockSize(mFeeFeed);
unsigned cipherBlockSize = feeFEEDCipherBlockSize(mFeeFeed);
setup(encoding ? plainBlockSize : cipherBlockSize, encoding ? cipherBlockSize : plainBlockSize, false, true, BCM_ECB,
NULL); mInitFlag = true;
}
void CryptKit::FEEDContext::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final)
{
feeReturn frtn;
unsigned actMoved;
assert(mFeeFeed != NULL);
frtn = feeFEEDEncryptBlock(mFeeFeed,
(unsigned char *)plainText,
plainTextLen,
(unsigned char *)cipherText,
&actMoved,
final ? 1 : 0);
if(frtn) {
throwCryptKit(frtn, "feeFEEDEncryptBlock");
}
if(actMoved > cipherTextLen) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
cipherTextLen = actMoved;
}
void CryptKit::FEEDContext::decryptBlock(
const void *cipherText, void *plainText,
size_t &plainTextLen, bool final)
{
feeReturn frtn;
unsigned actMoved;
assert(mFeeFeed != NULL);
frtn = feeFEEDDecryptBlock(mFeeFeed,
(unsigned char *)cipherText,
inBlockSize(),
(unsigned char *)plainText,
&actMoved,
final ? 1 : 0);
if(frtn) {
throwCryptKit(frtn, "feeFEEDDecryptBlock");
}
if(actMoved > plainTextLen) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
plainTextLen = actMoved;
}
#define BUFFER_DEBUG 0
#if BUFFER_DEBUG
#define bprintf(s) printf s
#else
#define bprintf(s)
#endif
size_t CryptKit::FEEDContext::inputSize(
size_t outSize) {
unsigned inSize;
if(encoding()) {
inSize = feeFEEDPlainTextSize(mFeeFeed, outSize, 0);
}
else {
inSize = feeFEEDCipherTextSize(mFeeFeed, outSize, 0);
}
if(inSize >= inBufSize()) {
inSize -= inBufSize();
}
unsigned inBlocks = ((inSize + inBlockSize()) / inBlockSize());
inSize = (inBlocks * inBlockSize()) - 1;
bprintf(("--- FEEDContext::inputSize inSize 0x%x outSize 0x%x\n",
inSize, outSize));
return inSize;
}
size_t CryptKit::FEEDContext::outputSize(
bool final,
size_t inSize) {
size_t rtn;
if(encoding()) {
rtn = feeFEEDCipherTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
}
else {
rtn = feeFEEDPlainTextSize(mFeeFeed, inSize + inBufSize(), final ? 1 : 0);
}
bprintf(("--- FEEDContext::outputSize inSize 0x%x outSize 0x%x final %d\n",
inSize, rtn, final));
return rtn;
}
void CryptKit::FEEDContext::minimumProgress(
size_t &in,
size_t &out) {
if(encoding()) {
in = inBlockSize();
out = feeFEEDCipherBufSize(mFeeFeed, 0);
}
else {
in = feeFEEDCipherBufSize(mFeeFeed, 0);
out = outBlockSize();
}
assert(in >= inBufSize());
in -= inBufSize();
if(in == 0) {
in++;
}
bprintf(("--- FEEDContext::minProgres inSize 0x%x outSize 0x%x\n",
in, out));
}
CryptKit::FEEDExpContext::~FEEDExpContext()
{
if(mFeeFeedExp) {
feeFEEDExpFree(mFeeFeedExp);
mFeeFeedExp = NULL;
}
if(mFeeKey && mAllocdFeeKey) {
feePubKeyFree(mFeeKey);
}
mFeeKey = NULL;
mInitFlag = false;
}
void CryptKit::FEEDExpContext::init(
const Context &context,
bool encoding)
{
if(mInitFlag && !opStarted()) {
return;
}
CSSM_KEYCLASS keyClass;
CSSM_KEYUSE keyUse;
if(encoding) {
keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
keyUse = CSSM_KEYUSE_ENCRYPT;
}
else {
keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
keyUse = CSSM_KEYUSE_DECRYPT;
}
if(mFeeKey == NULL) {
assert(!opStarted());
mFeeKey = contextToFeeKey(context,
session(),
CSSM_ATTRIBUTE_KEY,
keyClass,
keyUse,
mAllocdFeeKey);
}
else {
assert(opStarted());
}
validateFeedContext(context);
if(mFeeFeedExp != NULL) {
assert(opStarted());
feeFEEDExpFree(mFeeFeedExp);
mFeeFeedExp = NULL;
}
mFeeFeedExp = feeFEEDExpNewWithPubKey(mFeeKey,
feeRandCallback,
&session());
if(mFeeFeedExp == NULL) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
unsigned plainBlockSize = feeFEEDExpPlainBlockSize(mFeeFeedExp);
unsigned cipherBlockSize = feeFEEDExpCipherBlockSize(mFeeFeedExp);
setup(encoding ? plainBlockSize : cipherBlockSize, encoding ? cipherBlockSize : plainBlockSize, false, true, BCM_ECB,
NULL); mInitFlag = true;
}
void CryptKit::FEEDExpContext::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final)
{
feeReturn frtn;
unsigned actMoved;
assert(mFeeFeedExp != NULL);
frtn = feeFEEDExpEncryptBlock(mFeeFeedExp,
(unsigned char *)plainText,
plainTextLen,
(unsigned char *)cipherText,
&actMoved,
final ? 1 : 0);
if(frtn) {
throwCryptKit(frtn, "feeFEEDExpEncryptBlock");
}
if(actMoved > cipherTextLen) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
cipherTextLen = actMoved;
}
void CryptKit::FEEDExpContext::decryptBlock(
const void *cipherText, void *plainText,
size_t &plainTextLen, bool final)
{
feeReturn frtn;
unsigned actMoved;
assert(mFeeFeedExp != NULL);
frtn = feeFEEDExpDecryptBlock(mFeeFeedExp,
(unsigned char *)cipherText,
inBlockSize(),
(unsigned char *)plainText,
&actMoved,
final ? 1 : 0);
if(frtn) {
throwCryptKit(frtn, "feeFEEDExpDecryptBlock");
}
if(actMoved > plainTextLen) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
plainTextLen = actMoved;
}
#endif