gladmanContext.cpp [plain text]
#include "gladmanContext.h"
#include "cspdebugging.h"
class GladmanInit
{
public:
GladmanInit() : mTablesGenerated(false) { }
void genTables();
private:
bool mTablesGenerated;
Mutex mLock;
};
void GladmanInit::genTables()
{
StLock<Mutex> _(mLock);
if(mTablesGenerated) {
return;
}
CssmAllocator &alloc = CssmAllocator::standard(CssmAllocator::sensitive);
pow_tab = (u1byte *)alloc.malloc(POW_TAB_SIZE * sizeof(u1byte));
log_tab = (u1byte *)alloc.malloc(LOG_TAB_SIZE * sizeof(u1byte));
sbx_tab = (u1byte *)alloc.malloc(SBX_TAB_SIZE * sizeof(u1byte));
isb_tab = (u1byte *)alloc.malloc(ISB_TAB_SIZE * sizeof(u1byte));
rco_tab = (u4byte *)alloc.malloc(RCO_TAB_SIZE * sizeof(u4byte));
ft_tab = (u4byte (*)[FT_TAB_SIZE_LS])alloc.malloc(
FT_TAB_SIZE_LS * FT_TAB_SIZE_MS * sizeof(u4byte));
it_tab = (u4byte (*)[IT_TAB_SIZE_LS])alloc.malloc(
IT_TAB_SIZE_LS * IT_TAB_SIZE_MS * sizeof(u4byte));
#ifdef LARGE_TABLES
fl_tab = (u4byte (*)[FL_TAB_SIZE_LS])alloc.malloc(
FL_TAB_SIZE_LS * FL_TAB_SIZE_MS * sizeof(u4byte));
il_tab = (u4byte (*)[IL_TAB_SIZE_LS])alloc.malloc(
IL_TAB_SIZE_LS * IL_TAB_SIZE_MS * sizeof(u4byte));
#endif
gen_tabs();
mTablesGenerated = true;
}
static ModuleNexus<GladmanInit> gladmanInit;
GAESContext::GAESContext(AppleCSPSession &session) :
BlockCryptor(session),
mKeyValid(false),
mInitFlag(false),
mRawKeySize(0)
{
gladmanInit().genTables();
}
GAESContext::~GAESContext()
{
deleteKey();
memset(mRawKey, 0, MAX_AES_KEY_BITS / 8);
mInitFlag = false;
}
void GAESContext::deleteKey()
{
memset(&mAesKey, 0, sizeof(GAesKey));
mKeyValid = false;
}
void GAESContext::init(
const Context &context,
bool encrypting)
{
if(mInitFlag && !opStarted()) {
return;
}
UInt32 keyLen;
UInt8 *keyData = NULL;
bool sameKeySize = false;
symmetricKeyBits(context, CSSM_ALGID_AES,
encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
keyData, keyLen);
if(mRawKeySize == keyLen) {
sameKeySize = true;
}
else {
deleteKey();
}
if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) {
set_key((u4byte *)keyData, keyLen * 8, &mAesKey);
memmove(mRawKey, keyData, keyLen);
mRawKeySize = keyLen;
}
setup(GLADMAN_BLOCK_SIZE_BYTES, context);
mInitFlag = true;
}
void GAESContext::encryptBlock(
const void *plainText, size_t plainTextLen,
void *cipherText,
size_t &cipherTextLen, bool final) {
if(plainTextLen != GLADMAN_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
}
if(cipherTextLen < GLADMAN_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
rEncrypt((u4byte *)plainText, (u4byte *)cipherText, &mAesKey);
cipherTextLen = GLADMAN_BLOCK_SIZE_BYTES;
}
void GAESContext::decryptBlock(
const void *cipherText, void *plainText,
size_t &plainTextLen, bool final) {
if(plainTextLen < GLADMAN_BLOCK_SIZE_BYTES) {
CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
}
rDecrypt((u4byte *)cipherText, (u4byte *)plainText, &mAesKey);
plainTextLen = GLADMAN_BLOCK_SIZE_BYTES;
}