From a0fe93a32f0a9eff1489d36b5b3323fd6ca5651a Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 29 Jun 2015 15:52:45 +0200 Subject: [PATCH] Add support for different AES key sizes [Problem] AES encryption/decryption supports only 256-bit key size. [Solution] Add support for 128 and 192-bit key encryption/decryption. [Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION. Only TED_1250_gcm_aad may fail. Change-Id: Ia949250b7f3597dee5360c3373c9164dc2e4d9e8 --- src/manager/crypto/sw-backend/crypto.h | 17 ++++-- src/manager/crypto/sw-backend/internals.cpp | 83 ++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/manager/crypto/sw-backend/crypto.h b/src/manager/crypto/sw-backend/crypto.h index 9a09909..40fe42d 100644 --- a/src/manager/crypto/sw-backend/crypto.h +++ b/src/manager/crypto/sw-backend/crypto.h @@ -113,10 +113,19 @@ public: \ {} \ } -DEFINE_CIPHER(AesCbcEncryption, RawBuffer, EVP_aes_256_cbc(), true); -DEFINE_CIPHER(AesCbcDecryption, RawBuffer, EVP_aes_256_cbc(), false); -DEFINE_CIPHER(AesGcmEncryption, RawBuffer, EVP_aes_256_gcm(), true); -DEFINE_CIPHER(AesGcmDecryption, RawBuffer, EVP_aes_256_gcm(), false); +DEFINE_CIPHER(AesCbcEncryption128, RawBuffer, EVP_aes_128_cbc(), true); +DEFINE_CIPHER(AesCbcDecryption128, RawBuffer, EVP_aes_128_cbc(), false); +DEFINE_CIPHER(AesCbcEncryption192, RawBuffer, EVP_aes_192_cbc(), true); +DEFINE_CIPHER(AesCbcDecryption192, RawBuffer, EVP_aes_192_cbc(), false); +DEFINE_CIPHER(AesCbcEncryption256, RawBuffer, EVP_aes_256_cbc(), true); +DEFINE_CIPHER(AesCbcDecryption256, RawBuffer, EVP_aes_256_cbc(), false); + +DEFINE_CIPHER(AesGcmEncryption128, RawBuffer, EVP_aes_128_gcm(), true); +DEFINE_CIPHER(AesGcmDecryption128, RawBuffer, EVP_aes_128_gcm(), false); +DEFINE_CIPHER(AesGcmEncryption192, RawBuffer, EVP_aes_192_gcm(), true); +DEFINE_CIPHER(AesGcmDecryption192, RawBuffer, EVP_aes_192_gcm(), false); +DEFINE_CIPHER(AesGcmEncryption256, RawBuffer, EVP_aes_256_gcm(), true); +DEFINE_CIPHER(AesGcmDecryption256, RawBuffer, EVP_aes_256_gcm(), false); #undef DEFINE_CIPHER diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index 8612631..a6ad01a 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -215,6 +215,57 @@ void validateParams(const CryptoAlgorithm& ca) } } +typedef std::unique_ptr> EvpCipherPtr; + +typedef std::function InitCipherFn; + +// aes mode, key length in bits, encryption +typedef std::map>> CipherTree; + +template +void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv) +{ + ptr.reset(new T(key, iv)); +} + +CipherTree initializeCipherTree() +{ + CipherTree tree; + tree[AlgoType::AES_CBC][128][true] = initCipher; + tree[AlgoType::AES_CBC][192][true] = initCipher; + tree[AlgoType::AES_CBC][256][true] = initCipher; + + tree[AlgoType::AES_CBC][128][false] = initCipher; + tree[AlgoType::AES_CBC][192][false] = initCipher; + tree[AlgoType::AES_CBC][256][false] = initCipher; + + tree[AlgoType::AES_GCM][128][true] = initCipher; + tree[AlgoType::AES_GCM][192][true] = initCipher; + tree[AlgoType::AES_GCM][256][true] = initCipher; + + tree[AlgoType::AES_GCM][128][false] = initCipher; + tree[AlgoType::AES_GCM][192][false] = initCipher; + tree[AlgoType::AES_GCM][256][false] = initCipher; + + return tree; +} + +CipherTree g_cipherTree = initializeCipherTree(); + +// key length in bytes +InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true) +{ + try { + return g_cipherTree.at(type).at(key_len*8).at(encryption); + } catch (const std::out_of_range&) { + ThrowErr(Exc::Crypto::InternalError, + "Unsupported cipher: ", + static_cast(type), ", ", + key_len, ", ", + encryption); + } +} + } // anonymous namespace int initialize() { @@ -482,9 +533,10 @@ RawBuffer encryptDataAesCbc( const RawBuffer &data, const RawBuffer &iv) { - Crypto::SW::Cipher::AesCbcEncryption enc(key, iv); - RawBuffer result = enc.Append(data); - RawBuffer tmp = enc.Finalize(); + EvpCipherPtr enc; + selectCipher(AlgoType::AES_CBC, key.size())(enc, key, iv); + RawBuffer result = enc->Append(data); + RawBuffer tmp = enc->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); return result; } @@ -496,11 +548,12 @@ std::pair encryptDataAesGcm( int tagSize) { RawBuffer tag(tagSize); - Crypto::SW::Cipher::AesGcmEncryption enc(key, iv); - RawBuffer result = enc.Append(data); - RawBuffer tmp = enc.Finalize(); + EvpCipherPtr enc; + selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv); + RawBuffer result = enc->Append(data); + RawBuffer tmp = enc->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - if (0 == enc.Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) { + if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) { ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed."); } return std::make_pair(result, tag); @@ -522,9 +575,10 @@ RawBuffer decryptDataAesCbc( const RawBuffer &data, const RawBuffer &iv) { - Crypto::SW::Cipher::AesCbcDecryption dec(key, iv); - RawBuffer result = dec.Append(data); - RawBuffer tmp = dec.Finalize(); + EvpCipherPtr dec; + selectCipher(AlgoType::AES_CBC, key.size(), false)(dec, key, iv); + RawBuffer result = dec->Append(data); + RawBuffer tmp = dec->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); return result; } @@ -535,14 +589,15 @@ RawBuffer decryptDataAesGcm( const RawBuffer &iv, const RawBuffer &tag) { - Crypto::SW::Cipher::AesGcmDecryption dec(key, iv); + EvpCipherPtr dec; + selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv); void *ptr = (void*)tag.data(); - if (0 == dec.Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) { + if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) { ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Set tag failed."); } - RawBuffer result = dec.Append(data); - RawBuffer tmp = dec.Finalize(); + RawBuffer result = dec->Append(data); + RawBuffer tmp = dec->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); return result; } -- 2.7.4