diff --git a/src/sa/internal/sa_interface_inmemory.template.c b/src/sa/internal/sa_interface_inmemory.template.c index 912de8b4..24c09720 100644 --- a/src/sa/internal/sa_interface_inmemory.template.c +++ b/src/sa/internal/sa_interface_inmemory.template.c @@ -1650,13 +1650,10 @@ static int32_t sa_delete(TC_t *tc_frame) **/ static int32_t sa_setARSN(TC_t *tc_frame) { - // Local variables uint16_t spi = 0x0000; uint16_t control_spi = 0x0000; - int32_t status = CRYPTO_LIB_SUCCESS; int x; - // Read ingest spi = ((uint8_t)sdls_frame.tlv_pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.tlv_pdu.data[1]; control_spi = tc_frame->tc_sec_header.spi; @@ -1665,44 +1662,44 @@ static int32_t sa_setARSN(TC_t *tc_frame) #ifdef DEBUG printf(KRED "ERROR: Cannot modify SA in use\n" RESET); #endif - status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; - return status; + return CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; } - // TODO: Check SA type (authenticated, encrypted, both) and set appropriately - // TODO: Add more checks on bounds - - // Check SPI exists - if (spi < NUM_SA) + if (spi >= NUM_SA) { - // Check if Auth or Auth Enc - if ((sa[spi].est == 1 && sa[spi].ast == 1) || sa[spi].ast == 1) - { // Set SN #ifdef PDU_DEBUG - printf("SPI %d ARSN updated to: 0x", spi); + printf("sa_setARSN ERROR: SPI %d is out of range.\n", spi); #endif - for (x = 0; x < sa[spi].arsn_len; x++) - { - *(sa[spi].arsn + x) = (uint8_t)sdls_frame.tlv_pdu.data[x + 2]; + return CRYPTO_LIB_ERR_SPI_INDEX_OOB; + } + if (sa[spi].sa_state == SA_NONE) + { #ifdef PDU_DEBUG - printf("%02x", *(sa[spi].arsn + x)); + printf("sa_setARSN ERROR: SPI %d has not been created.\n", spi); #endif - } + return CRYPTO_LIB_ERR_SA_NOT_OPERATIONAL; + } + if (sa[spi].ast != 1) + { #ifdef PDU_DEBUG - printf("\n"); + printf("Failed setARSN on SPI %d: SA does not provide authentication.\n", spi); #endif - } - else - { + return CRYPTO_LIB_ERR_INVALID_SA_SERVICE_TYPE; + } + #ifdef PDU_DEBUG - printf("Failed setARSN on SPI %d, ECS %d, ACS %d\n", spi, sa[spi].ecs, sa[spi].acs); + printf("SPI %d ARSN updated to: 0x", spi); #endif - } - } - else + for (x = 0; x < sa[spi].arsn_len; x++) { - printf("sa_setARSN ERROR: SPI %d does not exist.\n", spi); + *(sa[spi].arsn + x) = (uint8_t)sdls_frame.tlv_pdu.data[x + 2]; +#ifdef PDU_DEBUG + printf("%02x", *(sa[spi].arsn + x)); +#endif } +#ifdef PDU_DEBUG + printf("\n"); +#endif return CRYPTO_LIB_SUCCESS; } @@ -1713,12 +1710,9 @@ static int32_t sa_setARSN(TC_t *tc_frame) **/ static int32_t sa_setARSNW(TC_t *tc_frame) { - // Local variables uint16_t spi = 0x0000; uint16_t control_spi = 0x0000; - int32_t status = CRYPTO_LIB_SUCCESS; - // Read ingest spi = ((uint8_t)sdls_frame.tlv_pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.tlv_pdu.data[1]; #ifdef PDU_DEBUG printf("spi = %d \n", spi); @@ -1730,31 +1724,41 @@ static int32_t sa_setARSNW(TC_t *tc_frame) #ifdef DEBUG printf(KRED "ERROR: Cannot modify SA in use\n" RESET); #endif - status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; - return status; + return CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; } - // Check SPI exists - if (spi < NUM_SA) + if (spi >= NUM_SA) { - // Check for out of bounds - if (sa[spi].arsnw_len > (ARSN_SIZE)) - { - sa[spi].arsnw_len = ARSN_SIZE; - } - - sa[spi].arsnw = (((uint8_t)sdls_frame.tlv_pdu.data[2])); #ifdef PDU_DEBUG - printf("ARSN set to: %d\n", sa[spi].arsnw); + printf("sa_setARSNW ERROR: SPI %d is out of range.\n", spi); #endif + return CRYPTO_LIB_ERR_SPI_INDEX_OOB; } - else + if (sa[spi].sa_state == SA_NONE) + { +#ifdef PDU_DEBUG + printf("sa_setARSNW ERROR: SPI %d has not been created.\n", spi); +#endif + return CRYPTO_LIB_ERR_SA_NOT_OPERATIONAL; + } + if (sa[spi].ast != 1) { #ifdef PDU_DEBUG - printf("sa_setARSNW ERROR: SPI %d does not exist.\n", spi); + printf("Failed setARSNW on SPI %d: SA does not provide authentication.\n", spi); #endif + return CRYPTO_LIB_ERR_INVALID_SA_SERVICE_TYPE; } + if (sa[spi].arsnw_len > ARSN_SIZE) + { + sa[spi].arsnw_len = ARSN_SIZE; + } + + sa[spi].arsnw = (uint8_t)sdls_frame.tlv_pdu.data[2]; +#ifdef PDU_DEBUG + printf("ARSN set to: %d\n", sa[spi].arsnw); +#endif + return CRYPTO_LIB_SUCCESS; } diff --git a/test/unit/ut_ep_sa_mgmt.c b/test/unit/ut_ep_sa_mgmt.c index f5bd830b..4e926ee6 100644 --- a/test/unit/ut_ep_sa_mgmt.c +++ b/test/unit/ut_ep_sa_mgmt.c @@ -4,6 +4,125 @@ #include "sa_interface.h" #include "utest.h" +static int32_t InitSaValidationTest(void) +{ + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL); + Crypto_Config_TC(CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_ANTI_REPLAY_FALSE, TC_IGNORE_SA_STATE_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); + TCGvcidManagedParameters_t TC_0_Managed_Parameters = {0, 0x0003, 0, TC_NO_FECF, TC_HAS_SEGMENT_HDRS, 41, 1}; + Crypto_Config_Add_TC_Gvcid_Managed_Parameters(TC_0_Managed_Parameters); + return Crypto_Init(); +} + +UTEST(EP_SA_MGMT, SET_ARSN_REJECTS_UNCREATED_SA) +{ + remove("sa_save_file.bin"); + ASSERT_EQ(CRYPTO_LIB_SUCCESS, InitSaValidationTest()); + + SaInterface sa_if = get_sa_interface_inmemory(); + SecurityAssociation_t *sa_ptr = NULL; + sa_if->sa_get_from_spi(63, &sa_ptr); + sa_ptr->sa_state = SA_NONE; + + TC_t tc_frame = {0}; + tc_frame.tc_sec_header.spi = 0; + sdls_frame.tlv_pdu.data[0] = 0; + sdls_frame.tlv_pdu.data[1] = 63; + + ASSERT_EQ(CRYPTO_LIB_ERR_SA_NOT_OPERATIONAL, sa_if->sa_setARSN(&tc_frame)); + ASSERT_EQ(CRYPTO_LIB_ERR_SA_NOT_OPERATIONAL, sa_if->sa_setARSNW(&tc_frame)); + Crypto_Shutdown(); +} + +UTEST(EP_SA_MGMT, SET_ARSN_REJECTS_OUT_OF_RANGE_SPI) +{ + remove("sa_save_file.bin"); + ASSERT_EQ(CRYPTO_LIB_SUCCESS, InitSaValidationTest()); + + SaInterface sa_if = get_sa_interface_inmemory(); + TC_t tc_frame = {0}; + tc_frame.tc_sec_header.spi = 0; + sdls_frame.tlv_pdu.data[0] = (NUM_SA >> BYTE_LEN) & 0xFF; + sdls_frame.tlv_pdu.data[1] = NUM_SA & 0xFF; + + ASSERT_EQ(CRYPTO_LIB_ERR_SPI_INDEX_OOB, sa_if->sa_setARSN(&tc_frame)); + ASSERT_EQ(CRYPTO_LIB_ERR_SPI_INDEX_OOB, sa_if->sa_setARSNW(&tc_frame)); + Crypto_Shutdown(); +} + +UTEST(EP_SA_MGMT, SET_ARSNW_REJECTS_NON_AUTHENTICATING_SA) +{ + remove("sa_save_file.bin"); + ASSERT_EQ(CRYPTO_LIB_SUCCESS, InitSaValidationTest()); + + SaInterface sa_if = get_sa_interface_inmemory(); + SecurityAssociation_t *sa_ptr = NULL; + sa_if->sa_get_from_spi(2, &sa_ptr); + sa_ptr->sa_state = SA_KEYED; + sa_ptr->est = 1; + sa_ptr->ast = 0; + uint16_t original_arsnw = sa_ptr->arsnw; + + TC_t tc_frame = {0}; + tc_frame.tc_sec_header.spi = 0; + sdls_frame.tlv_pdu.data[0] = 0; + sdls_frame.tlv_pdu.data[1] = 2; + sdls_frame.tlv_pdu.data[2] = 9; + + ASSERT_EQ(CRYPTO_LIB_ERR_INVALID_SA_SERVICE_TYPE, sa_if->sa_setARSNW(&tc_frame)); + ASSERT_EQ(original_arsnw, sa_ptr->arsnw); + Crypto_Shutdown(); +} + +UTEST(EP_SA_MGMT, SET_ARSN_ACCEPTS_AUTHENTICATING_SA) +{ + remove("sa_save_file.bin"); + ASSERT_EQ(CRYPTO_LIB_SUCCESS, InitSaValidationTest()); + + SaInterface sa_if = get_sa_interface_inmemory(); + SecurityAssociation_t *sa_ptr = NULL; + sa_if->sa_get_from_spi(7, &sa_ptr); + sa_ptr->sa_state = SA_KEYED; + sa_ptr->ast = 1; + sa_ptr->arsn_len = 2; + + TC_t tc_frame = {0}; + tc_frame.tc_sec_header.spi = 0; + sdls_frame.tlv_pdu.data[0] = 0; + sdls_frame.tlv_pdu.data[1] = 7; + sdls_frame.tlv_pdu.data[2] = 0xAA; + sdls_frame.tlv_pdu.data[3] = 0x55; + + ASSERT_EQ(CRYPTO_LIB_SUCCESS, sa_if->sa_setARSN(&tc_frame)); + ASSERT_EQ(0xAA, sa_ptr->arsn[0]); + ASSERT_EQ(0x55, sa_ptr->arsn[1]); + Crypto_Shutdown(); +} + +UTEST(EP_SA_MGMT, SET_ARSNW_ACCEPTS_AUTHENTICATING_SA) +{ + remove("sa_save_file.bin"); + ASSERT_EQ(CRYPTO_LIB_SUCCESS, InitSaValidationTest()); + + SaInterface sa_if = get_sa_interface_inmemory(); + SecurityAssociation_t *sa_ptr = NULL; + sa_if->sa_get_from_spi(3, &sa_ptr); + sa_ptr->sa_state = SA_KEYED; + sa_ptr->ast = 1; + + TC_t tc_frame = {0}; + tc_frame.tc_sec_header.spi = 0; + sdls_frame.tlv_pdu.data[0] = 0; + sdls_frame.tlv_pdu.data[1] = 3; + sdls_frame.tlv_pdu.data[2] = 9; + + ASSERT_EQ(CRYPTO_LIB_SUCCESS, sa_if->sa_setARSNW(&tc_frame)); + ASSERT_EQ(9, sa_ptr->arsnw); + Crypto_Shutdown(); +} + UTEST(EP_SA_MGMT, SA_6_REKEY_133) { remove("sa_save_file.bin"); @@ -335,7 +454,7 @@ UTEST(EP_SA_MGMT, SA_6_SET_ARSNW) hex_conversion(buffer_SET_h, (char **)&buffer_SET_b, &buffer_SET_len); status = Crypto_TC_ProcessSecurity(buffer_SET_b, &buffer_SET_len, &tc_nist_processed_frame); - ASSERT_EQ(CRYPTO_LIB_SUCCESS, status); + ASSERT_EQ(CRYPTO_LIB_ERR_INVALID_SA_SERVICE_TYPE, status); sa_if->sa_get_from_spi(6, &test_association); @@ -396,7 +515,7 @@ UTEST(EP_SA_MGMT, SA_6_SET_ARSN) hex_conversion(buffer_SET_h, (char **)&buffer_SET_b, &buffer_SET_len); status = Crypto_TC_ProcessSecurity(buffer_SET_b, &buffer_SET_len, &tc_nist_processed_frame); - ASSERT_EQ(CRYPTO_LIB_SUCCESS, status); + ASSERT_EQ(CRYPTO_LIB_ERR_INVALID_SA_SERVICE_TYPE, status); printf("SA %d ARSN: 0x", test_association->spi); for (int i = 0; i < test_association->arsn_len; i++)