RSA_asymmetric.cpp [plain text]
#include "RSA_asymmetric.h"
#include "RSA_DSA_utils.h"
#include <Security/debugging.h>
#define rsaCryptDebug(args...) debug("rsaCrypt", ## args)
#define rbprintf(args...) debug("rsaBuf", ## args)
RSA_CryptContext::~RSA_CryptContext()
{
if(mAllocdRsaKey) {
assert(mRsaKey != NULL);
RSA_free(mRsaKey);
mRsaKey = NULL;
mAllocdRsaKey = false;
}
}
void RSA_CryptContext::init(const Context &context, bool encoding = true)
{
if(mInitFlag && !opStarted()) {
return;
}
CSSM_KEYCLASS keyClass;
switch (context.getInt(CSSM_ATTRIBUTE_MODE)) {
case CSSM_ALGMODE_PUBLIC_KEY:
keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
break;
case CSSM_ALGMODE_PRIVATE_KEY:
keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
break;
case CSSM_ALGMODE_NONE:
keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY;
break;
default:
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
}
if(mRsaKey == NULL) {
assert(!opStarted());
mRsaKey = contextToRsaKey(context,
session(),
keyClass,
encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
mAllocdRsaKey);
}
else {
assert(opStarted());
}
unsigned cipherBlockSize = RSA_size(mRsaKey);
unsigned plainBlockSize = cipherBlockSize - 11;
setup(encoding ? plainBlockSize : cipherBlockSize, encoding ? cipherBlockSize : plainBlockSize, false, false, BCM_ECB,
NULL); mInitFlag = true;
}
void RSA_CryptContext::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final)
{
int irtn;
if(mRsaKey->d == NULL) {
irtn = RSA_public_encrypt(plainTextLen,
(unsigned char *)plainText,
(unsigned char *)cipherText,
mRsaKey,
RSA_PKCS1_PADDING);
}
else {
irtn = RSA_private_encrypt(plainTextLen,
(unsigned char *)plainText,
(unsigned char *)cipherText,
mRsaKey,
RSA_PKCS1_PADDING);
}
if(irtn < 0) {
throwRsaDsa("RSA_public_encrypt");
}
else if((unsigned)irtn > cipherTextLen) {
rsaCryptDebug("RSA_public_encrypt overflow");
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
cipherTextLen = (size_t)irtn;
}
void RSA_CryptContext::decryptBlock(
const void *cipherText, void *plainText,
size_t &plainTextLen, bool final)
{
int irtn;
if(mRsaKey->d == NULL) {
irtn = RSA_public_decrypt(inBlockSize(),
(unsigned char *)cipherText,
(unsigned char *)plainText,
mRsaKey,
RSA_PKCS1_PADDING);
}
else {
irtn = RSA_private_decrypt(inBlockSize(),
(unsigned char *)cipherText,
(unsigned char *)plainText,
mRsaKey,
RSA_PKCS1_PADDING);
}
if(irtn < 0) {
throwRsaDsa("RSA_private_decrypt");
}
else if((unsigned)irtn > plainTextLen) {
rsaCryptDebug("RSA_private_decrypt overflow");
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
plainTextLen = (size_t)irtn;
}
size_t RSA_CryptContext::outputSize(
bool final, size_t inSize = 0) {
UInt32 rawBytes = inSize + inBufSize();
UInt32 rawBlocks = (rawBytes + inBlockSize() - 1) / inBlockSize();
rbprintf("--- RSA_CryptContext::outputSize inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx",
inSize, rawBlocks * outBlockSize(), inBufSize());
return rawBlocks * outBlockSize();
}