diff --git a/CMakeLists.txt b/CMakeLists.txt index bb60312f..777fc9c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,8 +29,11 @@ OPTION(ENCTEST "Encryption-Tests" OFF) # Disabled by default, enable with: -DENC OPTION(CODECOV "Code-Coverage" OFF) # Disabled by default, enable with: -DCODECOV=ON OPTION(SYSTEM_INSTALL "SystemInstall" OFF) #Disabled by default, enable with: -DSYSTEM_INSTALL=ON -set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") -set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install) +IF(NOT DEFINED CFE_SYSTEM_PSPNAME) + # Not cFE / cFS + set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") + set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install) +ENDIF() IF(CRYPTO_SUBMODULE_INSTALL) #If building CryptoLib as a submodule of another build system (EG, JPL KMC, Nasa NOS3, etc...) set(CMAKE_INSTALL_PREFIX ${CRYPTO_SUBMODULE_INSTALL}) @@ -66,12 +69,10 @@ include_directories(include) # The shared OSAL and cFE include directories should always be used # Note that this intentionally does NOT include PSP-specific includes, just the generic # Only include cFS/NOS3 directories if env var is defined -if(DEFINED ENV{CFECORE_SOURCE_DIR}) #if ${CFECORE_SOURCE_DIR} is set, expect cFS build infrastructure to be in place. +IF(DEFINED CFE_SYSTEM_PSPNAME) include_directories(${CFECORE_SOURCE_DIR}/src/inc) include_directories(${CFEPSP_SOURCE_DIR}/fsw/inc) ADD_DEFINITIONS(-DNOS3) -else() - #pass endif() if(NOT DEFINED ${PROJECT_BINARY_DIR}) @@ -84,4 +85,6 @@ if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR MYPROJECT_BUILD_TESTING) AND BUI add_subdirectory(test) endif() -add_subdirectory(util) +IF(NOT DEFINED CFE_SYSTEM_PSPNAME) + add_subdirectory(util) +ENDIF() diff --git a/include/crypto_config.h b/include/crypto_config.h index 2eb46c4f..8c6a8dd8 100644 --- a/include/crypto_config.h +++ b/include/crypto_config.h @@ -35,6 +35,7 @@ // Debug Colors #ifdef DEBUG +#define CRYPTO_DEBUG printf("%s:%s: %d", __FILE__, __FUNCTION__, __LINE__); #define KRED "\x1B[31m" #define KGRN "\x1B[32m" #define KYEL "\x1B[33m" @@ -43,6 +44,7 @@ #define KCYN "\x1B[36m" #define RESET "\033[0m" #else +#define CRYPTO_DEBUG #define KRED #define RED #define KGRN diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8b77fc4..f1044340 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,11 +48,13 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) endif() # Create the app module -if(DEFINED ENV{CFECORE_SOURCE_DIR}) #if ${CFECORE_SOURCE_DIR} is set, expect cFS build infrastructure to be in place. +IF(DEFINED CFE_SYSTEM_PSPNAME) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/cpu${TGTSYS_${SYSVAR}}/${INSTALL_SUBDIR}") add_cfe_app(Crypto ${LIB_SRC_FILES}) -else() #standalone build +ELSE() + # Standalone build add_library(Crypto SHARED ${LIB_SRC_FILES}) -endif() +ENDIF() if(LIBGCRYPT) target_link_libraries(Crypto gcrypt) @@ -79,9 +81,15 @@ add_custom_command(TARGET Crypto POST_BUILD COMMENT "Created ${PROJECT_BINARY_DIR}/lib/libCrypto.so" ) -install(TARGETS Crypto - DESTINATION ${CMAKE_INSTALL_PREFIX}/lib - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include) + +IF(DEFINED CFE_SYSTEM_PSPNAME) + install(TARGETS Crypto + DESTINATION ${CMAKE_INSTALL_PREFIX}/cpu${TGTSYS_${SYSVAR}}/${INSTALL_SUBDIR}) +ELSE() + install(TARGETS Crypto + DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include) +ENDIF() IF(MYSQL) file(GLOB MYSQL_SCRIPTS crypto_sadb/sadb_mariadb_sql/*.sql) diff --git a/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c b/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c index c5205b96..2c87b4ce 100644 --- a/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c +++ b/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c @@ -923,7 +923,7 @@ static int32_t cryptography_encrypt(uint8_t* data_out, size_t len_data_out, #ifdef TC_DEBUG size_t j; - printf("Input payload length is %ld\n", len_data_in); + printf("Input payload length is %ld\n", (long int) len_data_in); printf(KYEL "Printing Frame Data prior to encryption:\n\t"); for (j = 0; j < len_data_in; j++) { @@ -954,7 +954,7 @@ static int32_t cryptography_encrypt(uint8_t* data_out, size_t len_data_out, } #ifdef TC_DEBUG - printf("Output payload length is %ld\n", len_data_out); + printf("Output payload length is %ld\n", (long int) len_data_out); printf(KYEL "Printing TC Frame Data after encryption:\n\t"); for (j = 0; j < len_data_out; j++) { @@ -1056,7 +1056,7 @@ static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, #ifdef TC_DEBUG size_t j; - printf("Input payload length is %ld\n", len_data_in); + printf("Input payload length is %ld\n", (long int) len_data_in); printf(KYEL "Printing Frame Data prior to encryption:\n\t"); for (j = 0; j < len_data_in; j++) { @@ -1113,7 +1113,7 @@ static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, } #ifdef TC_DEBUG - printf("Output payload length is %ld\n", len_data_out); + printf("Output payload length is %ld\n", (long int) len_data_out); printf(KYEL "Printing TC Frame Data after encryption:\n\t"); for (j = 0; j < len_data_out; j++) { diff --git a/src/src_main/crypto_config.c b/src/src_main/crypto_config.c index 0eea91a3..54bc15f8 100644 --- a/src/src_main/crypto_config.c +++ b/src/src_main/crypto_config.c @@ -53,6 +53,7 @@ int32_t Crypto_Init_Unit_Test(void) TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS, 1024); Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS, 1024); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 4, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS, 1024); status = Crypto_Init(); return status; } diff --git a/src/src_main/sadb_routine_inmemory.template.c b/src/src_main/sadb_routine_inmemory.template.c index 59bc86cd..eb87688a 100644 --- a/src/src_main/sadb_routine_inmemory.template.c +++ b/src/src_main/sadb_routine_inmemory.template.c @@ -132,7 +132,7 @@ int32_t sadb_config(void) // SA 4 VC0/1 is now 4-VC0, 7-VC1 sa[4].spi = 4; sa[4].ekid = 130; - sa[4].sa_state = SA_KEYED; + sa[4].sa_state = SA_OPERATIONAL; sa[4].est = 1; sa[4].ast = 1; sa[4].ecs_len = 1; @@ -150,7 +150,7 @@ int32_t sadb_config(void) sa[4].arsn_len = 0; sa[4].gvcid_tc_blk.tfvn = 0; sa[4].gvcid_tc_blk.scid = SCID & 0x3FF; - sa[4].gvcid_tc_blk.vcid = 0; + sa[4].gvcid_tc_blk.vcid = 4; sa[4].gvcid_tc_blk.mapid = TYPE_TC; // SA 5 - KEYED; ARSNW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 131 diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index e757ffba..09f6bdb3 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -29,6 +29,8 @@ endif(${ENCTEST}) aux_source_directory(core UTIL_SRC_FILES) aux_source_directory(src_util APP_SRC_FILES) +find_package(Threads REQUIRED) + file( GLOB SOURCE_FILES src_util/*.c ) foreach(SOURCE_PATH ${SOURCE_FILES}) get_filename_component(EXECUTABLE_NAME ${SOURCE_PATH} NAME_WE) @@ -38,7 +40,7 @@ foreach(SOURCE_PATH ${SOURCE_FILES}) else() add_executable(${EXECUTABLE_NAME} ${SOURCE_PATH}) target_sources(${EXECUTABLE_NAME} PRIVATE core/shared_util.c) - target_link_libraries(${EXECUTABLE_NAME} LINK_PUBLIC Crypto) + target_link_libraries(${EXECUTABLE_NAME} LINK_PUBLIC Crypto pthread) endif() if(${ENCTEST} AND ${EXECUTABLE_NAME} STREQUAL et_dt_validation) diff --git a/util/include/standalone.h b/util/include/standalone.h new file mode 100644 index 00000000..9bc7924e --- /dev/null +++ b/util/include/standalone.h @@ -0,0 +1,109 @@ +/* Copyright (C) 2009 - 2022 National Aeronautics and Space Administration. + All Foreign Rights are Reserved to the U.S. Government. + + This software is provided "as is" without any warranty of any kind, either expressed, implied, or statutory, + including, but not limited to, any warranty that the software will conform to specifications, any implied warranties + of merchantability, fitness for a particular purpose, and freedom from infringement, and any warranty that the + documentation will conform to the program, or any warranty that the software will be error free. + + In no event shall NASA be liable for any damages, including, but not limited to direct, indirect, special or + consequential damages, arising out of, resulting from, or in any way connected with the software or its + documentation, whether or not based upon warranty, contract, tort or otherwise, and whether or not loss was sustained + from, or arose out of the results of, or use of, the software, documentation or services provided hereunder. + + ITC Team + NASA IV&V + jstar-development-team@mail.nasa.gov +*/ + +#ifndef CRYPTOLIB_STANDALONE_H +#define CRYPTOLIB_STANDALONE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* +** Includes +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "shared_util.h" + + +/* +** Configuration +*/ +#define TC_APPLY_PORT 6010 +#define TC_APPLY_FWD_PORT 8010 +#define TM_PROCESS_PORT 8011 +#define TM_PROCESS_FWD_PORT 6011 + +//#define CRYPTO_STANDALONE_TC_APPLY_DEBUG +//#define CRYPTO_STANDALONE_TM_PROCESS_DEBUG + +#define CRYPTO_STANDALONE_HANDLE_FRAMING +#define CRYPTO_STANDALONE_FRAMING_SCID 3 +#define CRYPTO_STANDALONE_FRAMING_VCID 0x00 +#define CRYPTO_STANDALONE_FRAMING_TC_DATA_LEN 256 + + +/* +** Defines +*/ +#define CRYPTO_PROMPT "cryptolib> " +#define CRYPTO_MAX_INPUT_BUF 512 +#define CRYPTO_MAX_INPUT_TOKENS 32 +#define CRYPTO_MAX_INPUT_TOKEN_SIZE 64 + +#define CRYPTO_CMD_UNKNOWN -1 +#define CRYPTO_CMD_HELP 0 +#define CRYPTO_CMD_EXIT 1 +#define CRYPTO_CMD_NOOP 2 +#define CRYPTO_CMD_RESET 3 +#define CRYPTO_CMD_VCID 4 + + +/* +** Structures +*/ +typedef struct +{ + int sockfd; + int port; +} udp_info_t; + + +/* +** Prototypes +*/ +int32_t crypto_standalone_check_number_arguments(int actual, int expected); +void crypto_standalone_to_lower(char* str); +void crypto_standalone_print_help(void); +int32_t crypto_standalone_get_command(const char* str); +int32_t crypto_standalone_process_command(int32_t cc, int32_t num_tokens, char* tokens); +int32_t crypto_standalone_udp_init(udp_info_t* sock, int32_t port); +int32_t crypto_reset(void); +void crypto_standalone_tc_frame(uint8_t* in_data, uint16_t in_length, uint8_t* out_data, uint16_t* out_length); +void* crypto_standalone_tc_apply(void* sock); +void crypto_standalone_tm_frame(uint8_t* in_data, uint16_t in_length, uint8_t* out_data, uint16_t* out_length); +void* crypto_standalone_tm_process(void* sock); +void crypto_standalone_cleanup(const int signal); + + +#ifdef __cplusplus +} /* Close scope of 'extern "C"' declaration which encloses file. */ +#endif + +#endif /* CRYPTOLIB_STANDALONE_H */ diff --git a/util/src_util/standalone.c b/util/src_util/standalone.c new file mode 100644 index 00000000..b04ed34c --- /dev/null +++ b/util/src_util/standalone.c @@ -0,0 +1,592 @@ +/* Copyright (C) 2009 - 2022 National Aeronautics and Space Administration. + All Foreign Rights are Reserved to the U.S. Government. + + This software is provided "as is" without any warranty of any kind, either expressed, implied, or statutory, + including, but not limited to, any warranty that the software will conform to specifications, any implied warranties + of merchantability, fitness for a particular purpose, and freedom from infringement, and any warranty that the + documentation will conform to the program, or any warranty that the software will be error free. + + In no event shall NASA be liable for any damages, including, but not limited to direct, indirect, special or + consequential damages, arising out of, resulting from, or in any way connected with the software or its + documentation, whether or not based upon warranty, contract, tort or otherwise, and whether or not loss was sustained + from, or arose out of the results of, or use of, the software, documentation or services provided hereunder. + + ITC Team + NASA IV&V + jstar-development-team@mail.nasa.gov +*/ + + +/******************************************************************************* +** Standalone CryptoLib Implementation +** UDP interfaces to apply / process each frame type and return the result. +*******************************************************************************/ + +#include "standalone.h" + +/* +** Global Variables +*/ +static volatile uint8_t keepRunning = CRYPTO_LIB_SUCCESS; +static volatile uint8_t tc_seq_num = 0; +static volatile uint8_t tc_vcid = CRYPTO_STANDALONE_FRAMING_VCID; + + +/* +** Functions +*/ +int32_t crypto_standalone_check_number_arguments(int actual, int expected) +{ + int32_t status = CRYPTO_LIB_SUCCESS; + if (actual != expected) + { + status = CRYPTO_LIB_ERROR; + printf("Invalid command format or number of arguments, type 'help' for more info\n"); + } + return status; +} + +void crypto_standalone_to_lower(char* str) +{ + char* ptr = str; + while(*ptr) + { + *ptr = tolower((unsigned char) *ptr); + ptr++; + } + return; +} + +void crypto_standalone_print_help(void) +{ + printf(CRYPTO_PROMPT "command [args]\n" + "----------------------------------------------------------------------\n" + "help - Display help \n" + "exit - Exit app \n" + "noop - No operation command to device \n" + "reset - Reset CryptoLib \n" + "vcid # - Change active TC virtual channel \n" + "\n" + ); +} + +int32_t crypto_standalone_get_command(const char* str) +{ + int32_t status = CRYPTO_CMD_UNKNOWN; + char lcmd[CRYPTO_MAX_INPUT_TOKEN_SIZE]; + + strncpy(lcmd, str, CRYPTO_MAX_INPUT_TOKEN_SIZE); + crypto_standalone_to_lower(lcmd); + + if(strcmp(lcmd, "help") == 0) + { + status = CRYPTO_CMD_HELP; + } + else if(strcmp(lcmd, "exit") == 0) + { + status = CRYPTO_CMD_EXIT; + } + else if(strcmp(lcmd, "noop") == 0) + { + status = CRYPTO_CMD_NOOP; + } + else if(strcmp(lcmd, "reset") == 0) + { + status = CRYPTO_CMD_RESET; + } + else if(strcmp(lcmd, "vcid") == 0) + { + status = CRYPTO_CMD_VCID; + } + return status; +} + +int32_t crypto_standalone_process_command(int32_t cc, int32_t num_tokens, char* tokens) +{ + int32_t status = CRYPTO_LIB_SUCCESS; + + /* Process command */ + switch(cc) + { + case CRYPTO_CMD_HELP: + crypto_standalone_print_help(); + break; + + case CRYPTO_CMD_EXIT: + keepRunning = CRYPTO_LIB_ERROR; + break; + + case CRYPTO_CMD_NOOP: + if (crypto_standalone_check_number_arguments(num_tokens, 0) == CRYPTO_LIB_SUCCESS) + { + printf("NOOP command success\n"); + } + break; + + case CRYPTO_CMD_RESET: + if (crypto_standalone_check_number_arguments(num_tokens, 0) == CRYPTO_LIB_SUCCESS) + { + status = crypto_reset(); + printf("Reset command received\n"); + } + break; + + case CRYPTO_CMD_VCID: + if (crypto_standalone_check_number_arguments(num_tokens, 1) == CRYPTO_LIB_SUCCESS) + { + tc_vcid = (uint8_t) atoi(&tokens[0]); + printf("Changed active virtual channel (VCID) to %d \n", tc_vcid); + } + break; + + default: + printf("Invalid command format, type 'help' for more info\n"); + status = CRYPTO_LIB_ERROR; + break; + } + + return status; +} + +int32_t crypto_standalone_udp_init(udp_info_t* sock, int32_t port) +{ + int status = CRYPTO_LIB_SUCCESS; + int optval; + socklen_t optlen; + + sock->port = port; + + /* Create */ + sock->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if(sock->sockfd == -1) + { + printf("udp_init: Socket create error port %d", sock->port); + } + + /* Bind */ + struct sockaddr_in saddr; + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); + saddr.sin_port = htons(sock->port); + status = bind(sock->sockfd, (struct sockaddr *) &saddr, sizeof(saddr)); + if (status != 0) + { + printf(" udp_init: Socker bind error with port %d", sock->port); + status = CRYPTO_LIB_ERROR; + } + + /* Keep Alive */ + optval = 1; + optlen = sizeof(optval); + setsockopt(sock->sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); + + return status; +} + +int32_t crypto_reset(void) +{ + int32_t status; + + status = Crypto_Shutdown(); + if(status != CRYPTO_LIB_SUCCESS) + { + printf("CryptoLib initialization failed with error %d \n", status); + } + + status = Crypto_Init_Unit_Test(); + // TODO: CryptoLib appears to be looking at the second byte and not specficially the SCID bits + if(status != CRYPTO_LIB_SUCCESS) + { + printf("CryptoLib initialization failed with error %d \n", status); + } + + return status; +} + +void crypto_standalone_tc_frame(uint8_t* in_data, uint16_t in_length, uint8_t* out_data, uint16_t* out_length) +{ + /* TC Length */ + *out_length = (uint16_t) CRYPTO_STANDALONE_FRAMING_TC_DATA_LEN + 6; + + /* TC Header */ + out_data[0] = 0x20; + out_data[1] = CRYPTO_STANDALONE_FRAMING_SCID; + out_data[2] = ((tc_vcid << 2) & 0xFC) | (((uint16_t) CRYPTO_STANDALONE_FRAMING_TC_DATA_LEN >> 8) & 0x03); + out_data[3] = (uint16_t) CRYPTO_STANDALONE_FRAMING_TC_DATA_LEN & 0x00FF; + out_data[4] = tc_seq_num++; + + /* Segement Header */ + out_data[5] = 0x00; + + /* SDLS Header */ + + /* TC Data */ + memcpy(&out_data[6], in_data, in_length); + + /* SDLS Trailer */ +} + +void* crypto_standalone_tc_apply(void* sock) +{ + int32_t status = CRYPTO_LIB_SUCCESS; + udp_info_t* tc_sock = (udp_info_t*) sock; + + uint8_t tc_apply_in[TC_MAX_FRAME_SIZE]; + uint16_t tc_in_len = 0; + uint8_t* tc_out_ptr; + uint16_t tc_out_len = 0; + + #ifdef CRYPTO_STANDALONE_HANDLE_FRAMING + uint8_t tc_framed[TC_MAX_FRAME_SIZE]; + #endif + + struct sockaddr_in rcv_addr; + struct sockaddr_in fwd_addr; + int sockaddr_size = sizeof(struct sockaddr_in); + + fwd_addr.sin_family = AF_INET; + fwd_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + fwd_addr.sin_port = htons(TC_APPLY_FWD_PORT); + + /* Prepare */ + memset(tc_apply_in, 0x00, sizeof(tc_apply_in)); + + while(keepRunning == CRYPTO_LIB_SUCCESS) + { + /* Receive */ + status = recvfrom(tc_sock->sockfd, tc_apply_in, sizeof(tc_apply_in), 0, (struct sockaddr*) &rcv_addr, (socklen_t*) &sockaddr_size); + if (status != -1) + { + tc_in_len = status; + #ifdef CRYPTO_STANDALONE_TC_APPLY_DEBUG + printf("crypto_standalone_tc_apply - received[%d]: 0x", tc_in_len); + for(int i = 0; i < status; i++) + { + printf("%02x", tc_apply_in[i]); + } + printf("\n"); + #endif + + /* Frame */ + #ifdef CRYPTO_STANDALONE_HANDLE_FRAMING + crypto_standalone_tc_frame(tc_apply_in, tc_in_len, tc_framed, &tc_out_len); + memcpy(tc_apply_in, tc_framed, tc_out_len); + tc_in_len = tc_out_len; + tc_out_len = 0; + #ifdef CRYPTO_STANDALONE_TC_APPLY_DEBUG + printf("crypto_standalone_tc_apply - framed[%d]: 0x", tc_in_len); + for(int i = 0; i < tc_in_len; i++) + { + printf("%02x", tc_apply_in[i]); + } + printf("\n"); + #endif + #endif + + /* Process */ + status = Crypto_TC_ApplySecurity(tc_apply_in, tc_in_len, &tc_out_ptr, &tc_out_len); + if (status == CRYPTO_LIB_SUCCESS) + { + #ifdef CRYPTO_STANDALONE_TC_APPLY_DEBUG + printf("crypto_standalone_tc_apply - status = %d, encrypted[%d]: 0x", status, tc_out_len); + for(int i = 0; i < tc_out_len; i++) + { + printf("%02x", tc_out_ptr[i]); + } + printf("\n"); + #endif + + /* Reply */ + status = sendto(tc_sock->sockfd, tc_out_ptr, tc_out_len, 0, (struct sockaddr*) &fwd_addr, sizeof(fwd_addr)); + if ((status == -1) || (status != tc_out_len)) + { + printf("crypto_standalone_tc_apply - Reply error %d \n", status); + } + } + else + { + printf("crypto_standalone_tc_apply - AppySecurity error %d \n", status); + } + + /* Reset */ + memset(tc_apply_in, 0x00, sizeof(tc_apply_in)); + tc_in_len = 0; + tc_out_len = 0; + free(tc_out_ptr); + #ifdef CRYPTO_STANDALONE_TC_APPLY_DEBUG + printf("\n"); + #endif + } + + /* Delay */ + usleep(100); + } + close(tc_sock->port); + return tc_sock; +} + +void crypto_standalone_tm_frame(uint8_t* in_data, uint16_t in_length, uint8_t* out_data, uint16_t* out_length) +{ + /* TM Length */ + *out_length = (uint16_t) in_length - 10; + + /* TM Header */ + memcpy(out_data, &in_data[10], in_length - 10); +} + +void* crypto_standalone_tm_process(void* sock) +{ + int32_t status = CRYPTO_LIB_SUCCESS; + udp_info_t* tm_sock = (udp_info_t*) sock; + + uint8_t tm_process_in[TM_FRAME_DATA_SIZE]; + int tm_process_len = 0; + uint16_t spp_len = 0; + uint8_t* tm_ptr; + + #ifdef CRYPTO_STANDALONE_HANDLE_FRAMING + uint8_t tm_framed[TM_FRAME_DATA_SIZE]; + uint16_t tm_framed_len = 0; + #endif + + struct sockaddr_in rcv_addr; + struct sockaddr_in fwd_addr; + int sockaddr_size = sizeof(struct sockaddr_in); + + fwd_addr.sin_family = AF_INET; + fwd_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + fwd_addr.sin_port = htons(TM_PROCESS_FWD_PORT); + + while(keepRunning == CRYPTO_LIB_SUCCESS) + { + /* Receive */ + status = recvfrom(tm_sock->sockfd, tm_process_in, sizeof(tm_process_in), 0, (struct sockaddr*) &rcv_addr, (socklen_t*) &sockaddr_size); + if (status != -1) + { + tm_process_len = status; + #ifdef CRYPTO_STANDALONE_TM_PROCESS_DEBUG + printf("crypto_standalone_tm_process - received[%d]: 0x", tm_process_len); + for(int i = 0; i < status; i++) + { + printf("%02x", tm_process_in[i]); + } + printf("\n"); + #endif + + /* Process */ + status = Crypto_TM_ProcessSecurity(tm_process_in, &tm_process_len); + if (status == CRYPTO_LIB_SUCCESS) + { + #ifdef CRYPTO_STANDALONE_TM_PROCESS_DEBUG + printf("crypto_standalone_tm_process - status = %d, decrypted[%d]: 0x", status, tm_process_len); + for(int i = 0; i < tm_process_len; i++) + { + printf("%02x", tm_process_in[i]); + } + printf("\n"); + #endif + + /* Frame */ + #ifdef CRYPTO_STANDALONE_HANDLE_FRAMING + crypto_standalone_tm_frame(tm_process_in, tm_process_len, tm_framed, &tm_framed_len); + memcpy(tm_process_in, tm_framed, tm_framed_len); + tm_process_len = tm_framed_len; + tm_framed_len = 0; + #ifdef CRYPTO_STANDALONE_TM_PROCESS_DEBUG + printf("crypto_standalone_tm_process - deframed[%d]: 0x", tm_process_len); + for(int i = 0; i < tm_process_len; i++) + { + printf("%02x", tm_process_in[i]); + } + printf("\n"); + #endif + #endif + + /* Space Packet Protocol Loop */ + tm_ptr = &tm_process_in[0]; + + while (tm_process_len > 5) + { + if ((tm_ptr[0] == 0x08) || (tm_ptr[0] == 0x09)) + { + spp_len = ((tm_ptr[4] << 8) | tm_ptr[5]) + 7; + #ifdef CRYPTO_STANDALONE_TM_PROCESS_DEBUG + printf("crypto_standalone_tm_process - SPP[%d]: 0x", spp_len); + for(int i = 0; i < spp_len; i++) + { + printf("%02x", tm_ptr[i]); + } + printf("\n"); + #endif + status = sendto(tm_sock->sockfd, tm_ptr, spp_len, 0, (struct sockaddr*) &fwd_addr, sizeof(fwd_addr)); + if ((status == -1) || (status != spp_len)) + { + printf("crypto_standalone_tm_process - Reply error %d \n", status); + } + tm_ptr = &tm_ptr[spp_len]; + tm_process_len = tm_process_len - spp_len; + } + else + { + if ( ((tm_ptr[0] != 0x03) && (tm_ptr[1] != 0xFF)) && ((tm_ptr[0] != 0xFF) && (tm_ptr[1] != 0x48)) ) + { + printf("crypto_standalone_tm_process - SPP loop error, expected idle packet or frame! \n"); + } + tm_process_len = 0; + } + } + } + else + { + printf("crypto_standalone_tm_process - ProcessSecurity error %d \n", status); + } + + /* Reset */ + memset(tm_process_in, 0x00, sizeof(tm_process_in)); + tm_process_len = 0; + #ifdef CRYPTO_STANDALONE_TM_PROCESS_DEBUG + printf("\n"); + #endif + } + + /* Delay */ + usleep(100); + } + close(tm_sock->port); + return tm_sock; +} + +void crypto_standalone_cleanup(const int signal) +{ + if (signal == SIGINT) + { + printf("\n"); + printf("Received CTRL+C, cleaning up... \n"); + } + /* Signal threads to stop */ + keepRunning = CRYPTO_LIB_ERROR; + exit(signal); + return; +} + +int main(int argc, char* argv[]) +{ + int32_t status = CRYPTO_LIB_SUCCESS; + + char input_buf[CRYPTO_MAX_INPUT_BUF]; + char input_tokens[CRYPTO_MAX_INPUT_TOKENS][CRYPTO_MAX_INPUT_TOKEN_SIZE]; + int num_input_tokens; + int cmd; + char* token_ptr; + + udp_info_t tc_apply; + udp_info_t tm_process; + pthread_t tc_apply_thread; + pthread_t tm_process_thread; + + printf("Starting CryptoLib in standalone mode! \n"); + printf(" TC Apply - UDP %d \n", TC_APPLY_PORT); + printf(" TM Process - UDP %d \n", TM_PROCESS_PORT); + printf("\n"); + if (argc != 1) + { + printf("Invalid number of arguments! \n"); + printf(" Expected zero but received: %s \n", argv[1]); + } + + /* Initialize CryptoLib */ + status = crypto_reset(); + if(status != CRYPTO_LIB_SUCCESS) + { + printf("CryptoLib initialization failed with error %d \n", status); + keepRunning = CRYPTO_LIB_ERROR; + } + + /* Initialize sockets */ + if (keepRunning == CRYPTO_LIB_SUCCESS) + { + status = crypto_standalone_udp_init(&tc_apply, TC_APPLY_PORT); + if (status != CRYPTO_LIB_SUCCESS) + { + printf("crypto_standalone_udp_init tc_apply failed with status %d \n", status); + keepRunning = CRYPTO_LIB_ERROR; + } + else + { + status = crypto_standalone_udp_init(&tm_process, TM_PROCESS_PORT); + if (status != CRYPTO_LIB_SUCCESS) + { + printf("crypto_standalone_udp_init tm_process failed with status %d \n", status); + keepRunning = CRYPTO_LIB_ERROR; + } + } + } + + /* Catch CTRL+C */ + signal(SIGINT, crypto_standalone_cleanup); + + /* Start threads */ + if (keepRunning == CRYPTO_LIB_SUCCESS) + { + status = pthread_create(&tc_apply_thread, NULL, *crypto_standalone_tc_apply, &tc_apply); + if (status < 0) + { + perror("Failed to create tc_apply_thread thread"); + keepRunning = CRYPTO_LIB_ERROR; + } + else + { + status = pthread_create(&tm_process_thread, NULL, *crypto_standalone_tm_process, &tm_process); + if (status < 0) + { + perror("Failed to create tm_process_thread thread"); + keepRunning = CRYPTO_LIB_ERROR; + } + } + } + + /* Main loop */ + while (keepRunning == CRYPTO_LIB_SUCCESS) + { + num_input_tokens = -1; + cmd = CRYPTO_CMD_UNKNOWN; + + /* Read user input */ + printf(CRYPTO_PROMPT); + fgets(input_buf, CRYPTO_MAX_INPUT_BUF, stdin); + + /* Tokenize line buffer */ + token_ptr = strtok(input_buf, " \t\n"); + while ((num_input_tokens < CRYPTO_MAX_INPUT_TOKENS) && (token_ptr != NULL)) + { + if (num_input_tokens == -1) + { + /* First token is command */ + cmd = crypto_standalone_get_command(token_ptr); + //printf("CMD = %s %d\n",token_ptr,cmd); + } + else + { + strncpy(input_tokens[num_input_tokens], token_ptr, CRYPTO_MAX_INPUT_TOKEN_SIZE); + //printf("Token[%d] = %s\n",num_input_tokens,token_ptr); + } + token_ptr = strtok(NULL, " \t\n"); + num_input_tokens++; + } + + /* Process command if valid */ + if(num_input_tokens >= 0) + { + crypto_standalone_process_command(cmd, num_input_tokens, &input_tokens[0][0]); + } + } + + /* Cleanup */ + close(tc_apply.port); + close(tm_process.port); + + Crypto_Shutdown(); + + printf("\n"); + exit(status); +} \ No newline at end of file diff --git a/util/src_util/ut_tc_apply.c b/util/src_util/ut_tc_apply.c index dc66c29d..a626d9fa 100644 --- a/util/src_util/ut_tc_apply.c +++ b/util/src_util/ut_tc_apply.c @@ -133,6 +133,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_ENC) sadb_routine->sadb_get_sa_from_spi(1, &test_association); test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); + test_association->gvcid_tc_blk.vcid = 0; test_association->sa_state = SA_OPERATIONAL; test_association->ast = 0; test_association->arsn_len = 0; @@ -206,6 +207,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_AUTH_ENC) sadb_routine->sadb_get_sa_from_spi(1, &test_association); test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); + test_association->gvcid_tc_blk.vcid = 0; test_association->sa_state = SA_OPERATIONAL; test_association->arsn_len = 0; @@ -253,6 +255,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_APPLY_NONTRANSMITTED_INCREMENTING_IV_ROLLOVE sadb_routine->sadb_get_sa_from_spi(1, &test_association); test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); + test_association->gvcid_tc_blk.vcid = 0; test_association->sa_state = SA_OPERATIONAL; test_association->shivf_len = 6; test_association->iv_len = 12; @@ -331,6 +334,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_APPLY_STATIC_IV_ROLLOVER) sadb_routine->sadb_get_sa_from_spi(1, &test_association); test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); + test_association->gvcid_tc_blk.vcid = 0; test_association->sa_state = SA_OPERATIONAL; test_association->shivf_len = 6; test_association->iv_len = 12; @@ -408,6 +412,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_APPLY_NONTRANSMITTED_INCREMENTING_ARSN_ROLLO sadb_routine->sadb_get_sa_from_spi(1, &test_association); test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); + test_association->gvcid_tc_blk.vcid = 0; test_association->sa_state = SA_OPERATIONAL; test_association->shivf_len = 0; test_association->iv_len = 0;