#include <openssl/rc2_legacy.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)
{
CSSM_SIZE keyLen;
uint8 *keyData = NULL;
uint32 effectiveBits;
symmetricKeyBits(context, session(), 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, (int)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;
const unsigned char *pt = (const unsigned char *)plainText;
c2l(pt, l); d[0]=l;
c2l(pt, l); d[1]=l;
RC2_encrypt(d, &rc2Key);
unsigned char *ct = (unsigned char *)cipherText;
l=d[0]; l2c(l, ct);
l=d[1]; l2c(l, ct);
cipherTextLen = RC2_BLOCK_SIZE_BYTES;
}
void RC2Context::decryptBlock(
const void *cipherText, size_t cipherTextLen,
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;
const unsigned char *ct = (const unsigned char *)cipherText;
c2l(ct, l); d[0]=l;
c2l(ct, l); d[1]=l;
RC2_decrypt(d, &rc2Key);
unsigned char *pt = (unsigned char *)plainText;
l=d[0]; l2c(l, pt);
l=d[1]; l2c(l, pt);
plainTextLen = RC2_BLOCK_SIZE_BYTES;
}