#include <openssl/rc2.h>
#include <misc/rc2_locl.h>
#include "rc2Context.h"
RC2Context::~RC2Context()
{
memset(&rc2Key, 0, sizeof(RC2_KEY));
}
void RC2Context::init(
const Context &context,
bool encrypting)
{
UInt32 keyLen;
UInt8 *keyData = NULL;
UInt32 effectiveBits;
symmetricKeyBits(context, CSSM_ALGID_RC2,
encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
keyData, keyLen);
if((keyLen < RC2_MIN_KEY_SIZE_BYTES) || (keyLen > RC2_MAX_KEY_SIZE_BYTES)) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
effectiveBits = context.getInt(CSSM_ATTRIBUTE_EFFECTIVE_BITS);
if(effectiveBits == 0) {
CssmKey &key = context.get<CssmKey>(CSSM_ATTRIBUTE_KEY,
CSSMERR_CSP_MISSING_ATTR_KEY);
effectiveBits = key.KeyHeader.LogicalKeySizeInBits;
}
RC2_set_key(&rc2Key, keyLen, keyData, effectiveBits);
setup(RC2_BLOCK_SIZE_BYTES, context);
}
void RC2Context::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final) {
if(plainTextLen != RC2_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
}
if(cipherTextLen < RC2_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
RC2_INT d[2];
RC2_INT l;
c2l((unsigned char *)plainText, l); d[0]=l;
c2l((unsigned char *)plainText, l); d[1]=l;
RC2_encrypt(d, &rc2Key);
l=d[0]; l2c(l, (unsigned char *)cipherText);
l=d[1]; l2c(l, (unsigned char *)cipherText);
cipherTextLen = RC2_BLOCK_SIZE_BYTES;
}
void RC2Context::decryptBlock(
const void *cipherText, void *plainText,
size_t &plainTextLen, bool final) {
if(plainTextLen < RC2_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
RC2_INT d[2];
RC2_INT l;
c2l((unsigned char *)cipherText, l); d[0]=l;
c2l((unsigned char *)cipherText, l); d[1]=l;
RC2_decrypt(d, &rc2Key);
l=d[0]; l2c(l, (unsigned char *)plainText);
l=d[1]; l2c(l, (unsigned char *)plainText);
plainTextLen = RC2_BLOCK_SIZE_BYTES;
}