From 07f5e63abf1c9e446f9df6c86830cbdefcc7ae3f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 6 May 2021 10:53:14 +0200 Subject: [PATCH] tests: verify secure messaging functions work as expected --- src/tests/unittests/Makefile.am | 1 - src/tests/unittests/sm.c | 189 ++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am index 8708e464..03019c32 100644 --- a/src/tests/unittests/Makefile.am +++ b/src/tests/unittests/Makefile.am @@ -41,5 +41,4 @@ sm_LDADD = $(top_builddir)/src/sm/libsm.la $(LDADD) endif - endif diff --git a/src/tests/unittests/sm.c b/src/tests/unittests/sm.c index 75cce97d..d39d13c9 100644 --- a/src/tests/unittests/sm.c +++ b/src/tests/unittests/sm.c @@ -23,6 +23,33 @@ #include "libopensc/log.c" #include "sm/sm-common.h" +/* Setup context */ +static int setup_sc_context(void **state) +{ + sc_context_t *ctx = NULL; + int rv; + + rv = sc_establish_context(&ctx, "sm"); + assert_non_null(ctx); + assert_int_equal(rv, SC_SUCCESS); + + *state = ctx; + + return 0; +} + +/* Cleanup context */ +static int teardown_sc_context(void **state) +{ + sc_context_t *ctx = *state; + int rv; + + rv = sc_release_context(ctx); + assert_int_equal(rv, SC_SUCCESS); + + return 0; +} + static void torture_sm_incr_ssc(void **state) { unsigned char in[] = {0x00, 0x00}; @@ -55,6 +82,158 @@ static void torture_sm_incr_ssc(void **state) assert_int_equal(in[1], 0x00); } +static void torture_sm_crypt_des_cbc3(void **state) +{ + sc_context_t *ctx = *state; + /* Test vector from + * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf + * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode + */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_crypt_des_cbc3_multiblock(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + sc_context_t *ctx = *state; + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0xAF, 0xA0, 0x77, 0x1d, 0x35, 0xE1, 0xCC, 0x26}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_crypt_des_cbc3_force_pad(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + sc_context_t *ctx = *state; + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0xC6, 0xD3, 0xE1, 0x4F, 0xFB, 0xDE, 0xDF, 0xF9}; + unsigned char *out = NULL; /* allocates */ + size_t out_len = 0; + int rv; + + rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 0); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_encrypt_des_ecb3(void **state) +{ + /* Test vector from + * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf + * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode + */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00}; + unsigned char *out = NULL; /* allocates */ + int out_len = 0; + int rv; + + (void)state; + + rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} + +static void torture_sm_encrypt_des_ecb3_multiblock(void **state) +{ + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */}; + unsigned char plain[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00}; + unsigned char ciphertext[] = { + 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00, + 0x18, 0x0d, 0x91, 0xdf, 0xa1, 0x25, 0x2f, 0x81}; + unsigned char *out = NULL; /* allocates */ + int out_len = 0; + int rv; + + (void)state; + + rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); + free(out); + out = NULL; + out_len = 0; + + rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +} int main(void) { @@ -62,6 +241,16 @@ int main(void) struct CMUnitTest tests[] = { /* sm_incr_ssc */ cmocka_unit_test(torture_sm_incr_ssc), + /* sm_encrypt_des_cbc3 and sm_decrypt_des_cbc3 */ + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_multiblock, + setup_sc_context, teardown_sc_context), + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_force_pad, + setup_sc_context, teardown_sc_context), + /* sm_encrypt_des_ecb3 */ + cmocka_unit_test(torture_sm_encrypt_des_ecb3), + cmocka_unit_test(torture_sm_encrypt_des_ecb3_multiblock), }; rc = cmocka_run_group_tests(tests, NULL, NULL);