From 3d491c054ea8f662dc9dc499d3029d126a8726d3 Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 18 Aug 2021 11:58:11 +1000 Subject: [PATCH] test: add unit tests for TDES key wrap This functionality was completely untested. Doesn't fix #16002 since that's a bug against 1.1.1. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/16343) --- test/destest.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/test/destest.c b/test/destest.c index b61c9eecc8..d2f3cfe6a7 100644 --- a/test/destest.c +++ b/test/destest.c @@ -17,6 +17,7 @@ #include #include "testutil.h" +#include "internal/nelem.h" #ifndef OPENSSL_NO_DES # include @@ -697,6 +698,79 @@ static int test_des_quad_cksum(void) return 0; return 1; } + +/* + * Test TDES based key wrapping. + * The wrapping process uses a randomly generated IV so it is difficult to + * undertake KATs. End to end testing is performed instead. + */ +static const int test_des_key_wrap_sizes[] = { + 8, 16, 24, 32, 64, 80 +}; + +static int test_des_key_wrap(int idx) +{ + int in_bytes = test_des_key_wrap_sizes[idx]; + unsigned char in[100], c_txt[200], p_txt[200], key[24]; + int clen, clen_upd, clen_fin, plen, plen_upd, plen_fin, expect, bs, i; + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *ctx = NULL; + int res = 0; + + /* Some sanity checks and cipher loading */ + if (!TEST_size_t_le(in_bytes, sizeof(in)) + || !TEST_ptr(cipher = EVP_CIPHER_fetch(NULL, "DES3-WRAP", NULL)) + || !TEST_int_eq(bs = EVP_CIPHER_get_block_size(cipher), 8) + || !TEST_size_t_eq(bs * 3u, sizeof(key)) + || !TEST_true(in_bytes % bs == 0) + || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())) + goto err; + + /* Create random data to end to end test */ + for (i = 0; i < in_bytes; i++) + in[i] = test_random(); + + /* Build the key */ + memcpy(key, cbc_key, sizeof(cbc_key)); + memcpy(key + sizeof(cbc_key), cbc2_key, sizeof(cbc2_key)); + memcpy(key + sizeof(cbc_key) + sizeof(cbc3_key), cbc_key, sizeof(cbc3_key)); + + /* Wrap / encrypt the key */ + clen_upd = sizeof(c_txt); + if (!TEST_true(EVP_EncryptInit(ctx, cipher, key, NULL)) + || !TEST_true(EVP_EncryptUpdate(ctx, c_txt, &clen_upd, + in, in_bytes))) + goto err; + + expect = (in_bytes + (bs - 1)) / bs * bs + 2 * bs; + if (!TEST_int_eq(clen_upd, expect)) + goto err; + + clen_fin = sizeof(c_txt) - clen_upd; + if (!TEST_true(EVP_EncryptFinal(ctx, c_txt + clen_upd, &clen_fin)) + || !TEST_int_eq(clen_fin, 0)) + goto err; + clen = clen_upd + clen_fin; + + /* Decrypt the wrapped key */ + plen_upd = sizeof(p_txt); + if (!TEST_true(EVP_DecryptInit(ctx, cipher, key, NULL)) + || !TEST_true(EVP_DecryptUpdate(ctx, p_txt, &plen_upd, + c_txt, clen))) + goto err; + plen_fin = sizeof(p_txt) - plen_upd; + if (!TEST_true(EVP_DecryptFinal(ctx, p_txt + plen_upd, &plen_fin))) + goto err; + plen = plen_upd + plen_fin; + + if (!TEST_mem_eq(in, in_bytes, p_txt, plen)) + goto err; + res = 1; + err: + EVP_CIPHER_free(cipher); + EVP_CIPHER_CTX_free(ctx); + return res; +} #endif int setup_tests(void) @@ -722,6 +796,7 @@ int setup_tests(void) ADD_TEST(test_des_crypt); ADD_ALL_TESTS(test_input_align, 4); ADD_ALL_TESTS(test_output_align, 4); + ADD_ALL_TESTS(test_des_key_wrap, OSSL_NELEM(test_des_key_wrap_sizes)); #endif return 1; }