in xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp [130:236]
int WinCAPICryptoSymmetricKey::decryptCtxInit(const unsigned char * iv) {
// Returns amount of IV data used (in bytes)
// Sets m_initialised iff the key is OK and the IV is OK.
if (m_initialised)
return 0;
if (m_k == 0) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Cannot initialise without key");
}
else if (m_keyMode == MODE_NONE) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Cannot initialise without mode");
}
DWORD cryptMode;
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
return 0; // Cannot initialise without an IV
}
cryptMode = CRYPT_MODE_CBC;
if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Error setting cipher mode");
}
if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) iv, 0)) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Error setting IV");
}
}
else if (m_keyMode == MODE_ECB) {
cryptMode = CRYPT_MODE_ECB;
if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Error setting cipher mode");
}
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Unknown cipher mode");
}
// Set up the context according to the required cipher type
switch (m_keyType) {
case (XSECCryptoSymmetricKey::KEY_3DES_192) :
// A 3DES CBC key
m_blockSize = 8;
m_bytesInLastBlock = 0;
m_initialised = true;
break;
case (XSECCryptoSymmetricKey::KEY_AES_128) :
case (XSECCryptoSymmetricKey::KEY_AES_192) :
case (XSECCryptoSymmetricKey::KEY_AES_256) :
// An AES key
m_blockSize = 16;
m_bytesInLastBlock = 0;
m_initialised = true;
break;
default :
// Cannot do this without an IV
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Unknown key type");
}
// Setup ivSize
switch (m_keyMode) {
case MODE_CBC:
m_ivSize = m_blockSize;
break;
case MODE_GCM:
m_ivSize = 12;
break;
default:
m_ivSize = 0;
}
return m_ivSize;
}