diff --git a/WORKSPACE b/WORKSPACE index 6e5bd08..0e5a5d5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,17 +1,11 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -# Hedron's Compile Commands Extractor for Bazel -# https://github.com/hedronvision/bazel-compile-commands-extractor http_archive( name = "hedron_compile_commands", - - # Replace the commit hash in both places (below) with the latest, rather than using the stale one here. - # Even better, set up Renovate and let it do the work for you (see "Suggestion: Updates" in the README). url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/e16062717d9b098c3c2ac95717d2b3e661c50608.tar.gz", strip_prefix = "bazel-compile-commands-extractor-e16062717d9b098c3c2ac95717d2b3e661c50608", - # When you first run this tool, it'll recommend a sha256 hash to put here with a message like: "DEBUG: Rule 'hedron_compile_commands' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = ..." + sha256 = "ed5aea1dc87856aa2029cb6940a51511557c5cac3dbbcb05a4abd989862c36b4" ) load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup") hedron_compile_commands_setup() diff --git a/src/sys_unix.h b/src/sys_unix.h index b2baf19..0c19a42 100644 --- a/src/sys_unix.h +++ b/src/sys_unix.h @@ -8,5 +8,6 @@ #include #include #include +#include #endif diff --git a/test/test_server_0x27_security_access.c b/test/test_server_0x27_security_access.c index 6871d8d..ddf8c99 100644 --- a/test/test_server_0x27_security_access.c +++ b/test/test_server_0x27_security_access.c @@ -1,6 +1,8 @@ -#include "iso14229.h" #include "test/test.h" +static UDSTpHandle_t *mock_client = NULL; +static UDSServer_t srv; + // UDS-1 2013 9.4.5.2 // UDS-1 2013 9.4.5.3 uint8_t fn(UDSServer_t *srv, UDSServerEvent_t ev, const void *arg) { @@ -15,8 +17,11 @@ uint8_t fn(UDSServer_t *srv, UDSServerEvent_t ev, const void *arg) { case UDS_SRV_EVT_SecAccessValidateKey: { UDSSecAccessValidateKeyArgs_t *r = (UDSSecAccessValidateKeyArgs_t *)arg; const uint8_t expected_key[] = {0xC9, 0xA9}; - TEST_INT_EQUAL(r->len, sizeof(expected_key)); - TEST_MEMORY_EQUAL(r->key, expected_key, sizeof(expected_key)); + if (memcmp(r->key, expected_key, sizeof(expected_key))) { + return kSecurityAccessDenied; + } else { + return kPositiveResponse; + } break; } default: @@ -25,21 +30,84 @@ uint8_t fn(UDSServer_t *srv, UDSServerEvent_t ev, const void *arg) { return kPositiveResponse; } -int main() { - UDSTpHandle_t *mock_client = ENV_TpNew("client"); - // UDSTpHandle_t *mock_client = ENV_TpNew("client"); - UDSServer_t srv; +int setup(void **state) { + mock_client = ENV_TpNew("client"); ENV_SERVER_INIT(srv); srv.fn = fn; + return 0; +} +int teardown(void **state) { + ENV_TpFree(mock_client); + ENV_TpFree(srv.tp); + return 0; +} + +void TestSAInit(void **state) { // the server security level after initialization should be 0 TEST_INT_EQUAL(srv.securityLevel, 0); +} + + +void TestSABruteForcePrevention1(void **state) { + // sending a seed request should get this response + const uint8_t SEED_REQUEST[] = {0x27, 0x01}; + const uint8_t NEG_RESPONSE[] = {0x7F, 0x27, 0x37}; + UDSTpSend(mock_client, SEED_REQUEST, sizeof(SEED_REQUEST), NULL); + EXPECT_IN_APPROX_MS(UDSTpGetRecvLen(mock_client) != 0, srv.p2_ms); + TEST_MEMORY_EQUAL(UDSTpGetRecvBuf(mock_client, NULL), NEG_RESPONSE, sizeof(NEG_RESPONSE)); + UDSTpAckRecv(mock_client); + + // the server security level should still be 0 + TEST_INT_EQUAL(srv.securityLevel, 0); +} + +void TestSABruteForcePrevention2(void **state) { + // the server security level after initialization should be 0 + TEST_INT_EQUAL(srv.securityLevel, 0); + + // Wait for the anti-brute-force timeout to expire + ENV_RunMillis(1000); // sending a seed request should get this response const uint8_t SEED_REQUEST[] = {0x27, 0x01}; const uint8_t SEED_RESPONSE[] = {0x67, 0x01, 0x36, 0x57}; UDSTpSend(mock_client, SEED_REQUEST, sizeof(SEED_REQUEST), NULL); + EXPECT_WITHIN_MS(UDSTpGetRecvLen(mock_client) != 0, UDS_SERVER_DEFAULT_P2_MS); + TEST_MEMORY_EQUAL(UDSTpGetRecvBuf(mock_client, NULL), SEED_RESPONSE, sizeof(SEED_RESPONSE)); + UDSTpAckRecv(mock_client); + + // the server security level should still be 0 + TEST_INT_EQUAL(srv.securityLevel, 0); + + // subsequently sending an unlock request should get this response + const uint8_t BAD_UNLOCK_REQUEST[] = {0x27, 0x02, 0xFF, 0xFF}; + const uint8_t UNLOCK_FAIL[] = {0x7F, 0x27, 0x33}; + UDSTpSend(mock_client, BAD_UNLOCK_REQUEST, sizeof(BAD_UNLOCK_REQUEST), NULL); EXPECT_IN_APPROX_MS(UDSTpGetRecvLen(mock_client) != 0, srv.p2_ms); + TEST_MEMORY_EQUAL(UDSTpGetRecvBuf(mock_client, NULL), UNLOCK_FAIL, sizeof(UNLOCK_FAIL)); + UDSTpAckRecv(mock_client); + + // the server security level should still be 0 + TEST_INT_EQUAL(srv.securityLevel, 0); + + // sending another seed request should get denied + const uint8_t DENIED[] = {0x7F, 0x27, 0x36}; + UDSTpSend(mock_client, SEED_REQUEST, sizeof(SEED_REQUEST), NULL); + EXPECT_WITHIN_MS(UDSTpGetRecvLen(mock_client) != 0, UDS_SERVER_DEFAULT_P2_MS); + TEST_MEMORY_EQUAL(UDSTpGetRecvBuf(mock_client, NULL), DENIED, sizeof(DENIED)); + UDSTpAckRecv(mock_client); +} + +void TestSAUnlock(void **state) { + // Wait for the anti-brute-force timeout to expire + ENV_RunMillis(1000); + + // sending a seed request should get this response + const uint8_t SEED_REQUEST[] = {0x27, 0x01}; + const uint8_t SEED_RESPONSE[] = {0x67, 0x01, 0x36, 0x57}; + UDSTpSend(mock_client, SEED_REQUEST, sizeof(SEED_REQUEST), NULL); + EXPECT_WITHIN_MS(UDSTpGetRecvLen(mock_client) != 0, UDS_SERVER_DEFAULT_P2_MS); TEST_MEMORY_EQUAL(UDSTpGetRecvBuf(mock_client, NULL), SEED_RESPONSE, sizeof(SEED_RESPONSE)); UDSTpAckRecv(mock_client); @@ -66,4 +134,17 @@ int main() { // Additionally, the security level should still be 1 TEST_INT_EQUAL(srv.securityLevel, 1); -} \ No newline at end of file +} + + +int main() { + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(TestSAInit, setup, teardown), + cmocka_unit_test_setup_teardown(TestSABruteForcePrevention1, setup, teardown), + cmocka_unit_test_setup_teardown(TestSABruteForcePrevention2, setup, teardown), + cmocka_unit_test_setup_teardown(TestSAUnlock, setup, teardown), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} + + diff --git a/test/test_tp_compliance.c b/test/test_tp_compliance.c index 090cef0..36bd85a 100644 --- a/test/test_tp_compliance.c +++ b/test/test_tp_compliance.c @@ -1,4 +1,3 @@ -#include "test/env.h" #include "test/test.h" UDSTpHandle_t *srv = NULL;