in xsec/enc/NSS/NSSCryptoSymmetricKey.cpp [171:288]
int NSSCryptoSymmetricKey::decryptCtxInit(const unsigned char * iv) {
// Returns amount of IV data used (in bytes)
// Sets m_initialised if the key is OK and the IV is OK.
if (m_initialised)
return 0;
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");
}
// Set up the context according to the required cipher type
switch (m_keyType) {
case (XSECCryptoSymmetricKey::KEY_3DES_192) :
// A 3DES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
return 0; // Cannot initialise without an IV
}
SECItem ivItem;
ivItem.data = (unsigned char*)iv;
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_DECRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 8;
}
else if (m_keyMode == MODE_ECB) {
SECItem * secParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 0;
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unrecognized 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) {
return 0; // Cannot initialise without an IV
}
SECItem ivItem;
ivItem.data = (unsigned char*)iv;
ivItem.len = 16;
SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_DECRYPT, 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_DECRYPT, mp_k, secParam);
if (secParam)
SECITEM_FreeItem(secParam, PR_TRUE);
m_ivSize = 0;
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unrecognized cipher mode");
}
break;
default :
// Cannot do this without an IV
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"NSS:SymmetricKey - Unknown key type");
}
// Reset some parameters
m_initialised = true;
// Return number of bytes chewed up by IV
return m_ivSize;
}