in xsec/enc/WinCAPI/WinCAPICryptoSymmetricKey.cpp [356:477]
void WinCAPICryptoSymmetricKey::encryptCtxInit(const unsigned char * iv) {
if (m_initialised == true)
return;
if (m_keyLen == 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");
}
m_initialised = true;
// Set up the context according to the required cipher type
const unsigned char * usedIV = NULL;
unsigned char genIV[256];
DWORD cryptMode;
// Tell the library that the IV still has to be sent
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
BOOL res = CryptGenRandom(m_p, 256, genIV);
if (res == FALSE) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
//return 0; // Cannot initialise without an IV
}
else
usedIV = iv;
cryptMode = CRYPT_MODE_CBC;
if (!CryptSetKeyParam(m_k, KP_MODE, (BYTE *) (&cryptMode), 0)) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Error setting cipher mode");
}
// Set the IV parameter
if (!CryptSetKeyParam(m_k, KP_IV, (unsigned char *) usedIV, 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,
"OpenSSL:SymmetricKey - Unsupported cipher mode");
}
switch (m_keyType) {
case (XSECCryptoSymmetricKey::KEY_3DES_192) :
// A 3DES key
m_blockSize = 8;
if (m_keyMode == MODE_CBC)
m_ivSize = 8;
else
m_ivSize = 0;
m_bytesInLastBlock = 0;
break;
case (XSECCryptoSymmetricKey::KEY_AES_128) :
case (XSECCryptoSymmetricKey::KEY_AES_192) :
case (XSECCryptoSymmetricKey::KEY_AES_256) :
// An AES key
m_blockSize = 16;
if (m_keyMode == MODE_CBC)
m_ivSize = 16;
else if (m_keyMode == MODE_GCM)
m_ivSize = 12;
else
m_ivSize = 0;
m_bytesInLastBlock = 0;
break;
default :
// Cannot do this without an IV
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"WinCAPI:SymmetricKey - Unknown key type");
}
if (usedIV != NULL && m_ivSize > 0)
memcpy(m_lastBlock, usedIV, m_ivSize);
}