diff --git a/include/sa_interface.h b/include/sa_interface.h index 25f8b604..073b4e81 100644 --- a/include/sa_interface.h +++ b/include/sa_interface.h @@ -37,15 +37,15 @@ typedef struct int32_t (*sa_get_operational_sa_from_gvcid)(uint8_t, uint16_t, uint16_t, uint8_t, SecurityAssociation_t **); int32_t (*sa_save_sa)(SecurityAssociation_t *); // Security Association Utility Functions - int32_t (*sa_stop)(void); + int32_t (*sa_stop)(TC_t *tc_frame); int32_t (*sa_start)(TC_t *tc_frame); - int32_t (*sa_expire)(void); - int32_t (*sa_rekey)(void); + int32_t (*sa_expire)(TC_t *tc_frame); + int32_t (*sa_rekey)(TC_t *tc_frame); int32_t (*sa_status)(uint8_t *); - int32_t (*sa_create)(void); - int32_t (*sa_setARSN)(void); - int32_t (*sa_setARSNW)(void); - int32_t (*sa_delete)(void); + int32_t (*sa_create)(TC_t *tc_frame); + int32_t (*sa_setARSN)(TC_t *tc_frame); + int32_t (*sa_setARSNW)(TC_t *tc_frame); + int32_t (*sa_delete)(TC_t *tc_frame); } SaInterfaceStruct, *SaInterface; diff --git a/src/core/crypto.c b/src/core/crypto.c index 9bdc2d0f..613c02fc 100644 --- a/src/core/crypto.c +++ b/src/core/crypto.c @@ -529,37 +529,37 @@ int32_t Crypto_SG_SA_MGMT(uint8_t *ingest, TC_t *tc_frame) #ifdef PDU_DEBUG printf(KGRN "SA Create\n" RESET); #endif - status = sa_if->sa_create(); + status = sa_if->sa_create(tc_frame); break; case PID_DELETE_SA: #ifdef PDU_DEBUG printf(KGRN "SA Delete\n" RESET); #endif - status = sa_if->sa_delete(); + status = sa_if->sa_delete(tc_frame); break; case PID_SET_ARSNW: #ifdef PDU_DEBUG printf(KGRN "SA setARSNW\n" RESET); #endif - status = sa_if->sa_setARSNW(); + status = sa_if->sa_setARSNW(tc_frame); break; case PID_REKEY_SA: #ifdef PDU_DEBUG printf(KGRN "SA Rekey\n" RESET); #endif - status = sa_if->sa_rekey(); + status = sa_if->sa_rekey(tc_frame); break; case PID_EXPIRE_SA: #ifdef PDU_DEBUG printf(KGRN "SA Expire\n" RESET); #endif - status = sa_if->sa_expire(); + status = sa_if->sa_expire(tc_frame); break; case PID_SET_ARSN: #ifdef PDU_DEBUG printf(KGRN "SA SetARSN\n" RESET); #endif - status = sa_if->sa_setARSN(); + status = sa_if->sa_setARSN(tc_frame); break; case PID_START_SA: #ifdef PDU_DEBUG @@ -571,7 +571,7 @@ int32_t Crypto_SG_SA_MGMT(uint8_t *ingest, TC_t *tc_frame) #ifdef PDU_DEBUG printf(KGRN "SA Stop\n" RESET); #endif - status = sa_if->sa_stop(); + status = sa_if->sa_stop(tc_frame); break; case PID_READ_ARSN: #ifdef PDU_DEBUG diff --git a/src/sa/internal/sa_interface_inmemory.template.c b/src/sa/internal/sa_interface_inmemory.template.c index 0d59f13c..9ff488b0 100644 --- a/src/sa/internal/sa_interface_inmemory.template.c +++ b/src/sa/internal/sa_interface_inmemory.template.c @@ -25,15 +25,15 @@ static int32_t sa_get_from_spi(uint16_t, SecurityAssociation_t **); static int32_t sa_get_operational_sa_from_gvcid(uint8_t, uint16_t, uint16_t, uint8_t, SecurityAssociation_t **); static int32_t sa_save_sa(SecurityAssociation_t *sa); // Security Association Utility Functions -static int32_t sa_stop(void); +static int32_t sa_stop(TC_t *tc_frame); static int32_t sa_start(TC_t *tc_frame); -static int32_t sa_expire(void); -static int32_t sa_rekey(void); +static int32_t sa_expire(TC_t *tc_frame); +static int32_t sa_rekey(TC_t *tc_frame); static int32_t sa_status(uint8_t *); -static int32_t sa_create(void); -static int32_t sa_setARSN(void); -static int32_t sa_setARSNW(void); -static int32_t sa_delete(void); +static int32_t sa_create(TC_t *tc_frame); +static int32_t sa_setARSN(TC_t *tc_frame); +static int32_t sa_setARSNW(TC_t *tc_frame); +static int32_t sa_delete(TC_t *tc_frame); /* ** Global Variables @@ -1072,12 +1072,16 @@ static int32_t sa_start(TC_t *tc_frame) } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d is not in the KEYED state.\n" RESET, spi); +#endif } } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d does not exist.\n" RESET, spi); +#endif } #ifdef DEBUG @@ -1091,15 +1095,31 @@ static int32_t sa_start(TC_t *tc_frame) * @brief Function: sa_stop * @return int32: Success/Failure **/ -static int32_t sa_stop(void) +static int32_t sa_stop(TC_t *tc_frame) { // Local variables - uint16_t spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; + uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; int x; // Read ingest - spi = ((uint8_t)sdls_frame.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; + spi = ((uint8_t)sdls_frame.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; + control_spi = tc_frame->tc_sec_header.spi; + +#ifdef DEBUG + printf("control_spi = %d \n", spi); printf("spi = %d \n", spi); +#endif + + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } // Check SPI exists and in 'Active' state if (spi < NUM_SA) @@ -1137,36 +1157,52 @@ static int32_t sa_stop(void) } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d is not in the OPERATIONAL state.\n" RESET, spi); +#endif } } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d does not exist.\n" RESET, spi); +#endif } #ifdef DEBUG printf("\t spi = %d \n", spi); #endif - return CRYPTO_LIB_SUCCESS; + return status; } /** * @brief Function: sa_rekey * @return int32: Success/Failure **/ -static int32_t sa_rekey(void) +static int32_t sa_rekey(TC_t *tc_frame) { // Local variables - uint16_t spi = 0x0000; - int count = 0; - int x = 0; + uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; + int count = 0; + int x = 0; // Read ingest spi = ((uint8_t)sdls_frame.pdu.data[count] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[count + 1]; count = count + 2; + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } + // Check SPI exists and in 'Unkeyed' state if (spi < NUM_SA) { @@ -1245,14 +1281,25 @@ static int32_t sa_rekey(void) * @brief Function: sa_expire * @return int32: Success/Failure **/ -static int32_t sa_expire(void) +static int32_t sa_expire(TC_t *tc_frame) { // Local variables - uint16_t spi = 0x0000; + uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; // Read ingest spi = ((uint8_t)sdls_frame.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; - printf("spi = %d \n", spi); + + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } // Check SPI exists and in 'Keyed' state if (spi < NUM_SA) @@ -1275,12 +1322,16 @@ static int32_t sa_expire(void) } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d is not in the KEYED state.\n" RESET, spi); +#endif } } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d does not exist.\n" RESET, spi); +#endif } return CRYPTO_LIB_SUCCESS; @@ -1290,11 +1341,13 @@ static int32_t sa_expire(void) * @brief Function: sa_create * @return int32: Success/Failure **/ -static int32_t sa_create(void) +static int32_t sa_create(TC_t *tc_frame) { // Local variables uint8_t count = 6; uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; int x; // Read sdls_frame.pdu.data @@ -1303,6 +1356,16 @@ static int32_t sa_create(void) printf("spi = %d \n", spi); #endif + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } + // Check if valid SPI if (spi < NUM_SA) { @@ -1377,10 +1440,12 @@ static int32_t sa_create(void) * @brief Function: sa_delete * @return int32: Success/Failure **/ -static int32_t sa_delete(void) +static int32_t sa_delete(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.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; @@ -1388,6 +1453,16 @@ static int32_t sa_delete(void) printf("spi = %d \n", spi); #endif + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } + // Check SPI exists and in 'Unkeyed' state if (spi < NUM_SA) { @@ -1411,12 +1486,16 @@ static int32_t sa_delete(void) } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d is not in the UNKEYED state.\n" RESET, spi); +#endif } } else { +#ifdef DEBUG printf(KRED "ERROR: SPI %d does not exist.\n" RESET, spi); +#endif } return CRYPTO_LIB_SUCCESS; @@ -1426,15 +1505,26 @@ static int32_t sa_delete(void) * @brief Function: sa_setASRN * @return int32: Success/Failure **/ -static int32_t sa_setARSN(void) +static int32_t sa_setARSN(TC_t *tc_frame) { // Local variables - uint16_t spi = 0x0000; + uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; int x; // Read ingest spi = ((uint8_t)sdls_frame.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; - printf("spi = %d \n", spi); + + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } // TODO: Check SA type (authenticated, encrypted, both) and set appropriately // TODO: Add more checks on bounds @@ -1485,10 +1575,12 @@ static int32_t sa_setARSN(void) * @brief Function: sa_setARSNW * @return int32: Success/Failure **/ -static int32_t sa_setARSNW(void) +static int32_t sa_setARSNW(TC_t *tc_frame) { // Local variables - uint16_t spi = 0x0000; + uint16_t spi = 0x0000; + uint16_t control_spi = 0x0000; + int32_t status = CRYPTO_LIB_SUCCESS; // Read ingest spi = ((uint8_t)sdls_frame.pdu.data[0] << BYTE_LEN) | (uint8_t)sdls_frame.pdu.data[1]; @@ -1496,6 +1588,16 @@ static int32_t sa_setARSNW(void) printf("spi = %d \n", spi); #endif + control_spi = tc_frame->tc_sec_header.spi; + if (spi == control_spi) + { +#ifdef DEBUG + printf(KRED "ERROR: Cannot modify SA in use\n" RESET); +#endif + status = CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI; + return status; + } + // Check SPI exists if (spi < NUM_SA) { diff --git a/support/scripts/build_ep.sh b/support/scripts/build_ep.sh old mode 100644 new mode 100755 diff --git a/support/scripts/update_env.sh b/support/scripts/update_env.sh old mode 100644 new mode 100755 diff --git a/test/unit/ut_crypto.c b/test/unit/ut_crypto.c index 87b72600..35ad07ee 100644 --- a/test/unit/ut_crypto.c +++ b/test/unit/ut_crypto.c @@ -152,27 +152,27 @@ UTEST(CRYPTO_C, PDU_SWITCH) sdls_frame.pdu.hdr.sg = SG_SA_MGMT; sdls_frame.pdu.hdr.pid = PID_CREATE_SA; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_DELETE_SA; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_SET_ARSNW; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_REKEY_SA; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_EXPIRE_SA; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_SET_ARSN; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_START_SA; status = Crypto_PDU(ingest, &tc_frame); @@ -180,7 +180,7 @@ UTEST(CRYPTO_C, PDU_SWITCH) sdls_frame.pdu.hdr.pid = PID_STOP_SA; status = Crypto_PDU(ingest, &tc_frame); - ASSERT_EQ(status, CRYPTO_LIB_SUCCESS); + ASSERT_EQ(status, CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI); sdls_frame.pdu.hdr.pid = PID_READ_ARSN; status = Crypto_PDU(ingest, &tc_frame); diff --git a/test/unit/ut_ep_sa_mgmt.c b/test/unit/ut_ep_sa_mgmt.c index 5497a077..4d009c4d 100644 --- a/test/unit/ut_ep_sa_mgmt.c +++ b/test/unit/ut_ep_sa_mgmt.c @@ -539,4 +539,61 @@ UTEST(EP_SA_MGMT, SA_EXPIRE_6) free(buffer_EXPIRE_b); } +UTEST(EP_SA_MGMT, SA_STOP_SELF) +{ + remove("sa_save_file.bin"); + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_TRUE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_FALSE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); + + GvcidManagedParameters_t TC_0_Managed_Parameters = { + 0, 0x0003, 0, TC_NO_FECF, AOS_FHEC_NA, AOS_IZ_NA, 0, TC_HAS_SEGMENT_HDRS, 1024, TC_OCF_NA, 1}; + Crypto_Config_Add_Gvcid_Managed_Parameters(TC_0_Managed_Parameters); + + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + + int status = CRYPTO_LIB_SUCCESS; + + // NOTE: Added Transfer Frame header to the plaintext + char *buffer_STOP_h = "2003001c00ff000000001880d0b6000a197f0b001e00020000938f21c4555555555555"; + + uint8_t *buffer_STOP_b = NULL; + int buffer_STOP_len = 0; + + // Setup Processed Frame For Decryption + TC_t tc_nist_processed_frame; + + // Expose/setup SAs for testing + SecurityAssociation_t *test_association; + + // Modify SA 0 + sa_if->sa_get_from_spi(0, &test_association); + test_association->shivf_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->iv_len = 12; + test_association->shsnf_len = 2; + test_association->arsnw = 5; + test_association->arsnw_len = 1; + test_association->arsn_len = 2; + test_association->gvcid_blk.scid = SCID & 0x3FF; + + // Modify SA 6 + sa_if->sa_get_from_spi(6, &test_association); + test_association->sa_state = SA_OPERATIONAL; + + // Convert frames that will be processed + hex_conversion(buffer_STOP_h, (char **)&buffer_STOP_b, &buffer_STOP_len); + + status = Crypto_TC_ProcessSecurity(buffer_STOP_b, &buffer_STOP_len, &tc_nist_processed_frame); + ASSERT_EQ(CRYPTO_LIB_ERR_SDLS_EP_WRONG_SPI, status); + + printf("\n"); + Crypto_Shutdown(); + + free(buffer_STOP_b); +} + UTEST_MAIN(); \ No newline at end of file