{} \
}
-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
}
}
+typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr;
+
+typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn;
+
+// aes mode, key length in bits, encryption
+typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree;
+
+template <typename T>
+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<Cipher::AesCbcEncryption128>;
+ tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>;
+ tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>;
+
+ tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>;
+ tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>;
+ tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>;
+
+ tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>;
+ tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>;
+ tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>;
+
+ tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>;
+ tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>;
+ tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>;
+
+ 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<int>(type), ", ",
+ key_len, ", ",
+ encryption);
+ }
+}
+
} // anonymous namespace
int initialize() {
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;
}
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);
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;
}
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;
}