Add tests for AES-CBC padding 72/323872/9
authorJakub Wlostowski <j.wlostowski@samsung.com>
Thu, 8 May 2025 09:07:36 +0000 (11:07 +0200)
committerJakub Wlostowski <j.wlostowski@samsung.com>
Thu, 15 May 2025 10:53:38 +0000 (12:53 +0200)
Change-Id: I53727701fa89c1451961f078389a8702b798dfe9

src/ckm/unprivileged/encryption-decryption.cpp

index 422117c7fe715dd18b2eda1c0a3a1ede97b43663..6cefbe6f86fd4034282d1439f6c559e9b784ed01 100644 (file)
@@ -42,6 +42,7 @@ const uid_t UID = 5001;
 const size_t CTR_DEFAULT_LEN = 16*8;
 const size_t DEFAULT_IV_LEN = 16;
 const size_t BUF_LEN = 86; // must be less than 1024/8-41 to support RSA OAEP 1024
+const size_t AES_BLOCK_SIZE = 16;
 
 // Environment
 SyncApi g_syncApi;
@@ -163,6 +164,9 @@ enum KeyIdx {
 };
 
 RawBufferPtr PLAIN_DATA;
+RawBufferPtr BLOCK_SIZE_DATA;
+RawBufferPtr SMALLER_BLOCK_SIZE_DATA;
+RawBufferPtr BIGGER_BLOCK_SIZE_DATA;
 RawBufferPtr BIG_DATA;
 ckmc_raw_buffer_s* DEFAULT_IV;
 ckmc_raw_buffer_s* IV1;
@@ -214,6 +218,9 @@ public:
         generateRsaKeys(4096);
 #endif
         PLAIN_DATA = create_raw_buffer(createRandomBufferCAPI(BUF_LEN));
+        BLOCK_SIZE_DATA = create_raw_buffer(createRandomBufferCAPI(AES_BLOCK_SIZE));
+        SMALLER_BLOCK_SIZE_DATA = create_raw_buffer(createRandomBufferCAPI(AES_BLOCK_SIZE - 1));
+        BIGGER_BLOCK_SIZE_DATA = create_raw_buffer(createRandomBufferCAPI(AES_BLOCK_SIZE + 1));
 #ifdef TZ_BACKEND
         ckmc_backend_info_h info;
         size_t size;
@@ -290,6 +297,9 @@ public:
 
         BIG_DATA.reset();
         PLAIN_DATA.reset();
+        BLOCK_SIZE_DATA.reset();
+        SMALLER_BLOCK_SIZE_DATA.reset();
+        BIGGER_BLOCK_SIZE_DATA.reset();
         ckmc_buffer_free(AAD64);
         ckmc_buffer_free(AAD32);
         ckmc_buffer_free(IV63);
@@ -412,6 +422,237 @@ void testNoIvDec(const Algo& algo)
                                 &decrypted);
 }
 
+void testNoPaddingInvalidDataSize(const Algo& algo, const RawBufferPtr& data)
+{
+   // prepare buffers
+   ckmc_raw_buffer_s* encryptedTmp = nullptr;
+
+   // add key
+   KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+   // we only need one symmetric key here (aliases.prv = aliases.pub)
+   Alias aesKey = aliases.prv;
+
+   // setup params
+   ckmc_param_list_h handle = NULL;
+   assert_positive(ckmc_generate_new_params, algo.type, &handle);
+   ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+   setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+
+   // invalid encryption
+   auto test = [&](){
+        assert_crypto_result(EncryptionError::INVALID_PARAM,
+                             apiEncrypt,
+                             params.get(),
+                             aesKey.c_str(),
+                             nullptr,
+                             *data.get(),
+                             &encryptedTmp);
+       ckmc_buffer_free(encryptedTmp);
+       encryptedTmp = nullptr;
+   };
+
+   // invalid data size
+   setParam(params, CKMC_PARAM_ED_PADDING, CKMC_AES_NONE_PADDING);
+   test();
+}
+
+void testEncryptionDecryptionPadding(const Algo& algo, const RawBufferPtr& data, const int padding)
+{
+    // prepare buffers
+    RawBufferPtr encrypted;
+    RawBufferPtr decrypted;
+    ckmc_raw_buffer_s* encryptedTmp = nullptr;
+    ckmc_raw_buffer_s* decryptedTmp = nullptr;
+
+    // add key
+    KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+    // we only need one symmetric key here (aliases.prv = aliases.pub)
+    Alias aesKey = aliases.prv;
+
+    // setup params
+    ckmc_param_list_h handle = NULL;
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+    setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+    setParam(params, CKMC_PARAM_ED_PADDING, padding);
+
+    // encryption
+    assert_crypto_positive(apiEncrypt,
+                           params.get(),
+                           aesKey.c_str(),
+                           nullptr,
+                           *data.get(),
+                           &encryptedTmp);
+
+    encrypted = create_raw_buffer(encryptedTmp);
+
+    // decryption
+    assert_crypto_positive(apiDecrypt,
+                           params.get(),
+                           aesKey.c_str(),
+                           nullptr,
+                           *encrypted.get(),
+                           &decryptedTmp);
+    decrypted = create_raw_buffer(decryptedTmp);
+
+    assert_buffers_equal(data.get(), decrypted.get());
+}
+
+void testEncryptionDifferentPaddings(const Algo& algo)
+{
+    // prepare buffers
+    RawBufferPtr firstEncrypted;
+    RawBufferPtr secondEncrypted;
+    ckmc_raw_buffer_s* firstEncryptedTmp = nullptr;
+    ckmc_raw_buffer_s* secondEncryptedTmp = nullptr;
+
+    // add key
+    KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+    // we only need one symmetric key here (aliases.prv = aliases.pub)
+    Alias aesKey = aliases.prv;
+
+    // setup params
+    ckmc_param_list_h handle = NULL;
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+    setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+
+    // encryption with PKCS7 padding
+    setParam(params, CKMC_PARAM_ED_PADDING, CKMC_AES_PKCS7_PADDING);
+    assert_crypto_positive(apiEncrypt,
+                           params.get(),
+                           aesKey.c_str(),
+                           nullptr,
+                           *PLAIN_DATA.get(),
+                           &firstEncryptedTmp);
+
+    firstEncrypted = create_raw_buffer(firstEncryptedTmp);
+
+    // encryption with ISO9797_M2 padding
+    setParam(params, CKMC_PARAM_ED_PADDING, CKMC_AES_ISO9797_M2_PADDING);
+    assert_crypto_positive(apiEncrypt,
+                           params.get(),
+                           aesKey.c_str(),
+                           nullptr,
+                           *PLAIN_DATA.get(),
+                           &secondEncryptedTmp);
+
+    secondEncrypted = create_raw_buffer(secondEncryptedTmp);
+
+    // buffers should be different due to usage of different padding
+    assert_buffers_equal(firstEncrypted.get(), secondEncrypted.get(), false);
+}
+
+void testEncryptionDecryptionDifferentPaddings(const Algo& algo, const RawBufferPtr& data,
+                                               const int paddingType, const int unpaddingType)
+{
+    // prepare buffers
+    RawBufferPtr encrypted;
+    ckmc_raw_buffer_s* encryptedTmp = nullptr;
+    ckmc_raw_buffer_s* decryptedTmp = nullptr;
+
+    // add key
+    KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+    // we only need one symmetric key here (aliases.prv = aliases.pub)
+    Alias aesKey = aliases.prv;
+
+    // setup params
+    ckmc_param_list_h handle = NULL;
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+    setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+
+    // encryption
+    setParam(params, CKMC_PARAM_ED_PADDING, paddingType);
+    assert_crypto_positive(apiEncrypt,
+                           params.get(),
+                           aesKey.c_str(),
+                           nullptr,
+                           *data.get(),
+                           &encryptedTmp);
+
+    encrypted = create_raw_buffer(encryptedTmp);
+
+    // decryption with different padding type
+    setParam(params, CKMC_PARAM_ED_PADDING, unpaddingType);
+    assert_crypto_invalid_param(apiDecrypt,
+                                params.get(),
+                                aesKey.c_str(),
+                                nullptr,
+                                *encrypted.get(),
+                                &decryptedTmp);
+
+    ckmc_buffer_free(decryptedTmp);
+    decryptedTmp = nullptr;
+}
+
+void testInvalidPaddingEnc(const Algo& algo)
+{
+    // prepare buffers
+    ckmc_raw_buffer_s* encryptedTmp = nullptr;
+
+    // add key
+    KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+    // we only need one symmetric key here (aliases.prv = aliases.pub)
+    Alias aesKey = aliases.prv;
+
+    // setup params
+    ckmc_param_list_h handle = NULL;
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+
+    // invalid encryption
+    auto test = [&](){
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aesKey.c_str(),
+                                    nullptr,
+                                    *PLAIN_DATA.get(),
+                                    &encryptedTmp);
+        ckmc_buffer_free(encryptedTmp);
+        encryptedTmp = nullptr;
+    };
+
+    // invalid padding type
+    setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+    setParam(params, CKMC_PARAM_ED_PADDING, -1);
+    test();
+};
+
+void testInvalidPaddingDec(const Algo& algo)
+{
+    // prepare buffers
+    ckmc_raw_buffer_s* decrypted = nullptr;
+
+    // valid encryption
+    auto ret = encrypt(algo, PLAIN_DATA);
+
+    // we only need one symmetric key here (ret.prvKey = ret.pubKey)
+    Alias aesKey = ret.prvKey;
+
+    // decryption
+    auto test2 = [&](){
+        assert_crypto_invalid_param(apiDecrypt,
+                                    ret.params.get(),
+                                    aesKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
+        ckmc_buffer_free(decrypted);
+        decrypted = nullptr;
+    };
+
+    // invalid padding type
+    setParam(ret.params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+    setParam(ret.params, CKMC_PARAM_ED_PADDING, -1);
+    test2();
+};
+
 void testInvalidIvEnc(const Algo& algo)
 {
     // prepare buffers
@@ -647,7 +888,7 @@ void testCtrEncryptionValidLength(const Algo& algo)
         ckmc_buffer_free(encryptedTmp);
         encryptedTmp = nullptr;
     };
-    // valid counter sizez
+    // valid counter sizes
     setParam(params, CKMC_PARAM_ED_CTR_LEN, 1);
     test();
     setParam(params, CKMC_PARAM_ED_CTR_LEN, 4);
@@ -1345,7 +1586,113 @@ RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv, CipherEnv)
     testInvalidIvEnc({CKMC_ALGO_AES_CFB, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv, CipherEnv)
+RUNNER_TEST_MULTIPLE(TED_1011_no_padding_invalid_data_size, SyncEnv, AsyncEnv)
+{
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 128}, SMALLER_BLOCK_SIZE_DATA);
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 192}, SMALLER_BLOCK_SIZE_DATA);
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 256}, SMALLER_BLOCK_SIZE_DATA);
+
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 128}, BIGGER_BLOCK_SIZE_DATA);
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 192}, BIGGER_BLOCK_SIZE_DATA);
+    testNoPaddingInvalidDataSize({CKMC_ALGO_AES_CBC, 256}, BIGGER_BLOCK_SIZE_DATA);
+}
+
+RUNNER_TEST_MULTIPLE(TED_1012_none_padding, SyncEnv, AsyncEnv)
+{
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128}, BLOCK_SIZE_DATA, CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192}, BLOCK_SIZE_DATA, CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256}, BLOCK_SIZE_DATA, CKMC_AES_NONE_PADDING);
+
+    int n = 20;
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+
+    n = 85;
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256},
+        create_raw_buffer(createRandomBufferCAPI(n * AES_BLOCK_SIZE)), CKMC_AES_NONE_PADDING);
+}
+
+RUNNER_TEST_MULTIPLE(TED_1013_iso9797_m2_padding, SyncEnv, AsyncEnv)
+{
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128}, BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192}, BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256}, BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128},
+        SMALLER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192},
+        SMALLER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256},
+        SMALLER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 128},
+        BIGGER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 192},
+        BIGGER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionPadding({CKMC_ALGO_AES_CBC, 256},
+        BIGGER_BLOCK_SIZE_DATA, CKMC_AES_ISO9797_M2_PADDING);
+}
+
+RUNNER_TEST_MULTIPLE(TED_1014_encryption_different_paddings, SyncEnv, AsyncEnv)
+{
+    testEncryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 128});
+    testEncryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 192});
+    testEncryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 256});
+}
+
+RUNNER_TEST_MULTIPLE(TED_1015_encryption_decryption_different_paddings, SyncEnv, AsyncEnv)
+{
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 128},
+        SMALLER_BLOCK_SIZE_DATA,
+        CKMC_AES_PKCS7_PADDING, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 192},
+        BLOCK_SIZE_DATA,
+        CKMC_AES_PKCS7_PADDING, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 256},
+        BIGGER_BLOCK_SIZE_DATA,
+        CKMC_AES_PKCS7_PADDING, CKMC_AES_ISO9797_M2_PADDING);
+
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 128},
+        SMALLER_BLOCK_SIZE_DATA,
+        CKMC_AES_ISO9797_M2_PADDING, CKMC_AES_PKCS7_PADDING);
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 192},
+        BIGGER_BLOCK_SIZE_DATA,
+        CKMC_AES_ISO9797_M2_PADDING, CKMC_AES_PKCS7_PADDING);
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 256},
+        BLOCK_SIZE_DATA,
+        CKMC_AES_ISO9797_M2_PADDING, CKMC_AES_PKCS7_PADDING);
+
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 128},
+        BLOCK_SIZE_DATA,
+        CKMC_AES_NONE_PADDING, CKMC_AES_ISO9797_M2_PADDING);
+    testEncryptionDecryptionDifferentPaddings({CKMC_ALGO_AES_CBC, 192},
+        BLOCK_SIZE_DATA,
+        CKMC_AES_NONE_PADDING, CKMC_AES_PKCS7_PADDING);
+}
+
+RUNNER_TEST_MULTIPLE(TED_1016_invalid_padding_type_enc, SyncEnv, AsyncEnv)
+{
+    testInvalidPaddingEnc({CKMC_ALGO_AES_CBC, 128});
+    testInvalidPaddingEnc({CKMC_ALGO_AES_CBC, 192});
+    testInvalidPaddingEnc({CKMC_ALGO_AES_CBC, 256});
+}
+
+RUNNER_TEST_MULTIPLE(TED_1017_invalid_padding_type_dec, SyncEnv, AsyncEnv)
+{
+    testInvalidPaddingDec({CKMC_ALGO_AES_CBC, 128});
+    testInvalidPaddingDec({CKMC_ALGO_AES_CBC, 192});
+    testInvalidPaddingDec({CKMC_ALGO_AES_CBC, 256});
+}
+
+RUNNER_TEST_MULTIPLE(TED_1018_no_iv_dec, SyncEnv, AsyncEnv, CipherEnv)
 {
     testNoIvDec({CKMC_ALGO_AES_GCM, 128});
     testNoIvDec({CKMC_ALGO_AES_GCM, 192});