YACA: Add key wrapping tests. 65/84265/5
authorDariusz Michaluk <d.michaluk@samsung.com>
Wed, 17 Aug 2016 10:39:31 +0000 (12:39 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 29 Aug 2016 14:47:12 +0000 (07:47 -0700)
Change-Id: I2c467b97d72c912a70096e4b91e3409b3a224cd3

src/yaca/test-vectors/encrypt_output_comparison_wrap.txt [new file with mode: 0644]
src/yaca/test-vectors/encrypt_param_comb.txt
src/yaca/test-vectors/encrypt_valid_param_wrap.txt [new file with mode: 0644]
src/yaca/tools/containers.py
src/yaca/tools/encrypt_param_combinations.py
src/yaca/yaca-test-common.cpp
src/yaca/yaca-test-encrypt.cpp
src/yaca/yaca-test-vector.cpp

diff --git a/src/yaca/test-vectors/encrypt_output_comparison_wrap.txt b/src/yaca/test-vectors/encrypt_output_comparison_wrap.txt
new file mode 100644 (file)
index 0000000..ca63b04
--- /dev/null
@@ -0,0 +1,47 @@
+input=00112233445566778899aabbccddeeff
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5
+
+input=00112233445566778899aabbccddeeff
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f1011121314151617
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d
+
+input=00112233445566778899aabbccddeeff
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7
+
+input=00112233445566778899aabbccddeeff0001020304050607
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f1011121314151617
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2
+
+input=00112233445566778899aabbccddeeff0001020304050607
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1
+
+input=00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+algo=AES
+bcm=WRAP
+key=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+iv=a6a6a6a6a6a6a6a6
+repeats=1
+output=28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21
index d6090fb..fb1b0aa 100644 (file)
@@ -62,6 +62,12 @@ key_len=128
 iv_len=64
 valid=1
 
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+valid=1
+
 ################## DES ##################
 
 algo=DES
@@ -124,6 +130,12 @@ key_len=64
 iv_len=64
 valid=0
 
+algo=DES
+bcm=WRAP
+key_len=64
+iv_len=64
+valid=0
+
 ################## 3DES_2TDEA ##################
 
 algo=3DES_2TDEA
@@ -186,6 +198,12 @@ key_len=128
 iv_len=64
 valid=0
 
+algo=3DES_2TDEA
+bcm=WRAP
+key_len=128
+iv_len=64
+valid=0
+
 ################## 3DES_3TDEA ##################
 
 algo=3DES_3TDEA
@@ -248,6 +266,12 @@ key_len=192
 iv_len=64
 valid=0
 
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=0
+valid=1
+
 ################## RC2 ##################
 
 algo=RC2
@@ -310,6 +334,12 @@ key_len=8
 iv_len=64
 valid=0
 
+algo=RC2
+bcm=WRAP
+key_len=8
+iv_len=64
+valid=0
+
 ################## RC4 ##################
 
 algo=RC4
@@ -372,6 +402,12 @@ key_len=40
 iv_len=64
 valid=0
 
+algo=RC4
+bcm=WRAP
+key_len=40
+iv_len=64
+valid=0
+
 ################## CAST5 ##################
 
 algo=CAST5
@@ -434,6 +470,12 @@ key_len=40
 iv_len=64
 valid=0
 
+algo=CAST5
+bcm=WRAP
+key_len=40
+iv_len=64
+valid=0
+
 ################## check key_len for algorithm ##################
 
 ################## AES ##################
@@ -1294,6 +1336,48 @@ key_len=128
 iv_len=256
 valid=0
 
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=0
+valid=0
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=56
+valid=0
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+valid=1
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=96
+valid=0
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=104
+valid=0
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=128
+valid=0
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=256
+valid=0
+
 ################## DES ##################
 
 algo=DES
@@ -1972,6 +2056,48 @@ key_len=192
 iv_len=256
 valid=0
 
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=0
+valid=1
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=56
+valid=0
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=64
+valid=0
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=96
+valid=0
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=104
+valid=0
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=128
+valid=0
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=256
+valid=0
+
 ################## RC2 ##################
 
 algo=RC2
diff --git a/src/yaca/test-vectors/encrypt_valid_param_wrap.txt b/src/yaca/test-vectors/encrypt_valid_param_wrap.txt
new file mode 100644 (file)
index 0000000..741577c
--- /dev/null
@@ -0,0 +1,101 @@
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+key_data_len=128
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+key_data_len=192
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+key_data_len=256
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+key_data_len=512
+
+algo=AES
+bcm=WRAP
+key_len=128
+iv_len=64
+key_data_len=1024
+
+algo=AES
+bcm=WRAP
+key_len=192
+iv_len=64
+key_data_len=128
+
+algo=AES
+bcm=WRAP
+key_len=192
+iv_len=64
+key_data_len=192
+
+algo=AES
+bcm=WRAP
+key_len=192
+iv_len=64
+key_data_len=256
+
+algo=AES
+bcm=WRAP
+key_len=192
+iv_len=64
+key_data_len=512
+
+algo=AES
+bcm=WRAP
+key_len=192
+iv_len=64
+key_data_len=1024
+
+algo=AES
+bcm=WRAP
+key_len=256
+iv_len=64
+key_data_len=128
+
+algo=AES
+bcm=WRAP
+key_len=256
+iv_len=64
+key_data_len=192
+
+algo=AES
+bcm=WRAP
+key_len=256
+iv_len=64
+key_data_len=256
+
+algo=AES
+bcm=WRAP
+key_len=256
+iv_len=64
+key_data_len=512
+
+algo=AES
+bcm=WRAP
+key_len=256
+iv_len=64
+key_data_len=1024
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=0
+key_data_len=128
+
+algo=3DES_3TDEA
+bcm=WRAP
+key_len=192
+iv_len=0
+key_data_len=192
index 4bf8b9d..59d8d49 100644 (file)
@@ -4,7 +4,7 @@ from collections import OrderedDict
 import copy
 
 bcm_list = ['NONE', 'ECB', 'CTR', 'CBC', 'GCM',
-            'CFB', 'CFB1', 'CFB8','OFB', 'CCM']
+            'CFB', 'CFB1', 'CFB8','OFB', 'CCM', 'WRAP']
 
 key_length_list = [8, 40, 64, 80, 128,
                    192, 256, 512, 1024, 2048, 4096,]
@@ -71,9 +71,9 @@ key = '534c1dd926ffc55db2a1ec2f8d21ed4ac3b9ad3d67a0ae381275f00cc0f7d3fd' #256
 iv = 'd17d7ace9acea556527b1037ee3aa824' #128
 
 def default_iv_len(algo, bcm):
-    if bcm == 'ECB' or bcm == 'NONE':
+    if bcm == 'ECB' or bcm == 'NONE' or (algo == '3DES_3TDEA' and bcm == 'WRAP'):
         iv_len = 0
-    elif algo == 'AES' and bcm != 'CCM':
+    elif algo == 'AES' and bcm != 'CCM' and bcm != 'WRAP':
         iv_len = 128
     else:
         iv_len = 64
@@ -110,6 +110,7 @@ aes.set_bcm(OrderedDict([
                         ('GCM',  Bcm(range(24, 256 + 8, 8))),
                         ('CCM',  Bcm(range(56, 104 + 8, 8))),
                         ('CTR',  Bcm([128])),
+                        ('WRAP', Bcm([64])),
                         ]))
 
 des = Algorithm([64])
@@ -138,6 +139,7 @@ t_des_3.set_bcm(OrderedDict([
                             ('CFB1', Bcm([64])),
                             ('CFB8', Bcm([64])),
                             ('ECB',  Bcm([0])),
+                            ('WRAP', Bcm([0])),
                             ]))
 
 rc2 = Algorithm(range(8, 1024 + 8, 8))
index cb86529..833f802 100755 (executable)
@@ -81,8 +81,8 @@ def main():
 
     file_name = 'encrypt_valid_param.txt'
     out_file = open(file_name, 'w')
-    exclude_gcm_ccm = filter(lambda x: x != 'GCM' and x != 'CCM', containers.bcm_list)
-    generate_valid_combs_only(out_file, exclude_gcm_ccm)
+    exclude_gcm_ccm_wrap = filter(lambda x: x != 'GCM' and x != 'CCM' and x != 'WRAP', containers.bcm_list)
+    generate_valid_combs_only(out_file, exclude_gcm_ccm_wrap)
     out_file.close()
 
 if __name__ == "__main__":
index e321115..a028fcf 100644 (file)
@@ -330,7 +330,10 @@ Buffer random_buffer(size_t length)
 ChrPtr out_buf_alloc(const CtxPtr& ctx_ptr, size_t input_len, size_t &out_len)
 {
     out_len = get_output_length(ctx_ptr, input_len);
-    return create_yaca_buffer(out_len);
+    if (out_len > 0)
+        return create_yaca_buffer(out_len);
+    else
+        return wrap_ptr((char*)nullptr);
 }
 
 #define ENUM_DESCRIBE(enum_value) case (enum_value): return #enum_value;
@@ -406,6 +409,7 @@ const char* bcm2str(yaca_block_cipher_mode_e bcm)
     ENUM_DESCRIBE(YACA_BCM_CFB8);
     ENUM_DESCRIBE(YACA_BCM_OFB);
     ENUM_DESCRIBE(YACA_BCM_CCM);
+    ENUM_DESCRIBE(YACA_BCM_WRAP);
     default: return "Unknown bcm type";
     }
 }
index 298a892..123837c 100644 (file)
@@ -120,9 +120,10 @@ private:
         Buffer output;
         size_t len = 0;
         auto final_ptr = out_buf_alloc(m_decCtxPtr, 0, len);
-        YACA_SUCCESS(finalize(ctx_ptr->get(), final_ptr.get(), &len));
-        output.insert(output.end(), final_ptr.get(), final_ptr.get() + len);
-
+        if (final_ptr != nullptr) {
+            YACA_SUCCESS(finalize(ctx_ptr->get(), final_ptr.get(), &len));
+            output.insert(output.end(), final_ptr.get(), final_ptr.get() + len);
+        }
         return output;
     }
 };
@@ -231,13 +232,12 @@ void test_encryption_output(std::string filename, bool padded=true)
     }
 }
 
-void test_vector_encrypt_decrypt(yaca_encrypt_algorithm_e algo,
+void test_vector_encrypt_decrypt(const Buffer &input,
+                                 yaca_encrypt_algorithm_e algo,
                                  yaca_block_cipher_mode_e bcm,
                                  size_t key_len,
                                  size_t iv_len)
 {
-    std::string s = "abcdefghijklmnoprstuvwxyz0123456789";
-    Buffer input(s.begin(), s.end());
     std::stringstream message;
 
     auto key_ptr = generate_key(algo_to_key_type(algo), key_len);
@@ -259,6 +259,36 @@ void test_vector_encrypt_decrypt(yaca_encrypt_algorithm_e algo,
                                               << message.str());
 }
 
+void test_encryption_decryption(std::string filename)
+{
+    Buffer input;
+    std::string s = "abcdefghijklmnoprstuvwxyz0123456789";
+
+    auto tvv = loadTestVector(filename);
+
+    for (const auto& tv : tvv) {
+        yaca_encrypt_algorithm_e algo;
+        yaca_block_cipher_mode_e bcm;
+        size_t key_len;
+        size_t iv_len;
+        size_t key_data_len = 0;
+
+        tv.get("algo", algo);
+        tv.get("bcm", bcm);
+        tv.get("key_len", key_len);
+        tv.get("iv_len", iv_len);
+        if (bcm == YACA_BCM_WRAP)
+            tv.get("key_data_len", key_data_len);
+
+        if (key_data_len > 0)
+            input = random_buffer(key_data_len / 8);
+        else
+            std::copy(s.begin(), s.end(), std::back_inserter(input));
+
+        test_vector_encrypt_decrypt(input, algo, bcm, key_len, iv_len);
+    }
+}
+
 }//namespace anonymous
 
 RUNNER_TEST_GROUP_INIT(T3000_YACA_ENCRYPT);
@@ -318,6 +348,9 @@ RUNNER_TEST(T3020_yaca_encrypt_update_invalid_param, YacaTest)
     YACA_INVALID_PARAM(yaca_encrypt_update(en_ctx_ptr.get(), nullptr, DATA.size(),
                                            ciphertext_ptr.get(), &ciphertext_len));
 
+    YACA_INVALID_PARAM(yaca_encrypt_update(en_ctx_ptr.get(), nullptr, 0,
+                                           ciphertext_ptr.get(), &ciphertext_len));
+
     YACA_INVALID_PARAM(yaca_encrypt_update(en_ctx_ptr.get(), DATA.data(), 0,
                                            ciphertext_ptr.get(), &ciphertext_len));
 
@@ -408,6 +441,9 @@ RUNNER_TEST(T3050_yaca_decrypt_update_invalid_param, YacaTest)
     YACA_INVALID_PARAM(yaca_decrypt_update(dec_ctx_ptr.get(), DATA.data(), 0,
                                            plaintext_ptr.get(), &plaintext_len));
 
+    YACA_INVALID_PARAM(yaca_decrypt_update(dec_ctx_ptr.get(), nullptr, 0,
+                                           plaintext_ptr.get(), &plaintext_len));
+
     YACA_INVALID_PARAM(yaca_decrypt_update(dec_ctx_ptr.get(), DATA.data(), DATA.size(),
                                            nullptr, &plaintext_len));
 
@@ -457,6 +493,44 @@ RUNNER_TEST(T3070_yaca_get_iv_bits_invalid_param, YacaTest)
                                                       KEY_LEN, nullptr));
 }
 
+RUNNER_TEST(T3075_yaca_key_wrap_unwrap_invalid_param, YacaTest)
+{
+    size_t wrapped_len = 0;
+    size_t unwrapped_len = 0;
+
+    KeyPtr key = generate_key(YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT);
+    KeyPtr iv = null_key();
+    Buffer key_data = random_buffer(YACA_KEY_LENGTH_192BIT / 8);
+
+    CtxPtr enc_ctx = encrypt_init(YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_WRAP, key, iv);
+    CtxPtr dec_ctx = decrypt_init(YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_WRAP, key, iv);
+
+    ChrPtr wrapped = out_buf_alloc(enc_ctx, key_data.size(), wrapped_len);
+    ChrPtr unwrapped = out_buf_alloc(dec_ctx, wrapped_len, unwrapped_len);
+
+    YACA_INVALID_PARAM(yaca_encrypt_finalize(enc_ctx.get(), wrapped.get(), &wrapped_len));
+    YACA_INVALID_PARAM(yaca_encrypt_update(enc_ctx.get(), key_data.data(), YACA_KEY_LENGTH_UNSAFE_64BIT / 8,
+                                           wrapped.get(), &wrapped_len));
+    YACA_INVALID_PARAM(yaca_encrypt_update(enc_ctx.get(), key_data.data(), YACA_KEY_LENGTH_512BIT / 8,
+                                           wrapped.get(), &wrapped_len));
+    YACA_SUCCESS(yaca_encrypt_update(enc_ctx.get(), key_data.data(), key_data.size(),
+                                     wrapped.get(), &wrapped_len));
+
+    // only a single update is allowed
+    YACA_INVALID_PARAM(yaca_encrypt_update(enc_ctx.get(), key_data.data(), key_data.size(),
+                                           wrapped.get(), &wrapped_len));
+
+    YACA_INVALID_PARAM(yaca_decrypt_finalize(dec_ctx.get(), wrapped.get(), &wrapped_len));
+    YACA_INVALID_PARAM(yaca_decrypt_update(dec_ctx.get(), wrapped.get(), wrapped_len - 1,
+                                           unwrapped.get(),&unwrapped_len));
+    YACA_SUCCESS(yaca_decrypt_update(dec_ctx.get(), wrapped.get(), wrapped_len,
+                                     unwrapped.get(), &unwrapped_len));
+
+    // only a single update is allowed
+    YACA_INVALID_PARAM(yaca_decrypt_update(dec_ctx.get(), wrapped.get(), wrapped_len,
+                                           unwrapped.get(), &unwrapped_len));
+}
+
 RUNNER_TEST(T3080_yaca_encrypt_decrypt_init_param_comb, YacaTest)
 {
     auto tvv = loadTestVector("encrypt_param_comb.txt");
@@ -483,23 +557,11 @@ RUNNER_TEST(T3090_yaca_encrypt_update_finalize_output_comp, YacaTest)
     test_encryption_output("encrypt_output_comparison.txt");
     test_encryption_output("encrypt_output_comparison_rc2_cast5_nopad.txt", false);
     test_encryption_output("encrypt_output_comparison_rc4.txt");
+    test_encryption_output("encrypt_output_comparison_wrap.txt");
 }
 
 RUNNER_TEST(T3100_yaca_encrypt_decrypt_comparison, YacaTest)
 {
-    auto tvv = loadTestVector("encrypt_valid_param.txt");
-
-    for (const auto& tv : tvv) {
-        yaca_encrypt_algorithm_e algo;
-        yaca_block_cipher_mode_e bcm;
-        size_t key_len;
-        size_t iv_len;
-
-        tv.get("algo", algo);
-        tv.get("bcm", bcm);
-        tv.get("key_len", key_len);
-        tv.get("iv_len", iv_len);
-
-        test_vector_encrypt_decrypt(algo, bcm, key_len, iv_len);
-    }
+    test_encryption_decryption("encrypt_valid_param.txt");
+    test_encryption_decryption("encrypt_valid_param_wrap.txt");
 }
index 6c99dc4..b145a67 100644 (file)
@@ -111,7 +111,8 @@ std::unordered_map<std::string, yaca_block_cipher_mode_e> str2bcm = {
     std::make_pair("CFB1", YACA_BCM_CFB1),
     std::make_pair("CFB8", YACA_BCM_CFB8),
     std::make_pair("OFB",  YACA_BCM_OFB),
-    std::make_pair("CCM",  YACA_BCM_CCM)
+    std::make_pair("CCM",  YACA_BCM_CCM),
+    std::make_pair("WRAP", YACA_BCM_WRAP)
 };
 
 std::unordered_map<std::string, yaca_kdf_e> str2kdf = {