in xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp [603:891]
bool OpenSSLCryptoSymmetricKey::encryptInit(bool doPad,
SymmetricKeyMode mode,
const unsigned char * iv) {
if (m_initialised == true)
return true;
m_doPad = doPad;
m_keyMode = mode;
if (m_keyLen == 0) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Cannot initialise without key");
}
else if (m_keyMode == MODE_NONE) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Cannot initialise without mode");
}
// Do some parameter initialisation
m_initialised = true;
m_bytesInLastBlock = 0;
// 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) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 8) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else {
usedIV = iv;
}
#if defined (XSEC_OPENSSL_CONST_BUFFERS)
EVP_EncryptInit(mp_ctx, EVP_des_ede3_cbc(), m_keyBuf.rawBuffer(), usedIV);
#else
EVP_EncryptInit(mp_ctx, EVP_des_ede3_cbc(), (unsigned char *) m_keyBuf.rawBuffer(), (unsigned char *) usedIV);
#endif
}
else if (m_keyMode == MODE_ECB) {
#if defined (XSEC_OPENSSL_CONST_BUFFERS)
EVP_EncryptInit(mp_ctx, EVP_des_ede3_ecb(), m_keyBuf.rawBuffer(), NULL);
#else
EVP_EncryptInit(mp_ctx, EVP_des_ede3(), (unsigned char *) m_keyBuf.rawBuffer(), NULL);
#endif
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Unsupported DES3 cipher mode");
}
m_blockSize = 8;
break;
#if defined (XSEC_OPENSSL_HAVE_AES)
case (XSECCryptoSymmetricKey::KEY_AES_128) :
// An AES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
else if (m_keyMode == MODE_ECB) {
EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
}
#ifdef XSEC_OPENSSL_HAVE_GCM
else if (m_keyMode == MODE_GCM) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_128_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
#endif
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Unsupported AES cipher mode");
}
m_blockSize = 16;
break;
case (XSECCryptoSymmetricKey::KEY_AES_192) :
// An AES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
#ifdef XSEC_OPENSSL_HAVE_GCM
else if (m_keyMode == MODE_GCM) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
#endif
else if (m_keyMode == MODE_ECB) {
EVP_EncryptInit_ex(mp_ctx, EVP_aes_192_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Unsupported AES cipher mode");
}
m_blockSize = 16;
break;
case (XSECCryptoSymmetricKey::KEY_AES_256) :
// An AES key
if (m_keyMode == MODE_CBC) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 16) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_cbc(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
#ifdef XSEC_OPENSSL_HAVE_GCM
else if (m_keyMode == MODE_GCM) {
if (iv == NULL) {
bool res = ((RAND_status() == 1) && (RAND_bytes(genIV, 12) == 1));
if (res == false) {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Error generating random IV");
}
usedIV = genIV;
}
else
usedIV = iv;
EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_gcm(), NULL, m_keyBuf.rawBuffer(), usedIV);
}
#endif
else if (m_keyMode == MODE_ECB) {
EVP_EncryptInit_ex(mp_ctx, EVP_aes_256_ecb(), NULL, m_keyBuf.rawBuffer(), NULL);
}
else {
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Unsupported AES cipher mode");
}
m_blockSize = 16;
break;
#else
case (XSECCryptoSymmetricKey::KEY_AES_128) :
case (XSECCryptoSymmetricKey::KEY_AES_192) :
case (XSECCryptoSymmetricKey::KEY_AES_256) :
throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
"OpenSSL:SymmetricKey - AES not supported in this version of OpenSSL");
#endif /* XSEC_OPENSSL_HAVE_AES */
default :
throw XSECCryptoException(XSECCryptoException::SymmetricError,
"OpenSSL:SymmetricKey - Unknown key type");
}
// Clear up any read padding
if (m_keyMode == MODE_CBC) {
m_ivSize = m_blockSize;
memcpy(m_lastBlock, usedIV, m_ivSize);
}
else if (m_keyMode == MODE_GCM) {
m_ivSize = 12;
memcpy(m_lastBlock, usedIV, m_ivSize);
}
else {
m_ivSize = 0;
}
#if defined (XSEC_OPENSSL_CANSET_PADDING)
// Setup padding
if (m_doPad) {
EVP_CIPHER_CTX_set_padding(mp_ctx, 1);
}
else {
EVP_CIPHER_CTX_set_padding(mp_ctx, 0);
}
#endif
return true;
}