From 3515b821866efcbe14609b1f63732c3628b56be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Sun, 7 Jul 2024 23:15:22 +0200 Subject: [PATCH] add cipher test for buffer lengths Use CHECK_XXX functions in cipher_drive, extend CHECK_XXX to improve testing. --- CMakeLists.txt | 2 +- Makefile.in | 2 +- crypto/cipher/aes_gcm_mbedtls.c | 14 ++- crypto/cipher/aes_gcm_nss.c | 24 +++- crypto/cipher/aes_gcm_ossl.c | 8 +- crypto/cipher/aes_gcm_wssl.c | 8 +- crypto/cipher/aes_icm_nss.c | 12 +- crypto/cipher/aes_icm_ossl.c | 8 ++ crypto/cipher/aes_icm_wssl.c | 8 ++ crypto/include/aes_gcm.h | 8 +- crypto/test/cipher_driver.c | 210 +++++++++++++++++++++++--------- test/util.c | 76 +++++++++++- test/util.h | 7 ++ 13 files changed, 305 insertions(+), 82 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa896e33a..7f7fa027b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -386,7 +386,7 @@ if(LIBSRTP_TEST_APPS) target_link_libraries(datatypes_driver srtp3) add_test(datatypes_driver datatypes_driver -v) - add_executable(cipher_driver crypto/test/cipher_driver.c test/getopt_s.c) + add_executable(cipher_driver crypto/test/cipher_driver.c test/getopt_s.c test/util.c) target_set_warnings( TARGET cipher_driver diff --git a/Makefile.in b/Makefile.in index 33bc66b03..2eae17e60 100644 --- a/Makefile.in +++ b/Makefile.in @@ -229,7 +229,7 @@ test/roc_driver$(EXE): test/roc_driver.c test/ut_sim.c test/replay_driver$(EXE): test/replay_driver.c test/ut_sim.c $(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) -crypto/test/cipher_driver$(EXE): crypto/test/cipher_driver.c test/getopt_s.c +crypto/test/cipher_driver$(EXE): crypto/test/cipher_driver.c test/getopt_s.c test/util.c $(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB) crypto/test/kernel_driver$(EXE): crypto/test/kernel_driver.c test/getopt_s.c diff --git a/crypto/cipher/aes_gcm_mbedtls.c b/crypto/cipher/aes_gcm_mbedtls.c index 4a6da1cfb..854d72b95 100644 --- a/crypto/cipher/aes_gcm_mbedtls.c +++ b/crypto/cipher/aes_gcm_mbedtls.c @@ -290,7 +290,7 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv, srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; int errCode = 0; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + if (c->dir != srtp_direction_encrypt) { return srtp_err_status_bad_param; } @@ -331,8 +331,12 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv, srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; int errCode = 0; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { - return (srtp_err_status_bad_param); + if (c->dir != srtp_direction_decrypt) { + return srtp_err_status_bad_param; + } + + if (src_len < c->tag_len) { + return srtp_err_status_bad_param; } if (*dst_len < (src_len - c->tag_len)) { @@ -347,7 +351,7 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv, src + (src_len - c->tag_len), c->tag_len, src, dst); c->aad_size = 0; if (errCode != 0) { - return (srtp_err_status_auth_fail); + return srtp_err_status_auth_fail; } /* @@ -356,7 +360,7 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv, */ *dst_len = (src_len - c->tag_len); - return (srtp_err_status_ok); + return srtp_err_status_ok; } /* diff --git a/crypto/cipher/aes_gcm_nss.c b/crypto/cipher/aes_gcm_nss.c index 6ecabf069..d70386d0f 100644 --- a/crypto/cipher/aes_gcm_nss.c +++ b/crypto/cipher/aes_gcm_nss.c @@ -301,16 +301,36 @@ static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv, SECItem param = { siBuffer, (unsigned char *)&c->params, sizeof(CK_GCM_PARAMS) }; if (encrypt) { + if (c->dir != srtp_direction_encrypt) { + return srtp_err_status_bad_param; + } + + if (*dst_len < src_len + c->tag_size) { + return srtp_err_status_buffer_small; + } + rv = PK11_Encrypt(c->key, CKM_AES_GCM, ¶m, dst, &out_len, *dst_len, src, src_len); } else { + if (c->dir != srtp_direction_decrypt) { + return srtp_err_status_bad_param; + } + + if (src_len < c->tag_size) { + return srtp_err_status_bad_param; + } + + if (*dst_len < src_len - c->tag_size) { + return srtp_err_status_buffer_small; + } + rv = PK11_Decrypt(c->key, CKM_AES_GCM, ¶m, dst, &out_len, *dst_len, src, src_len); } *dst_len = out_len; - srtp_err_status_t status = (srtp_err_status_ok); + srtp_err_status_t status = srtp_err_status_ok; if (rv != SECSuccess) { - status = (srtp_err_status_cipher_fail); + status = srtp_err_status_cipher_fail; } return status; diff --git a/crypto/cipher/aes_gcm_ossl.c b/crypto/cipher/aes_gcm_ossl.c index 3704eb848..6432abf44 100644 --- a/crypto/cipher/aes_gcm_ossl.c +++ b/crypto/cipher/aes_gcm_ossl.c @@ -300,7 +300,7 @@ static srtp_err_status_t srtp_aes_gcm_openssl_encrypt(void *cv, { srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + if (c->dir != srtp_direction_encrypt) { return srtp_err_status_bad_param; } @@ -347,7 +347,11 @@ static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv, { srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + if (c->dir != srtp_direction_decrypt) { + return srtp_err_status_bad_param; + } + + if (src_len < c->tag_len) { return srtp_err_status_bad_param; } diff --git a/crypto/cipher/aes_gcm_wssl.c b/crypto/cipher/aes_gcm_wssl.c index fec34d6c6..8f4699e20 100644 --- a/crypto/cipher/aes_gcm_wssl.c +++ b/crypto/cipher/aes_gcm_wssl.c @@ -330,7 +330,7 @@ static srtp_err_status_t srtp_aes_gcm_wolfssl_encrypt(void *cv, srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; int err; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + if (c->dir != srtp_direction_encrypt) { return srtp_err_status_bad_param; } @@ -385,7 +385,11 @@ static srtp_err_status_t srtp_aes_gcm_wolfssl_decrypt(void *cv, srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; int err; - if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + if (c->dir != srtp_direction_decrypt) { + return srtp_err_status_bad_param; + } + + if (src_len < c->tag_len) { return srtp_err_status_bad_param; } diff --git a/crypto/cipher/aes_icm_nss.c b/crypto/cipher/aes_icm_nss.c index ef141755e..5d6dc07b7 100644 --- a/crypto/cipher/aes_icm_nss.c +++ b/crypto/cipher/aes_icm_nss.c @@ -334,12 +334,20 @@ static srtp_err_status_t srtp_aes_icm_nss_encrypt(void *cv, return srtp_err_status_bad_param; } + if (dst_len == NULL) { + return srtp_err_status_bad_param; + } + + if (*dst_len < src_len) { + return srtp_err_status_buffer_small; + } + int out_len = 0; int rv = PK11_CipherOp(c->ctx, dst, &out_len, *dst_len, src, src_len); *dst_len = out_len; - srtp_err_status_t status = (srtp_err_status_ok); + srtp_err_status_t status = srtp_err_status_ok; if (rv != SECSuccess) { - status = (srtp_err_status_cipher_fail); + status = srtp_err_status_cipher_fail; } return status; diff --git a/crypto/cipher/aes_icm_ossl.c b/crypto/cipher/aes_icm_ossl.c index 81a5de7e3..82e7d9632 100644 --- a/crypto/cipher/aes_icm_ossl.c +++ b/crypto/cipher/aes_icm_ossl.c @@ -308,6 +308,14 @@ static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv, debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); + if (dst_len == NULL) { + return srtp_err_status_bad_param; + } + + if (*dst_len < src_len) { + return srtp_err_status_buffer_small; + } + if (!EVP_EncryptUpdate(c->ctx, dst, &len, src, src_len)) { return srtp_err_status_cipher_fail; } diff --git a/crypto/cipher/aes_icm_wssl.c b/crypto/cipher/aes_icm_wssl.c index a8f640bdc..41cb38eef 100644 --- a/crypto/cipher/aes_icm_wssl.c +++ b/crypto/cipher/aes_icm_wssl.c @@ -318,6 +318,14 @@ static srtp_err_status_t srtp_aes_icm_wolfssl_encrypt(void *cv, int err; debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); + if (dst_len == NULL) { + return srtp_err_status_bad_param; + } + + if (*dst_len < src_len) { + return srtp_err_status_buffer_small; + } + err = wc_AesCtrEncrypt(c->ctx, dst, src, src_len); if (err < 0) { debug_print(srtp_mod_aes_icm, "wolfSSL encrypt error: %d", err); diff --git a/crypto/include/aes_gcm.h b/crypto/include/aes_gcm.h index 5117ad122..d6705a460 100644 --- a/crypto/include/aes_gcm.h +++ b/crypto/include/aes_gcm.h @@ -76,11 +76,11 @@ typedef struct { #include typedef struct { - int key_size; - int tag_len; + size_t key_size; + size_t tag_len; #ifndef WOLFSSL_AESGCM_STREAM - int aad_size; - int iv_len; + size_t aad_size; + size_t iv_len; uint8_t iv[GCM_NONCE_MID_SZ]; uint8_t aad[MAX_AD_SIZE]; #endif diff --git a/crypto/test/cipher_driver.c b/crypto/test/cipher_driver.c index a17fc220f..a61ff19b1 100644 --- a/crypto/test/cipher_driver.c +++ b/crypto/test/cipher_driver.c @@ -52,8 +52,9 @@ #include "cipher_priv.h" #include "datatypes.h" #include "alloc.h" +#include "util.h" -#include /* for printf() */ +#include #include #define PRINT_DEBUG 0 @@ -62,7 +63,9 @@ void cipher_driver_test_throughput(srtp_cipher_t *c); srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct); -srtp_err_status_t cipher_driver_test_api(srtp_cipher_type_t *ct, int key_len); +srtp_err_status_t cipher_driver_test_api(srtp_cipher_type_t *ct, + size_t key_len, + size_t tag_len); /* * cipher_driver_test_buffering(ct) tests the cipher's output @@ -100,15 +103,6 @@ void usage(char *prog_name) exit(255); } -void check_status(srtp_err_status_t s) -{ - if (s) { - printf("error (code %d)\n", s); - exit(s); - } - return; -} - /* * null_cipher and srtp_aes_icm are the cipher meta-objects * defined in the files in crypto/cipher subdirectory. these are @@ -172,7 +166,7 @@ int main(int argc, char *argv[]) usage(argv[0]); } - /* arry timing (cache thrash) test */ + /* array timing (cache thrash) test */ if (do_array_timing_test) { size_t max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */ size_t num_cipher; @@ -220,25 +214,29 @@ int main(int argc, char *argv[]) cipher_driver_self_test(&srtp_aes_gcm_256); #endif cipher_driver_test_api(&srtp_aes_icm_128, - SRTP_AES_ICM_128_KEY_LEN_WSALT); + SRTP_AES_ICM_128_KEY_LEN_WSALT, 0); +#ifdef GCM + cipher_driver_test_api(&srtp_aes_gcm_128, + SRTP_AES_GCM_128_KEY_LEN_WSALT, 16); +#endif } /* do timing and/or buffer_test on srtp_null_cipher */ status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0); - check_status(status); + CHECK_OK(status); status = srtp_cipher_init(c, NULL); - check_status(status); + CHECK_OK(status); if (do_timing_test) { cipher_driver_test_throughput(c); } if (do_validation) { status = cipher_driver_test_buffering(c); - check_status(status); + CHECK_OK(status); } status = srtp_cipher_dealloc(c); - check_status(status); + CHECK_OK(status); /* run the throughput test on the aes_icm cipher (128-bit key) */ status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c, @@ -249,7 +247,7 @@ int main(int argc, char *argv[]) } status = srtp_cipher_init(c, test_key); - check_status(status); + CHECK_OK(status); if (do_timing_test) { cipher_driver_test_throughput(c); @@ -257,11 +255,11 @@ int main(int argc, char *argv[]) if (do_validation) { status = cipher_driver_test_buffering(c); - check_status(status); + CHECK_OK(status); } status = srtp_cipher_dealloc(c); - check_status(status); + CHECK_OK(status); /* repeat the tests with 256-bit keys */ status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, @@ -272,7 +270,7 @@ int main(int argc, char *argv[]) } status = srtp_cipher_init(c, test_key); - check_status(status); + CHECK_OK(status); if (do_timing_test) { cipher_driver_test_throughput(c); @@ -280,11 +278,11 @@ int main(int argc, char *argv[]) if (do_validation) { status = cipher_driver_test_buffering(c); - check_status(status); + CHECK_OK(status); } status = srtp_cipher_dealloc(c); - check_status(status); + CHECK_OK(status); #ifdef GCM /* run the throughput test on the aes_gcm_128 cipher */ @@ -295,7 +293,7 @@ int main(int argc, char *argv[]) exit(status); } status = srtp_cipher_init(c, test_key); - check_status(status); + CHECK_OK(status); if (do_timing_test) { cipher_driver_test_throughput(c); } @@ -303,7 +301,7 @@ int main(int argc, char *argv[]) // GCM ciphers don't do buffering; they're "one shot" status = srtp_cipher_dealloc(c); - check_status(status); + CHECK_OK(status); /* run the throughput test on the aes_gcm_256 cipher */ status = srtp_cipher_type_alloc(&srtp_aes_gcm_256, &c, @@ -313,7 +311,7 @@ int main(int argc, char *argv[]) exit(status); } status = srtp_cipher_init(c, test_key); - check_status(status); + CHECK_OK(status); if (do_timing_test) { cipher_driver_test_throughput(c); } @@ -321,7 +319,7 @@ int main(int argc, char *argv[]) // GCM ciphers don't do buffering; they're "one shot" status = srtp_cipher_dealloc(c); - check_status(status); + CHECK_OK(status); #endif return 0; @@ -354,16 +352,27 @@ srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct) printf("running cipher self-test for %s...", ct->description); status = srtp_cipher_type_self_test(ct); - if (status) { - printf("failed with error code %d\n", status); - exit(status); - } + CHECK_OK(status); printf("passed\n"); return srtp_err_status_ok; } -srtp_err_status_t cipher_driver_test_api(srtp_cipher_type_t *ct, int key_len) +void reint_cipher(srtp_cipher_t *c, + uint8_t *test_key, + uint8_t *iv, + srtp_cipher_direction_t direction) +{ + srtp_err_status_t status = srtp_cipher_init(c, test_key); + CHECK_OK(status); + + status = srtp_cipher_set_iv(c, iv, direction); + CHECK_OK(status); +} + +srtp_err_status_t cipher_driver_test_api(srtp_cipher_type_t *ct, + size_t key_len, + size_t tag_len) { srtp_err_status_t status; srtp_cipher_t *c = NULL; @@ -380,33 +389,131 @@ srtp_err_status_t cipher_driver_test_api(srtp_cipher_type_t *ct, int key_len) uint8_t iv[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + uint8_t plaintext[64] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }; + uint8_t encrypted[96] = {0}; + uint8_t decrypted[96] = {0}; /* clang-format on */ printf("testing cipher api for %s...", ct->description); + fflush(stdout); - if (key_len > (int)sizeof(test_key)) { + if (key_len > sizeof(test_key)) { return srtp_err_status_bad_param; } - status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, key_len, 0); - if (status) { - return status; - } + status = srtp_cipher_type_alloc(ct, &c, key_len, tag_len); + CHECK_OK(status); status = srtp_cipher_init(c, test_key); - if (status) { - return status; - } + CHECK_OK(status); status = srtp_cipher_set_iv(c, iv, srtp_direction_encrypt); - if (status) { - return status; + CHECK_OK(status); + + size_t src_len; + size_t dst_len; + + // test dst len zero + src_len = sizeof(plaintext); + dst_len = 0; + status = srtp_cipher_encrypt(c, plaintext, src_len, encrypted, &dst_len); + CHECK_RETURN(status, srtp_err_status_buffer_small); + + reint_cipher(c, test_key, iv, srtp_direction_encrypt); + + // test dst len smaller than expected + src_len = sizeof(plaintext); + dst_len = src_len + tag_len - 1; + status = srtp_cipher_encrypt(c, plaintext, src_len, encrypted, &dst_len); + CHECK_RETURN(status, srtp_err_status_buffer_small); + + reint_cipher(c, test_key, iv, srtp_direction_encrypt); + + // test dst len exact size + src_len = sizeof(plaintext); + dst_len = src_len + tag_len; + status = srtp_cipher_encrypt(c, plaintext, src_len, encrypted, &dst_len); + CHECK_OK(status); + CHECK(dst_len == src_len + tag_len); + + reint_cipher(c, test_key, iv, srtp_direction_encrypt); + + // dst len larger than src len + src_len = sizeof(plaintext); + dst_len = sizeof(encrypted); + status = srtp_cipher_encrypt(c, plaintext, src_len, encrypted, &dst_len); + CHECK_OK(status); + CHECK(dst_len == src_len + tag_len); + + reint_cipher(c, test_key, iv, srtp_direction_encrypt); + + size_t encrypted_len = dst_len; + + // init for decrypt + status = srtp_cipher_init(c, test_key); + CHECK_OK(status); + + status = srtp_cipher_set_iv(c, iv, srtp_direction_decrypt); + CHECK_OK(status); + + if (tag_len != 0) { + // test src less than tag len + src_len = tag_len - 1; + dst_len = sizeof(decrypted); + status = + srtp_cipher_decrypt(c, encrypted, src_len, decrypted, &dst_len); + CHECK_RETURN(status, srtp_err_status_bad_param); + + reint_cipher(c, test_key, iv, srtp_direction_decrypt); } + // test dst len zero + src_len = encrypted_len; + dst_len = 0; + status = srtp_cipher_decrypt(c, encrypted, src_len, decrypted, &dst_len); + CHECK_RETURN(status, srtp_err_status_buffer_small); + + reint_cipher(c, test_key, iv, srtp_direction_decrypt); + + // test dst len smaller than expected + src_len = encrypted_len; + dst_len = src_len - tag_len - 1; + status = srtp_cipher_decrypt(c, encrypted, src_len, decrypted, &dst_len); + CHECK_RETURN(status, srtp_err_status_buffer_small); + + reint_cipher(c, test_key, iv, srtp_direction_decrypt); + + // test dst len exact + src_len = encrypted_len; + dst_len = src_len - tag_len; + status = srtp_cipher_decrypt(c, encrypted, src_len, decrypted, &dst_len); + CHECK_OK(status); + CHECK(dst_len == sizeof(plaintext)); + CHECK_BUFFER_EQUAL(plaintext, decrypted, sizeof(plaintext)); + + reint_cipher(c, test_key, iv, srtp_direction_decrypt); + + // dst len larger than src len + src_len = encrypted_len; + dst_len = sizeof(decrypted); + status = srtp_cipher_decrypt(c, encrypted, src_len, decrypted, &dst_len); + CHECK_OK(status); + CHECK(dst_len == sizeof(plaintext)); + CHECK_BUFFER_EQUAL(plaintext, decrypted, sizeof(plaintext)); + + reint_cipher(c, test_key, iv, srtp_direction_decrypt); + status = srtp_cipher_dealloc(c); - if (status) { - return status; - } + CHECK_OK(status); printf("passed\n"); @@ -482,18 +589,7 @@ srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c) } /* compare buffers */ - for (size_t j = 0; j < buflen; j++) { - if (buffer0[j] != buffer1[j]) { -#if PRINT_DEBUG - printf("test case %zd failed at byte %zu\n", i, j); - printf("computed: %s\n", - octet_string_hex_string(buffer1, buflen)); - printf("expected: %s\n", - octet_string_hex_string(buffer0, buflen)); -#endif - return srtp_err_status_algo_fail; - } - } + CHECK_BUFFER_EQUAL(buffer0, buffer1, buflen); } printf("passed\n"); diff --git a/test/util.c b/test/util.c index 4385b507e..16b678c7d 100644 --- a/test/util.c +++ b/test/util.c @@ -52,11 +52,52 @@ /* include space for null terminator */ static char bit_string[MAX_PRINT_STRING_LEN + 1]; +#define ERR_STATUS_STRING(STATUS) \ + case srtp_err_status_##STATUS: \ + return #STATUS + +const char *err_status_string(srtp_err_status_t status) +{ + switch (status) { + ERR_STATUS_STRING(ok); + ERR_STATUS_STRING(fail); + ERR_STATUS_STRING(bad_param); + ERR_STATUS_STRING(alloc_fail); + ERR_STATUS_STRING(dealloc_fail); + ERR_STATUS_STRING(init_fail); + ERR_STATUS_STRING(terminus); + ERR_STATUS_STRING(auth_fail); + ERR_STATUS_STRING(cipher_fail); + ERR_STATUS_STRING(replay_fail); + ERR_STATUS_STRING(replay_old); + ERR_STATUS_STRING(algo_fail); + ERR_STATUS_STRING(no_such_op); + ERR_STATUS_STRING(no_ctx); + ERR_STATUS_STRING(cant_check); + ERR_STATUS_STRING(key_expired); + ERR_STATUS_STRING(socket_err); + ERR_STATUS_STRING(signal_err); + ERR_STATUS_STRING(nonce_bad); + ERR_STATUS_STRING(read_fail); + ERR_STATUS_STRING(write_fail); + ERR_STATUS_STRING(parse_err); + ERR_STATUS_STRING(encode_err); + ERR_STATUS_STRING(semaphore_err); + ERR_STATUS_STRING(pfkey_err); + ERR_STATUS_STRING(bad_mki); + ERR_STATUS_STRING(pkt_idx_old); + ERR_STATUS_STRING(pkt_idx_adv); + ERR_STATUS_STRING(buffer_small); + } + return "unkown srtp_err_status"; +} + void check_ok_impl(srtp_err_status_t status, const char *file, int line) { if (status != srtp_err_status_ok) { - fprintf(stderr, "error at %s:%d, unexpected srtp failure (code %d)\n", - file, line, status); + fprintf(stderr, + "\nerror at %s:%d, unexpected srtp failure: %d (\"%s\")\n", + file, line, status, err_status_string(status)); exit(1); } } @@ -68,8 +109,10 @@ void check_return_impl(srtp_err_status_t status, { if (status != expected) { fprintf(stderr, - "error at %s:%d, unexpected srtp status (code %d != %d)\n", - file, line, status, expected); + "\nerror at %s:%d, unexpected srtp status: %d != %d (\"%s\" != " + "\"%s\")\n", + file, line, status, expected, err_status_string(status), + err_status_string(expected)); exit(1); } } @@ -80,7 +123,7 @@ void check_impl(bool condition, const char *condition_str) { if (!condition) { - fprintf(stderr, "error at %s:%d, %s)\n", file, line, condition_str); + fprintf(stderr, "\nerror at %s:%d, %s)\n", file, line, condition_str); exit(1); } } @@ -92,6 +135,27 @@ void overrun_check_prepare(uint8_t *buffer, size_t offset, size_t buffer_len) memset(buffer + offset, OVERRUN_CHECK_BYTE, buffer_len - offset); } +void check_buffer_equal_impl(const uint8_t *buffer1, + const uint8_t *buffer2, + size_t buffer_length, + const char *file, + int line) +{ + for (size_t i = 0; i < buffer_length; i++) { + if (buffer1[i] != buffer2[i]) { + fprintf(stderr, + "\nerror at %s:%d, buffer1 != buffer2 at index: %zu (%x != " + "%x)\n", + file, line, i, buffer1[i], buffer2[i]); + fprintf(stderr, "buffer1 = %s\n", + octet_string_hex_string(buffer1, buffer_length)); + fprintf(stderr, "buffer2 = %s\n", + octet_string_hex_string(buffer2, buffer_length)); + exit(1); + } + } +} + void check_overrun_impl(const uint8_t *buffer, size_t offset, size_t buffer_length, @@ -100,7 +164,7 @@ void check_overrun_impl(const uint8_t *buffer, { for (size_t i = offset; i < buffer_length; i++) { if (buffer[i] != OVERRUN_CHECK_BYTE) { - printf("error at %s:%d, overrun detected in buffer at index %zu " + printf("\nerror at %s:%d, overrun detected in buffer at index %zu " "(expected %x, found %x)\n", file, line, i, OVERRUN_CHECK_BYTE, buffer[i]); exit(1); diff --git a/test/util.h b/test/util.h index 43926bcff..4f86552b9 100644 --- a/test/util.h +++ b/test/util.h @@ -56,6 +56,11 @@ void check_impl(bool condition, const char *file, int line, const char *condition_str); +void check_buffer_equal_impl(const uint8_t *buffer1, + const uint8_t *buffer2, + size_t buffer_length, + const char *file, + int line); void check_overrun_impl(const uint8_t *buffer, size_t offset, size_t buffer_length, @@ -67,6 +72,8 @@ void overrun_check_prepare(uint8_t *buffer, size_t offset, size_t buffer_len); #define CHECK_RETURN(status, expected) \ check_return_impl((status), (expected), __FILE__, __LINE__) #define CHECK(condition) check_impl((condition), __FILE__, __LINE__, #condition) +#define CHECK_BUFFER_EQUAL(buffer1, buffer2, length) \ + check_buffer_equal_impl((buffer1), (buffer2), (length), __FILE__, __LINE__) #define CHECK_OVERRUN(buffer, offset, length) \ check_overrun_impl((buffer), (offset), (length), __FILE__, __LINE__)