in xsec/enc/NSS/NSSCryptoSymmetricKey.cpp [381:530]
bool NSSCryptoSymmetricKey::encryptInit(bool doPad,
SymmetricKeyMode mode,
const unsigned char * iv) {
if (m_initialised == true)
return true;
m_doPad = doPad;
m_keyMode = mode;
if (mp_k == 0) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Cannot initialise without key");
}
else if (m_keyMode == MODE_NONE) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Cannot initialise without mode");
}
// Do some parameter initialisation
m_initialised = true;
// Set up the context according to the required cipher type
const unsigned char * usedIV = NULL;
unsigned char genIV[256];
// Tell the library that the IV still has to be sent
m_ivSent = false;
switch (m_keyType) {
case (XSECCryptoSymmetricKey::KEY_3DES_192) :
// A 3DES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
SECStatus s = PK11_GenerateRandom(genIV, 8);
if (s != SECSuccess) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
SECItem ivItem;
ivItem.data = (unsigned char*)usedIV;
ivItem.len = 8;
int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);
SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_ENCRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 8;
}
else if (m_keyMode == MODE_ECB) {
mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, mp_k, NULL);
m_ivSize = 0;
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unsupported DES3 cipher mode");
}
break;
case (XSECCryptoSymmetricKey::KEY_AES_128) :
case (XSECCryptoSymmetricKey::KEY_AES_192) :
case (XSECCryptoSymmetricKey::KEY_AES_256) :
// An AES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
SECStatus s = PK11_GenerateRandom(genIV, 16);
if (s != SECSuccess) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
SECItem ivItem;
ivItem.data = (unsigned char*)usedIV;
ivItem.len = 16;
SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_ENCRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 16;
}
else if (m_keyMode == MODE_ECB) {
SECItem * secParam = PK11_ParamFromIV(CKM_AES_ECB, NULL);
mp_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_ENCRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 0;
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unsupported AES cipher mode");
}
break;
default :
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unknown key type");
}
// Add IV
if (m_keyMode == MODE_CBC || m_keyMode == MODE_GCM) {
memcpy(m_lastBlock, usedIV, m_ivSize);
}
return true;
}