Add support for different AES key sizes 26/42526/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 29 Jun 2015 13:52:45 +0000 (15:52 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 1 Jul 2015 11:41:47 +0000 (04:41 -0700)
[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
src/manager/crypto/sw-backend/internals.cpp

index 9a09909..40fe42d 100644 (file)
@@ -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
 
index 8612631..a6ad01a 100644 (file)
@@ -215,6 +215,57 @@ void validateParams(const CryptoAlgorithm& ca)
     }
 }
 
+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() {
@@ -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<RawBuffer, RawBuffer> 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;
 }