From 2e505c2dc7a7e849fe7a327f9cbdfc587477a3d1 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sun, 13 Jul 2025 07:42:58 +0200 Subject: irmd: Initial Flow Allocation Protocol Header This adds the initial version for the flow allocation protocol header between IRMd instances. This is a step towards flow authentication. The header supports secure and authenticated flow allocation, supporting certificate-based authentication and ephemeral key exchange for end-to-end encryption. id: 128-bit identifier for the entity. timestamp: 64-bit timestamp (replay protection). certificate: Certificate for authentication. public key: ECDHE public key for key exchange. data: Application data. signature: Signature for integrity/authenticity. Authentication and encryption require OpenSSL to be installed. The IRMd compares the allocation request delay with the MPL of the Layer over which the flow allocation was sent. MPL is now reported by the Layer in ms instead of seconds. Time functions revised for consistency and adds some tests. The TPM can now print thread running times in Debug builds (TPM_DEBUG_REPORT_INTERVAL) and abort processes with hung threads (TPM_DEBUG_ABORT_TIMEOUT). Long running threads waiting for input should call tpm_wait_work() to avoid trigger a process abort. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/lib/tests/auth_test.c | 8 +- src/lib/tests/time_test.c | 545 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 458 insertions(+), 95 deletions(-) (limited to 'src/lib/tests') diff --git a/src/lib/tests/auth_test.c b/src/lib/tests/auth_test.c index c3d42b8f..271fdabf 100644 --- a/src/lib/tests/auth_test.c +++ b/src/lib/tests/auth_test.c @@ -36,7 +36,7 @@ * https://community.f5.com/kb/technicalarticles/ */ -/* Root certificate for CA ca.unittest.o7s */ +/* Root certificate for CA ca2.unittest.o7s */ static const char * root_ca_crt = \ "-----BEGIN CERTIFICATE-----\n" "MIICiTCCAi+gAwIBAgIUe4iFIymeUTgutBrdvcxFihOVHnowCgYIKoZIzj0EAwIw\n" @@ -55,7 +55,7 @@ static const char * root_ca_crt = \ "JSTSWB29kFFiM9ZdMV7M/tiZH9nSz1M8XhsTIGk=\n" "-----END CERTIFICATE-----\n"; -/* Certificate for intermediary im.unittest.o7s used for signing */ +/* Certificate for intermediary im2.unittest.o7s used for signing */ static const char * intermediate_ca_crt = \ "-----BEGIN CERTIFICATE-----\n" "MIIChTCCAiqgAwIBAgICEAIwCgYIKoZIzj0EAwIwgZExCzAJBgNVBAYTAkJFMQww\n" @@ -74,7 +74,7 @@ static const char * intermediate_ca_crt = \ "NnkLn+73oMj8w4pXGLNKAkX0z7yPJ4QhwA==\n" "-----END CERTIFICATE-----\n"; -/* Server server-1.unittest.o7s private-public key pair */ +/* Server server-2.unittest.o7s private-public key pair */ static const char * server_ec_pkp = \ "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIC13y+5jdKe80HBJD7WITpQamcn3rrkTX1r0v+JwSk4NoAoGCCqGSM49\n" @@ -89,7 +89,7 @@ static const char * server_ec_pk = \ "uhDhqqrEcBO5+eob2xyqEaNknIV/86724zPptGRahWz0rzW2PvNppJdNBg==\n" "-----END PUBLIC KEY-----\n"; -/* Valid signed server certificate for server-1.unittest.o7s, SHA2 */ +/* Valid signed server certificate for server-2.unittest.o7s */ static const char * signed_server_crt = \ "-----BEGIN CERTIFICATE-----\n" "MIIDgjCCAyigAwIBAgICEAIwCgYIKoZIzj0EAwIwWzELMAkGA1UEBhMCQkUxDDAK\n" diff --git a/src/lib/tests/time_test.c b/src/lib/tests/time_test.c index 77fecdac..2b75b873 100644 --- a/src/lib/tests/time_test.c +++ b/src/lib/tests/time_test.c @@ -22,145 +22,508 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include -static void ts_print(struct timespec * s) +static int ts_check(struct timespec * s, + time_t sec, + time_t nsec) { - printf("timespec is %zd:%ld.\n", - (ssize_t) s->tv_sec, s->tv_nsec); + return s->tv_sec == sec && s->tv_nsec == nsec; } -static void tv_print(struct timeval * v) +static int tv_check(struct timeval * v, + time_t sec, + time_t usec) { - printf("timeval is %zd:%zu.\n", - (ssize_t) v->tv_sec, (size_t) v->tv_usec); + return v->tv_sec == sec && v->tv_usec == usec; } -static void ts_init(struct timespec * s, - time_t sec, - time_t nsec) + +static int test_time_ts_init(void) { - s->tv_sec = sec; - s->tv_nsec = nsec; + struct timespec s = TIMESPEC_INIT_S (100); + struct timespec ms = TIMESPEC_INIT_MS(100); + struct timespec us = TIMESPEC_INIT_US(100); + struct timespec ns = TIMESPEC_INIT_NS(100); + + TEST_START(); + + if (!ts_check(&s, 100, 0)) { + printf("timespec_init_s failed.\n"); + goto fail; + } + + if (!ts_check(&ms, 0, 100 * MILLION)) { + printf("timespec_init_ms failed.\n"); + goto fail; + } + + if (!ts_check(&us, 0, 100* 1000L)) { + printf("timespec_init_us failed.\n"); + goto fail; + } + + if (!ts_check(&ns, 0, 100)) { + printf("timespec_init_ns failed.\n"); + goto fail; + } + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; } -static void tv_init(struct timeval * v, - time_t sec, - time_t usec) +static int test_time_tv_init(void) { - v->tv_sec = sec; - v->tv_usec = usec; + struct timeval s = TIMEVAL_INIT_S (100); + struct timeval ms = TIMEVAL_INIT_MS(100); + struct timeval us = TIMEVAL_INIT_US(100); + + TEST_START(); + + if (!tv_check(&s, 100, 0)) { + printf("timeval_init_s failed.\n"); + goto fail; + } + + if (!tv_check(&ms, 0, 100 * 1000L)) { + printf("timeval_init_ms failed.\n"); + goto fail; + } + + if (!tv_check(&us, 0, 100)) { + printf("timeval_init_us failed.\n"); + goto fail; + } + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; } -static int ts_check(struct timespec * s, - time_t sec, - time_t nsec) +static int test_ts_diff(void) { - return s->tv_sec == sec && s->tv_nsec == nsec; + struct timespec s0 = TIMESPEC_INIT_S (100); + struct timespec s1 = TIMESPEC_INIT_S (200); + struct timespec ms0 = TIMESPEC_INIT_MS(100); + struct timespec ms1 = TIMESPEC_INIT_MS(200); + struct timespec us0 = TIMESPEC_INIT_US(100); + struct timespec us1 = TIMESPEC_INIT_US(200); + struct timespec ns0 = TIMESPEC_INIT_NS(100); + struct timespec ns1 = TIMESPEC_INIT_NS(200); + struct timespec res; + + TEST_START(); + + ts_diff(&s0, &s1, &res); + if (!ts_check(&res, -100, 0)) { + printf("timespec_diff failed at s0 - s1.\n"); + goto fail; + } + + ts_diff(&s1, &s0, &res); + if (!ts_check(&res, 100, 0)) { + printf("timespec_diff failed at s1 - s0.\n"); + goto fail; + } + + ts_diff(&ms0, &ms1, &res); + if (!ts_check(&res, -1, 900 * MILLION)) { + printf("timespec_diff failed at ms0 - ms1.\n"); + goto fail; + } + + ts_diff(&ms1, &ms0, &res); + if (!ts_check(&res, 0, 100 * MILLION)) { + printf("timespec_diff failed at ms1 - ms0.\n"); + goto fail; + } + + ts_diff(&us0, &us1, &res); + if (!ts_check(&res, -1, 999900 * 1000L)) { + printf("timespec_diff failed at us0 - us1.\n"); + goto fail; + } + + ts_diff(&us1, &us0, &res); + if (!ts_check(&res, 0, 100 * 1000L)) { + printf("timespec_diff failed at us1 - us0.\n"); + goto fail; + } + + ts_diff(&ns0, &ns1, &res); + if (!ts_check(&res, -1, 999999900)) { + printf("timespec_diff failed at ns0 - ns1.\n"); + goto fail; + } + + ts_diff(&ns1, &ns0, &res); + if (!ts_check(&res, 0, 100)) { + printf("timespec_diff failed at ns1 - ns0.\n"); + goto fail; + } + + ts_diff(&s0, &ms0, &res); + if (!ts_check(&res, 99, 900 * MILLION)) { + printf("timespec_diff failed at s0 - ms0.\n"); + goto fail; + } + + ts_diff(&s0, &us0, &res); + if (!ts_check(&res, 99, 999900 * 1000L)) { + printf("timespec_diff failed at s0 - us0.\n"); + goto fail; + } + + ts_diff(&s0, &ns0, &res); + if (!ts_check(&res, 99, 999999900)) { + printf("timespec_diff failed at s0 - ns0.\n"); + goto fail; + } + + ts_diff(&ms0, &us0, &res); + if (!ts_check(&res, 0, 99900 * 1000L)) { + printf("timespec_diff failed at ms0 - us0.\n"); + goto fail; + } + + ts_diff(&ms0, &ns0, &res); + if (!ts_check(&res, 0, 99999900)) { + printf("timespec_diff failed at ms0 - ns0.\n"); + goto fail; + } + + ts_diff(&us0, &ns0, &res); + if (!ts_check(&res, 0, 99900)) { + printf("timespec_diff failed at us0 - ns0.\n"); + goto fail; + } + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; } -static int tv_check(struct timeval * v, - time_t sec, - time_t usec) +static int test_tv_diff(void) { - return v->tv_sec == sec && v->tv_usec == usec; + struct timeval s0 = TIMEVAL_INIT_S (100); + struct timeval s1 = TIMEVAL_INIT_S (200); + struct timeval ms0 = TIMEVAL_INIT_MS(100); + struct timeval ms1 = TIMEVAL_INIT_MS(200); + struct timeval us0 = TIMEVAL_INIT_US(100); + struct timeval us1 = TIMEVAL_INIT_US(200); + struct timeval res; + + TEST_START(); + + tv_diff(&s0, &s1, &res); + if (!tv_check(&res, -100, 0)) { + printf("timeval_diff failed at s0 - s1.\n"); + goto fail; + } + + tv_diff(&s1, &s0, &res); + if (!tv_check(&res, 100, 0)) { + printf("timeval_diff failed at s1 - s0.\n"); + goto fail; + } + + tv_diff(&ms0, &ms1, &res); + if (!tv_check(&res, -1, 900 * 1000L)) { + printf("timeval_diff failed at ms0 - ms1.\n"); + goto fail; + } + + tv_diff(&ms1, &ms0, &res); + if (!tv_check(&res, 0, 100 * 1000L)) { + printf("timeval_diff failed at ms1 - ms0.\n"); + goto fail; + } + + tv_diff(&us0, &us1, &res); + if (!tv_check(&res, -1, 999900)) { + printf("timeval_diff failed at us0 - us1.\n"); + goto fail; + } + + tv_diff(&us1, &us0, &res); + if (!tv_check(&res, 0, 100)) { + printf("timeval_diff failed at us1 - us0.\n"); + goto fail; + } + + tv_diff(&s0, &ms0, &res); + if (!tv_check(&res, 99, 900 * 1000L)) { + printf("timeval_diff failed at s0 - ms0.\n"); + goto fail; + } + + tv_diff(&s0, &us0, &res); + if (!tv_check(&res, 99, 999900)) { + printf("timeval_diff failed at s0 - us0.\n"); + goto fail; + } + + tv_diff(&ms0, &us0, &res); + if (!tv_check(&res, 0, 99900)) { + printf("timeval_diff failed at ms0 - us0.\n"); + goto fail; + } + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; } -int time_test(int argc, - char ** argv) +static int test_ts_diff_time(void) { - struct timespec s0; - struct timespec s1; - struct timespec s2; + struct timespec s0 = TIMESPEC_INIT_S (100); + struct timespec s1 = TIMESPEC_INIT_S (200); + struct timespec ms0 = TIMESPEC_INIT_MS(100); + struct timespec ms1 = TIMESPEC_INIT_MS(200); + struct timespec us0 = TIMESPEC_INIT_US(100); + struct timespec us1 = TIMESPEC_INIT_US(200); + struct timespec ns0 = TIMESPEC_INIT_NS(100); + struct timespec ns1 = TIMESPEC_INIT_NS(200); - struct timeval v0; - struct timeval v1; - struct timeval v2; + TEST_START(); - (void) argc; - (void) argv; + if (ts_diff_ms(&s0, &s1) != -100 * 1000L) { + printf("timespec_diff_ms failed at s0 - s1.\n"); + goto fail; + } + + if (ts_diff_ms(&s1, &s0) != 100 * 1000L) { + printf("timespec_diff_ms failed at s1 - s0.\n"); + goto fail; + } + + if (ts_diff_us(&s0, &s1) != -100 * MILLION) { + printf("timespec_diff_us failed at s1 - s0.\n"); + goto fail; + } + + if (ts_diff_us(&s1, &s0) != 100 * MILLION) { + printf("timespec_diff_us failed at s0 - s1.\n"); + goto fail; + } + + if (ts_diff_ns(&s0, &s1) != -100 * BILLION) { + printf("timespec_diff_ns failed at s0 - s1.\n"); + goto fail; + } + + if (ts_diff_ns(&s1, &s0) != 100 * BILLION) { + printf("timespec_diff_ns failed at s1 - s0.\n"); + goto fail; + } + + if (ts_diff_ms(&ms0, &ms1) != -100) { + printf("timespec_diff_ms failed at ms0 - ms1.\n"); + goto fail; + } + + if (ts_diff_ms(&ms1, &ms0) != 100) { + printf("timespec_diff_ms failed at ms1 - ms0.\n"); + goto fail; + } - ts_init(&s0, 0, 0); - ts_init(&s1, 5, 0); + if (ts_diff_us(&ms0, &ms1) != -100 * 1000L) { + printf("timespec_diff_us failed at ms0 - ms1.\n"); + goto fail; + } - ts_add(&s0, &s1, &s2); - if (!ts_check(&s2, 5, 0)) { - printf("ts_add failed.\n"); - ts_print(&s2); - return -1; + if (ts_diff_us(&ms1, &ms0) != 100 * 1000L) { + printf("timespec_diff_us failed at ms1 - ms0.\n"); + goto fail; } - tv_init(&v0, 0, 0); - tv_init(&v1, 5, 0); + if (ts_diff_ns(&ms0, &ms1) != -100 * MILLION) { + printf("timespec_diff_ns failed at ms0 - ms1.\n"); + goto fail; + } - tv_add(&v0, &v1, &v2); - if (!tv_check(&v2, 5, 0)) { - printf("tv_add failed.\n"); - tv_print(&v2); - return -1; + if (ts_diff_ns(&ms1, &ms0) != 100 * MILLION) { + printf("timespec_diff_ns failed at ms1 - ms0.\n"); + goto fail; } - ts_init(&s0, 0, 500 * MILLION); - ts_init(&s1, 0, 600 * MILLION); + if (ts_diff_ms(&us0, &us1) != 0) { + printf("timespec_diff_ms failed at us0 - us1.\n"); + goto fail; + } - ts_add(&s0, &s1, &s2); - if (!ts_check(&s2, 1, 100 * MILLION)) { - printf("ts_add with nano overflow failed.\n"); - ts_print(&s2); - return -1; + if (ts_diff_ms(&us1, &us0) != 0) { + printf("timespec_diff_ms failed at us1 - us0.\n"); + goto fail; } - tv_init(&v0, 0, 500 * 1000); - tv_init(&v1, 0, 600 * 1000); + if (ts_diff_us(&us0, &us1) != -100) { + printf("timespec_diff_us failed at us0 - us1.\n"); + goto fail; + } - tv_add(&v0, &v1, &v2); - if (!tv_check(&v2, 1, 100 * 1000)) { - printf("tv_add with nano overflow failed.\n"); - tv_print(&v2); - return -1; + if (ts_diff_us(&us1, &us0) != 100) { + printf("timespec_diff_us failed at us1 - us0.\n"); + goto fail; } - ts_init(&s0, 0, 0); - ts_init(&s1, 5, 0); + if (ts_diff_ns(&us0, &us1) != -100 * 1000L) { + printf("timespec_diff_ns failed at us0 - us1.\n"); + goto fail; + } - ts_diff(&s0, &s1, &s2); - if (!ts_check(&s2, -5, 0)) { - printf("ts_diff failed.\n"); - ts_print(&s2); - return -1; + if (ts_diff_ns(&us1, &us0) != 100 * 1000L) { + printf("timespec_diff_ns failed at us1 - us0.\n"); + goto fail; } - tv_init(&v0, 0, 0); - tv_init(&v1, 5, 0); + if (ts_diff_ms(&ns0, &ns1) != 0) { + printf("timespec_diff_ms failed at ns0 - ns1.\n"); + goto fail; + } - tv_diff(&v0, &v1, &v2); - if (!tv_check(&v2, -5, 0)) { - printf("tv_diff failed.\n"); - tv_print(&v2); - return -1; + if (ts_diff_ms(&ns1, &ns0) != 0) { + printf("timespec_diff_ms failed at ns1 - ns0.\n"); + goto fail; } - ts_init(&s0, 0, 500 * MILLION); - ts_init(&s1, 0, 600 * MILLION); + if (ts_diff_us(&ns0, &ns1) != 0) { + printf("timespec_diff_us failed at ns0 - ns1.\n"); + goto fail; + } - ts_diff(&s0, &s1, &s2); - if (!ts_check(&s2, -1, 900 * MILLION)) { - printf("ts_diff with nano underflow failed.\n"); - ts_print(&s2); - return -1; + if (ts_diff_us(&ns1, &ns0) != 0) { + printf("timespec_diff_us failed at ns1 - ns0.\n"); + goto fail; } - tv_init(&v0, 0, 500 * 1000); - tv_init(&v1, 0, 600 * 1000); + if (ts_diff_ns(&ns0, &ns1) != -100) { + printf("timespec_diff_ns failed at ns0 - ns1.\n"); + goto fail; + } - tv_diff(&v0, &v1, &v2); - if (!tv_check(&v2, -1, 900 * 1000)) { - printf("tv_diff with nano underflow failed.\n"); - tv_print(&v2); - return -1; + if (ts_diff_ns(&ns1, &ns0) != 100) { + printf("timespec_diff_ns failed at ns1 - ns0.\n"); + goto fail; } - return 0; + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_tv_diff_time(void) +{ + struct timeval s0 = TIMEVAL_INIT_S (100); + struct timeval s1 = TIMEVAL_INIT_S (200); + struct timeval ms0 = TIMEVAL_INIT_MS(100); + struct timeval ms1 = TIMEVAL_INIT_MS(200); + struct timeval us0 = TIMEVAL_INIT_US(100); + struct timeval us1 = TIMEVAL_INIT_US(200); + + TEST_START(); + + if (tv_diff_ms(&s0, &s1) != -100 * 1000L) { + printf("timeval_diff_ms failed at s0 - s1.\n"); + goto fail; + } + + if (tv_diff_ms(&s1, &s0) != 100 * 1000L) { + printf("timeval_diff_ms failed at s1 - s0.\n"); + goto fail; + } + + if (tv_diff_us(&s0, &s1) != -100 * MILLION) { + printf("timeval_diff_us failed at s0 - s1.\n"); + goto fail; + } + + if (tv_diff_us(&s1, &s0) != 100 * MILLION) { + printf("timeval_diff_us failed at s1 - s0.\n"); + goto fail; + } + + if (tv_diff_ms(&ms0, &ms1) != -100) { + printf("timeval_diff_ms failed at ms0 - ms1.\n"); + goto fail; + } + + if (tv_diff_ms(&ms1, &ms0) != 100) { + printf("timeval_diff_ms failed at ms1 - ms0.\n"); + goto fail; + } + + if (tv_diff_us(&ms0, &ms1) != -100 * 1000L) { + printf("timeval_diff_us failed at ms0 - ms1.\n"); + goto fail; + } + + if (tv_diff_us(&ms1, &ms0) != 100 * 1000L) { + printf("timeval_diff_us failed at ms1 - ms0.\n"); + goto fail; + } + + if (tv_diff_ms(&us0, &us1) != 0) { + printf("timeval_diff_ms failed at us0 - us1.\n"); + goto fail; + } + + if (tv_diff_ms(&us1, &us0) != 0) { + printf("timeval_diff_ms failed at us1 - us0.\n"); + goto fail; + } + + if (tv_diff_us(&us0, &us1) != -100) { + printf("timeval_diff_us failed at us0 - us1.\n"); + goto fail; + } + + if (tv_diff_us(&us1, &us0) != 100) { + printf("timeval_diff_us failed at us1 - us0.\n"); + goto fail; + } + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +int time_test(int argc, + char ** argv) +{ + int ret = 0; + + (void) argc; + (void) argv; + + ret |= test_time_ts_init(); + ret |= test_time_tv_init(); + ret |= test_ts_diff(); + ret |= test_tv_diff(); + ret |= test_ts_diff_time(); + ret |= test_tv_diff_time(); + + return ret; } -- cgit v1.2.3