#include <openssl/rc5_legacy.h>
#include <misc/rc5_locl.h>
#include "rc5Context.h"
RC5Context::~RC5Context()
{
memset(&rc5Key, 0, sizeof(RC5_32_KEY));
}
void RC5Context::init(
const Context &context,
bool encrypting)
{
CSSM_SIZE keyLen;
uint8 *keyData = NULL;
uint32 rounds = RC5_16_ROUNDS;
symmetricKeyBits(context, session(), CSSM_ALGID_RC5,
encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
keyData, keyLen);
if((keyLen < RC5_MIN_KEY_SIZE_BYTES) || (keyLen > RC5_MAX_KEY_SIZE_BYTES)) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
}
rounds = context.getInt(CSSM_ATTRIBUTE_ROUNDS);
if(rounds == 0) {
rounds = RC5_16_ROUNDS;
}
RC5_32_set_key(&rc5Key, (int)keyLen, keyData, rounds);
setup(RC5_BLOCK_SIZE_BYTES, context);
}
void RC5Context::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final) {
if(plainTextLen != RC5_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
}
if(cipherTextLen < RC5_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
RC5_32_INT d[2];
RC5_32_INT l;
const unsigned char *pt = (const unsigned char *)plainText;
c2l(pt, l); d[0]=l;
c2l(pt, l); d[1]=l;
RC5_32_encrypt(d, &rc5Key);
unsigned char *ct = (unsigned char *)cipherText;
l=d[0]; l2c(l, ct);
l=d[1]; l2c(l, ct);
cipherTextLen = RC5_BLOCK_SIZE_BYTES;
}
void RC5Context::decryptBlock(
const void *cipherText, size_t cipherTextLen,
void *plainText,
size_t &plainTextLen, bool final) {
if(plainTextLen < RC5_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
RC5_32_INT d[2];
RC5_32_INT l;
const unsigned char *ct = (const unsigned char *)cipherText;
c2l(ct, l); d[0]=l;
c2l(ct, l); d[1]=l;
RC5_32_decrypt(d, &rc5Key);
unsigned char *pt = (unsigned char *)plainText;
l=d[0]; l2c(l, pt);
l=d[1]; l2c(l, pt);
plainTextLen = RC5_BLOCK_SIZE_BYTES;
}