From 1fdde9cdc18fd68d33d2b527c9d3b5b561e09e69 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 17 Aug 2016 12:39:31 +0200 Subject: [PATCH] YACA: Add key wrapping tests. Change-Id: I2c467b97d72c912a70096e4b91e3409b3a224cd3 --- .../encrypt_output_comparison_wrap.txt | 47 +++++++ src/yaca/test-vectors/encrypt_param_comb.txt | 126 ++++++++++++++++++ .../test-vectors/encrypt_valid_param_wrap.txt | 101 ++++++++++++++ src/yaca/tools/containers.py | 8 +- src/yaca/tools/encrypt_param_combinations.py | 4 +- src/yaca/yaca-test-common.cpp | 6 +- src/yaca/yaca-test-encrypt.cpp | 104 ++++++++++++--- src/yaca/yaca-test-vector.cpp | 3 +- 8 files changed, 371 insertions(+), 28 deletions(-) create mode 100644 src/yaca/test-vectors/encrypt_output_comparison_wrap.txt create mode 100644 src/yaca/test-vectors/encrypt_valid_param_wrap.txt 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 index 00000000..ca63b04a --- /dev/null +++ b/src/yaca/test-vectors/encrypt_output_comparison_wrap.txt @@ -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 diff --git a/src/yaca/test-vectors/encrypt_param_comb.txt b/src/yaca/test-vectors/encrypt_param_comb.txt index d6090fb0..fb1b0aab 100644 --- a/src/yaca/test-vectors/encrypt_param_comb.txt +++ b/src/yaca/test-vectors/encrypt_param_comb.txt @@ -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 index 00000000..741577cf --- /dev/null +++ b/src/yaca/test-vectors/encrypt_valid_param_wrap.txt @@ -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 diff --git a/src/yaca/tools/containers.py b/src/yaca/tools/containers.py index 4bf8b9d9..59d8d494 100644 --- a/src/yaca/tools/containers.py +++ b/src/yaca/tools/containers.py @@ -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)) diff --git a/src/yaca/tools/encrypt_param_combinations.py b/src/yaca/tools/encrypt_param_combinations.py index cb865291..833f8029 100755 --- a/src/yaca/tools/encrypt_param_combinations.py +++ b/src/yaca/tools/encrypt_param_combinations.py @@ -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__": diff --git a/src/yaca/yaca-test-common.cpp b/src/yaca/yaca-test-common.cpp index e3211157..a028fcff 100644 --- a/src/yaca/yaca-test-common.cpp +++ b/src/yaca/yaca-test-common.cpp @@ -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"; } } diff --git a/src/yaca/yaca-test-encrypt.cpp b/src/yaca/yaca-test-encrypt.cpp index 298a8924..123837c7 100644 --- a/src/yaca/yaca-test-encrypt.cpp +++ b/src/yaca/yaca-test-encrypt.cpp @@ -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"); } diff --git a/src/yaca/yaca-test-vector.cpp b/src/yaca/yaca-test-vector.cpp index 6c99dc4e..b145a67c 100644 --- a/src/yaca/yaca-test-vector.cpp +++ b/src/yaca/yaca-test-vector.cpp @@ -111,7 +111,8 @@ std::unordered_map 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 str2kdf = { -- 2.34.1