diff --git a/CMakeLists.txt b/CMakeLists.txt index 2651840b..8eda60d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") OPTION(DEBUG "Debug" OFF) # Disabled by default IF(DEBUG) - ADD_DEFINITIONS(-DDEBUG) + ADD_DEFINITIONS(-DDEBUG -DOCF_DEBUG -DFECF_DEBUG -DSA_DEBUG -DPDU_DEBUG -DCCSDS_DEBUG -DTC_DEBUG -DMAC_DEBUG -DTM_DEBUG) add_compile_options(-ggdb) ENDIF(DEBUG) diff --git a/fsw/crypto_tests/data/tc5.1.dat b/fsw/crypto_tests/data/tc5.1.dat new file mode 100644 index 00000000..7526bfcf Binary files /dev/null and b/fsw/crypto_tests/data/tc5.1.dat differ diff --git a/fsw/crypto_tests/data/tc5.2.dat b/fsw/crypto_tests/data/tc5.2.dat new file mode 100644 index 00000000..cb4f0e79 Binary files /dev/null and b/fsw/crypto_tests/data/tc5.2.dat differ diff --git a/fsw/crypto_tests/data/tc5.3.dat b/fsw/crypto_tests/data/tc5.3.dat new file mode 100644 index 00000000..ed021679 Binary files /dev/null and b/fsw/crypto_tests/data/tc5.3.dat differ diff --git a/fsw/crypto_util/app/crypto_sequence.c b/fsw/crypto_util/app/crypto_sequence.c index be43b008..8c55c563 100644 --- a/fsw/crypto_util/app/crypto_sequence.c +++ b/fsw/crypto_util/app/crypto_sequence.c @@ -62,7 +62,9 @@ int main(int argc, char *argv[]) { } else if (strcmp(security_type,"aos_a")==0){ Crypto_AOS_ApplySecurity(buffer, &buffer_size_i); } else if (strcmp(security_type,"tc_p")==0){ - Crypto_TC_ProcessSecurity(buffer, &buffer_size_i); + TC_t* tc_sdls_processed_frame = malloc(sizeof(TC_t)); + Crypto_TC_ProcessSecurity(buffer, &buffer_size_i,tc_sdls_processed_frame); + free(tc_sdls_processed_frame); } else if (strcmp(security_type,"tm_p")==0){ Crypto_TM_ProcessSecurity(buffer, &buffer_size_i); } else if (strcmp(security_type,"aos_p")==0){ diff --git a/fsw/crypto_util/app/process_security.c b/fsw/crypto_util/app/process_security.c index 15d1cad7..37682c70 100644 --- a/fsw/crypto_util/app/process_security.c +++ b/fsw/crypto_util/app/process_security.c @@ -52,7 +52,9 @@ int main(int argc, char *argv[]) { //Call ProcessSecurity on buffer contents depending on type. if (strcmp(security_type,"tc")==0){ - Crypto_TC_ProcessSecurity(buffer, &buffer_size_i); + TC_t* tc_sdls_processed_frame = malloc(sizeof(TC_t)); + Crypto_TC_ProcessSecurity(buffer, &buffer_size_i,tc_sdls_processed_frame); + free(tc_sdls_processed_frame); } else if (strcmp(security_type,"tm")==0){ Crypto_TM_ProcessSecurity(buffer, &buffer_size_i); } else if (strcmp(security_type,"aos")==0){ diff --git a/fsw/public_inc/common_types_minimum.h b/fsw/public_inc/common_types_minimum.h index 23bb908d..7d0c28dc 100644 --- a/fsw/public_inc/common_types_minimum.h +++ b/fsw/public_inc/common_types_minimum.h @@ -42,8 +42,6 @@ #endif #include -#include -#include /* * NOTE - NOT DEFINING STRUCT_LOW_BIT_FIRST or STRUCT_HIGH_BIT_FIRST @@ -59,9 +57,6 @@ typedef uint32_t uint32; typedef uint64_t uint64; typedef intptr_t intptr; - typedef uintptr_t cpuaddr; - typedef size_t cpusize; - typedef ptrdiff_t cpudiff; #ifdef __cplusplus diff --git a/fsw/public_inc/crypto.h b/fsw/public_inc/crypto.h index b51d3611..4ac8a351 100644 --- a/fsw/public_inc/crypto.h +++ b/fsw/public_inc/crypto.h @@ -27,6 +27,8 @@ ivv-itc@lists.nasa.gov #include "cfe_minimum.h" #endif +#include "crypto_structs.h" + #define CRYPTO_LIB_MAJOR_VERSION 1 #define CRYPTO_LIB_MINOR_VERSION 2 #define CRYPTO_LIB_REVISION 0 @@ -39,7 +41,7 @@ ivv-itc@lists.nasa.gov extern int32 Crypto_Init(void); // Telecommand (TC) extern int32 Crypto_TC_ApplySecurity(char** ingest, int* len_ingest); -extern int32 Crypto_TC_ProcessSecurity(char* ingest, int* len_ingest); +extern int32 Crypto_TC_ProcessSecurity(char* ingest, int* len_ingest, TC_t* tc_sdls_processed_frame); // Telemetry (TM) extern int32 Crypto_TM_ApplySecurity(char* ingest, int* len_ingest); extern int32 Crypto_TM_ProcessSecurity(char* ingest, int* len_ingest); diff --git a/fsw/public_inc/crypto_config.h b/fsw/public_inc/crypto_config.h index cf305d04..caf8e124 100644 --- a/fsw/public_inc/crypto_config.h +++ b/fsw/public_inc/crypto_config.h @@ -20,14 +20,14 @@ ivv-itc@lists.nasa.gov // Build Defines //#define BUILD_STATIC -// Debug Defines +// Debug Defines -- Use CMAKE options //#define ARC_DEBUG //#define CCSDS_DEBUG //#define DEBUG //(CMAKE option, not hardcoded) //#define FECF_DEBUG //#define MAC_DEBUG - #define OCF_DEBUG - #define PDU_DEBUG + //#define OCF_DEBUG + //#define PDU_DEBUG //#define SA_DEBUG //#define TC_DEBUG //#define TM_DEBUG @@ -98,7 +98,8 @@ ivv-itc@lists.nasa.gov #define NUM_KEYS 256 #define DISABLED 0 #define ENABLED 1 - #define IV_SIZE 12 + #define IV_SIZE 12 /* TM IV size bytes */ + #define IV_SIZE_TC 4 /* TC IV size bytes */ #define OCF_SIZE 4 #define MAC_SIZE 16 /* bytes */ #define FECF_SIZE 2 @@ -155,10 +156,18 @@ ivv-itc@lists.nasa.gov // CCSDS PUS Defines #define TLV_DATA_SIZE 494 /* bytes */ + #define PUS_HDR 1 //(1=true,0=false) // TM Defines #define TM_FRAME_DATA_SIZE 1740 /* bytes */ #define TM_FILL_SIZE 1145 /* bytes */ #define TM_PAD_SIZE 2 /* bytes */ +// TC Behavior Defines + #define TC_PROCESS_SDLS_PDUS 1 //(1=true,0=false) + #define TC_SDLS_EP_VCID 4 //VCID which has SDLS PDUs (JPL uses VCIDs to determine TC type, there is no space packet layer with APIDs). Set to -1 if uses SP APIDs. + #define VCID_BITMASK 0b111111 //Some JPL missions do not use the entire CCSDS 6 bit field for VCID. + #define SEGMENTATION_HDR 1 //(1=true,0=false) + #define HAS_FECF 1 //(1=true,0=false) + #endif \ No newline at end of file diff --git a/fsw/public_inc/crypto_structs.h b/fsw/public_inc/crypto_structs.h index e5c3e5ab..45696575 100644 --- a/fsw/public_inc/crypto_structs.h +++ b/fsw/public_inc/crypto_structs.h @@ -18,7 +18,12 @@ ivv-itc@lists.nasa.gov #define _crypto_structs_h_ #include "crypto_config.h" -#include + +#ifdef NOS3 //NOS3/cFS build is ready +#include "common_types.h" +#else //Assume build outside of NOS3/cFS infrastructure +#include "common_types_minimum.h" +#endif /* ** Key Definitions @@ -266,6 +271,7 @@ typedef struct TC_FramePrimaryHeader_t tc_header; TC_FrameSecurityHeader_t tc_sec_header; uint8 tc_pdu[TC_FRAME_DATA_SIZE]; + uint16 tc_pdu_len; TC_FrameSecurityTrailer_t tc_sec_trailer; } TC_t; #define TC_SIZE (sizeof(TC_t)) diff --git a/fsw/public_inc/itc_common_types_minimum.h b/fsw/public_inc/itc_common_types_minimum.h new file mode 100644 index 00000000..10408298 --- /dev/null +++ b/fsw/public_inc/itc_common_types_minimum.h @@ -0,0 +1,41 @@ +/* + * Minimal port of https://github.com/nasa-itc/osal/blob/master/src/os/inc/common_types.h + * needed to build standalone crypto library. + * + * Copyright (c) 2019 United States Government as represented by + * the Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _itc_common_types_minimum_ +#define _itc_common_types_minimum_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef uintptr_t cpuaddr; +typedef size_t cpusize; +typedef ptrdiff_t cpudiff; + +#ifdef __cplusplus +} +#endif + + +#endif //itc_common_types_minimum_.h diff --git a/fsw/src/crypto.c b/fsw/src/crypto.c index a1070845..87ecb1a8 100644 --- a/fsw/src/crypto.c +++ b/fsw/src/crypto.c @@ -49,7 +49,7 @@ ivv-itc@lists.nasa.gov static int32 Crypto_SA_init(void); static int32 Crypto_SA_config(void); // Assisting Functions -static int32 Crypto_Get_tcPayloadLength(void); +static int32 Crypto_Get_tcPayloadLength(TC_t* tc_frame); static int32 Crypto_Get_tmLength(int len); static void Crypto_TM_updatePDU(char* ingest, int len_ingest); static void Crypto_TM_updateOCF(void); @@ -58,7 +58,7 @@ static int32 Crypto_increment(uint8* num, int length); static int32 Crypto_window(uint8 *actual, uint8 *expected, int length, int window); static int32 Crypto_compare_less_equal(uint8 *actual, uint8 *expected, int length); static uint8 Crypto_Prep_Reply(char*, uint8); -static int32 Crypto_FECF(int fecf, char* ingest, int len_ingest); +static int32 Crypto_FECF(int fecf, char* ingest, int len_ingest,TC_t* tc_frame); static uint16 Crypto_Calc_FECF(char* ingest, int len_ingest); static void Crypto_Calc_CRC_Init_Table(void); static uint16 Crypto_Calc_CRC16(char* data, int size); @@ -66,10 +66,10 @@ static uint16 Crypto_Calc_CRC16(char* data, int size); static int32 Crypto_Key_OTAR(void); static int32 Crypto_Key_update(uint8 state); static int32 Crypto_Key_inventory(char*); -static int32 Crypto_Key_verify(char*); +static int32 Crypto_Key_verify(char*,TC_t* tc_frame); // Security Association Functions static int32 Crypto_SA_stop(void); -static int32 Crypto_SA_start(void); +static int32 Crypto_SA_start(TC_t* tc_frame); static int32 Crypto_SA_expire(void); static int32 Crypto_SA_rekey(void); static int32 Crypto_SA_status(char*); @@ -95,7 +95,7 @@ static int32 Crypto_User_ModifyKey(void); static int32 Crypto_User_ModifyActiveTM(void); static int32 Crypto_User_ModifyVCID(void); // Determine Payload Data Unit -static int32 Crypto_PDU(char* ingest); +static int32 Crypto_PDU(char* ingest, TC_t* tc_frame); /* ** Global Variables @@ -105,7 +105,6 @@ static SecurityAssociation_t sa[NUM_SA]; static crypto_key_t ek_ring[NUM_KEYS]; //static crypto_key_t ak_ring[NUM_KEYS]; // Local Frames -static TC_t tc_frame; static CCSDS_t sdls_frame; static TM_t tm_frame; // OCF @@ -768,10 +767,18 @@ static void Crypto_Calc_CRC_Init_Table(void) /* ** Assisting Functions */ -static int32 Crypto_Get_tcPayloadLength(void) +static int32 Crypto_Get_tcPayloadLength(TC_t* tc_frame) // Returns the payload length of current tc_frame in BYTES! { - return (tc_frame.tc_header.fl - (5 + 2 + IV_SIZE ) - (MAC_SIZE + FECF_SIZE) ); + int seg_hdr = 0;if(SEGMENTATION_HDR){seg_hdr=1;} + int fecf = 0;if(HAS_FECF){fecf=FECF_SIZE;} + int spi = 2; + int iv_size = IV_SIZE_TC; if(PUS_HDR){iv_size=IV_SIZE - 1;} //For some reason, the interoperability tests with PUS header frames work with a 12 byte TC IV, so we'll use that for those. + int tf_hdr = 5; + + return (tc_frame->tc_header.fl - (tf_hdr + seg_hdr + spi + iv_size ) - (MAC_SIZE + FECF_SIZE) ); + //return (tc_frame->tc_header.fl - (5 + 2 + IV_SIZE ) - (MAC_SIZE + FECF_SIZE) ); + //TFHDR=5bytes, SegHdr=1byte,SPI=2bytes,SeqNum=4bytes,MAC=16bytes,FECF=2bytes -- should be 30 bytes max, above calculation seems incorrect. } static int32 Crypto_Get_tmLength(int len) @@ -1052,7 +1059,7 @@ static uint8 Crypto_Prep_Reply(char* ingest, uint8 appID) return count; } -static int32 Crypto_FECF(int fecf, char* ingest, int len_ingest) +static int32 Crypto_FECF(int fecf, char* ingest, int len_ingest,TC_t* tc_frame) // Calculate the Frame Error Control Field (FECF), also known as a cyclic redundancy check (CRC) { int32 result = OS_SUCCESS; @@ -1079,7 +1086,7 @@ static int32 Crypto_FECF(int fecf, char* ingest, int len_ingest) log.blk[log_count++].em_len = 4; } #ifdef FECF_DEBUG - OS_printf("\t Calculated = 0x%04x \n\t Received = 0x%04x \n", calc_fecf, tc_frame.tc_sec_trailer.fecf); + OS_printf("\t Calculated = 0x%04x \n\t Received = 0x%04x \n", calc_fecf, tc_frame->tc_sec_trailer.fecf); #endif result = OS_ERROR; } @@ -1445,7 +1452,7 @@ static int32 Crypto_Key_inventory(char* ingest) return count; } -static int32 Crypto_Key_verify(char* ingest) +static int32 Crypto_Key_verify(char* ingest,TC_t* tc_frame) { // Local variables SDLS_KEYV_CMD_t packet; @@ -1495,7 +1502,7 @@ static int32 Crypto_Key_verify(char* ingest) iv_loc = count; for (int y = 0; y < IV_SIZE; y++) { - ingest[count++] = tc_frame.tc_sec_header.iv[y]; + ingest[count++] = tc_frame->tc_sec_header.iv[y]; } ingest[count-1] = ingest[count-1] + x + 1; @@ -1571,7 +1578,7 @@ static int32 Crypto_Key_verify(char* ingest) /* ** Security Association Management Services */ -static int32 Crypto_SA_start(void) +static int32 Crypto_SA_start(TC_t* tc_frame) { // Local variables uint8 count = 0; @@ -1602,7 +1609,7 @@ static int32 Crypto_SA_start(void) gvcid.mapid = (sdls_frame.pdu.data[count + 3]); // TC - if (gvcid.vcid != tc_frame.tc_header.vcid) + if (gvcid.vcid != tc_frame->tc_header.vcid) { // Clear all GVCIDs for provided SPI if (gvcid.mapid == TYPE_TC) { @@ -2384,7 +2391,7 @@ static int32 Crypto_User_ModifyVCID(void) /* ** Procedures Specifications */ -static int32 Crypto_PDU(char* ingest) +static int32 Crypto_PDU(char* ingest,TC_t* tc_frame) { int32 status = OS_SUCCESS; @@ -2421,7 +2428,7 @@ static int32 Crypto_PDU(char* ingest) #ifdef PDU_DEBUG OS_printf(KGRN "Key Verify\n" RESET); #endif - status = Crypto_Key_verify(ingest); + status = Crypto_Key_verify(ingest,tc_frame); break; case PID_KEY_DESTRUCTION: #ifdef PDU_DEBUG @@ -2483,7 +2490,7 @@ static int32 Crypto_PDU(char* ingest) #ifdef PDU_DEBUG OS_printf(KGRN "SA Start\n" RESET); #endif - status = Crypto_SA_start(); + status = Crypto_SA_start(tc_frame); break; case PID_STOP_SA: #ifdef PDU_DEBUG @@ -2688,8 +2695,8 @@ int32 Crypto_TC_ApplySecurity(char** ingest, int* len_ingest) return status; } -int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) -// Loads the ingest frame into the global tc_frame while performing decrpytion +int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest,TC_t* tc_sdls_processed_frame) +// Loads the ingest frame into the global tc_frame while performing decryption { // Local Variables int32 status = OS_SUCCESS; @@ -2702,37 +2709,47 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) OS_printf(KYEL "\n----- Crypto_TC_ProcessSecurity START -----\n" RESET); #endif + int byte_idx = 0; // Primary Header - tc_frame.tc_header.tfvn = ((uint8)ingest[0] & 0xC0) >> 6; - tc_frame.tc_header.bypass = ((uint8)ingest[0] & 0x20) >> 5; - tc_frame.tc_header.cc = ((uint8)ingest[0] & 0x10) >> 4; - tc_frame.tc_header.spare = ((uint8)ingest[0] & 0x0C) >> 2; - tc_frame.tc_header.scid = ((uint8)ingest[0] & 0x03) << 8; - tc_frame.tc_header.scid = tc_frame.tc_header.scid | (uint8)ingest[1]; - tc_frame.tc_header.vcid = ((uint8)ingest[2] & 0xFC) >> 2; - tc_frame.tc_header.fl = ((uint8)ingest[2] & 0x03) << 8; - tc_frame.tc_header.fl = tc_frame.tc_header.fl | (uint8)ingest[3]; - tc_frame.tc_header.fsn = (uint8)ingest[4]; + tc_sdls_processed_frame->tc_header.tfvn = ((uint8)ingest[byte_idx] & 0xC0) >> 6; + tc_sdls_processed_frame->tc_header.bypass = ((uint8)ingest[byte_idx] & 0x20) >> 5; + tc_sdls_processed_frame->tc_header.cc = ((uint8)ingest[byte_idx] & 0x10) >> 4; + tc_sdls_processed_frame->tc_header.spare = ((uint8)ingest[byte_idx] & 0x0C) >> 2; + tc_sdls_processed_frame->tc_header.scid = ((uint8)ingest[byte_idx] & 0x03) << 8; + byte_idx++; + tc_sdls_processed_frame->tc_header.scid = tc_sdls_processed_frame->tc_header.scid | (uint8)ingest[byte_idx]; + byte_idx++; + tc_sdls_processed_frame->tc_header.vcid = (((uint8)ingest[byte_idx] & 0xFC) >> 2) & VCID_BITMASK; + tc_sdls_processed_frame->tc_header.fl = ((uint8)ingest[byte_idx] & 0x03) << 8; + byte_idx++; + tc_sdls_processed_frame->tc_header.fl = tc_sdls_processed_frame->tc_header.fl | (uint8)ingest[byte_idx]; + byte_idx++; + tc_sdls_processed_frame->tc_header.fsn = (uint8)ingest[byte_idx]; + byte_idx++; // Security Header - tc_frame.tc_sec_header.sh = (uint8)ingest[5]; - tc_frame.tc_sec_header.spi = ((uint8)ingest[6] << 8) | (uint8)ingest[7]; + if(SEGMENTATION_HDR){ + tc_sdls_processed_frame->tc_sec_header.sh = (uint8)ingest[byte_idx]; + byte_idx++; + } + tc_sdls_processed_frame->tc_sec_header.spi = ((uint8)ingest[byte_idx] << 8) | (uint8)ingest[byte_idx+1]; + byte_idx+=2; #ifdef TC_DEBUG - OS_printf("vcid = %d \n", tc_frame.tc_header.vcid ); - OS_printf("spi = %d \n", tc_frame.tc_sec_header.spi); + OS_printf("vcid = %d \n", tc_sdls_processed_frame->tc_header.vcid ); + OS_printf("spi = %d \n", tc_sdls_processed_frame->tc_sec_header.spi); #endif // Checks - if (((uint8)ingest[18] == 0x0B) && ((uint8)ingest[19] == 0x00) && (((uint8)ingest[20] & 0xF0) == 0x40)) + if (PUS_HDR && ((uint8)ingest[18] == 0x0B) && ((uint8)ingest[19] == 0x00) && (((uint8)ingest[20] & 0xF0) == 0x40)) { // User packet check only used for ESA Testing! } else { // Update last spi used - report.lspiu = tc_frame.tc_sec_header.spi; + report.lspiu = tc_sdls_processed_frame->tc_sec_header.spi; // Verify - if (tc_frame.tc_header.scid != (SCID & 0x3FF)) + if (tc_sdls_processed_frame->tc_header.scid != (SCID & 0x3FF)) { OS_printf(KRED "Error: SCID incorrect! \n" RESET); status = OS_ERROR; @@ -2751,6 +2768,8 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) break; } } + + if ((report.lspiu > NUM_SA) && (status == OS_SUCCESS)) { report.ispif = 1; @@ -2759,7 +2778,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) } if (status == OS_SUCCESS) { - if (sa[report.lspiu].gvcid_tc_blk[tc_frame.tc_header.vcid].mapid != TYPE_TC) + if (sa[report.lspiu].gvcid_tc_blk[tc_sdls_processed_frame->tc_header.vcid].mapid != TYPE_TC) { OS_printf(KRED "Error: SA invalid type! \n" RESET); status = OS_ERROR; @@ -2768,7 +2787,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) // TODO: I don't think this is needed. //if (status == OS_SUCCESS) //{ - // if (sa[report.lspiu].gvcid_tc_blk[tc_frame.tc_header.vcid].vcid != tc_frame.tc_header.vcid) + // if (sa[report.lspiu].gvcid_tc_blk[tc_sdls_processed_frame->tc_header.vcid].vcid != tc_sdls_processed_frame->tc_header.vcid) // { // OS_printf(KRED "Error: VCID not mapped to provided SPI! \n" RESET); // status = OS_ERROR; @@ -2802,8 +2821,8 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) } // Determine mode via SPI - if ((sa[tc_frame.tc_sec_header.spi].est == 1) && - (sa[tc_frame.tc_sec_header.spi].ast == 1)) + if ((sa[tc_sdls_processed_frame->tc_sec_header.spi].est == 1) && + (sa[tc_sdls_processed_frame->tc_sec_header.spi].ast == 1)) { // Authenticated Encryption #ifdef DEBUG OS_printf(KBLU "ENCRYPTED TC Received!\n" RESET); @@ -2811,23 +2830,24 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) #ifdef TC_DEBUG OS_printf("IV: \n"); #endif - for (x = 8; x < (8 + IV_SIZE); x++) + for (x = byte_idx; x < (byte_idx + IV_SIZE); x++) { - tc_frame.tc_sec_header.iv[x-8] = (uint8)ingest[x]; + tc_sdls_processed_frame->tc_sec_header.iv[x-byte_idx] = (uint8)ingest[x]; #ifdef TC_DEBUG - OS_printf("\t iv[%d] = 0x%02x\n", x-8, tc_frame.tc_sec_header.iv[x-8]); + OS_printf("\t iv[%d] = 0x%02x\n", x-byte_idx, tc_sdls_processed_frame->tc_sec_header.iv[x-byte_idx]); #endif } - report.snval = tc_frame.tc_sec_header.iv[IV_SIZE-1]; + byte_idx += IV_SIZE; + report.snval = tc_sdls_processed_frame->tc_sec_header.iv[IV_SIZE-1]; #ifdef DEBUG - OS_printf("\t tc_sec_header.iv[%d] = 0x%02x \n", IV_SIZE-1, tc_frame.tc_sec_header.iv[IV_SIZE-1]); - OS_printf("\t sa[%d].iv[%d] = 0x%02x \n", tc_frame.tc_sec_header.spi, IV_SIZE-1, sa[tc_frame.tc_sec_header.spi].iv[IV_SIZE-1]); + OS_printf("\t tc_sec_header.iv[%d] = 0x%02x \n", IV_SIZE-1, tc_sdls_processed_frame->tc_sec_header.iv[IV_SIZE-1]); + OS_printf("\t sa[%d].iv[%d] = 0x%02x \n", tc_sdls_processed_frame->tc_sec_header.spi, IV_SIZE-1, sa[tc_sdls_processed_frame->tc_sec_header.spi].iv[IV_SIZE-1]); #endif // Check IV is in ARCW - if ( Crypto_window(tc_frame.tc_sec_header.iv, sa[tc_frame.tc_sec_header.spi].iv, IV_SIZE, - sa[tc_frame.tc_sec_header.spi].arcw[sa[tc_frame.tc_sec_header.spi].arcw_len-1]) != OS_SUCCESS ) + if ( Crypto_window(tc_sdls_processed_frame->tc_sec_header.iv, sa[tc_sdls_processed_frame->tc_sec_header.spi].iv, IV_SIZE, + sa[tc_sdls_processed_frame->tc_sec_header.spi].arcw[sa[tc_sdls_processed_frame->tc_sec_header.spi].arcw_len-1]) != OS_SUCCESS ) { report.af = 1; report.bsnf = 1; @@ -2850,7 +2870,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) } else { - if ( Crypto_compare_less_equal(tc_frame.tc_sec_header.iv, sa[tc_frame.tc_sec_header.spi].iv, IV_SIZE) == OS_SUCCESS ) + if ( Crypto_compare_less_equal(tc_sdls_processed_frame->tc_sec_header.iv, sa[tc_sdls_processed_frame->tc_sec_header.spi].iv, IV_SIZE) == OS_SUCCESS ) { // Replay - IV value lower than expected report.af = 1; report.bsnf = 1; @@ -2875,7 +2895,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) { // Adjust expected IV to acceptable received value for (int i = 0; i < (IV_SIZE); i++) { - sa[tc_frame.tc_sec_header.spi].iv[i] = tc_frame.tc_sec_header.iv[i]; + sa[tc_sdls_processed_frame->tc_sec_header.spi].iv[i] = tc_sdls_processed_frame->tc_sec_header.iv[i]; } } } @@ -2886,11 +2906,13 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) return status; } - x = x + Crypto_Get_tcPayloadLength(); + tc_sdls_processed_frame->tc_pdu_len = Crypto_Get_tcPayloadLength(tc_sdls_processed_frame); + + x = x + tc_sdls_processed_frame->tc_pdu_len; #ifdef TC_DEBUG OS_printf("TC: \n"); - for (int temp = 0; temp < Crypto_Get_tcPayloadLength(); temp++) + for (int temp = 0; temp < tc_sdls_processed_frame->tc_pdu_len; temp++) { OS_printf("\t ingest[%d] = 0x%02x \n", temp, (uint8)ingest[temp+20]); } @@ -2902,19 +2924,19 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) #endif for (y = x; y < (x + MAC_SIZE); y++) { - tc_frame.tc_sec_trailer.mac[y-x] = (uint8)ingest[y]; + tc_sdls_processed_frame->tc_sec_trailer.mac[y-x] = (uint8)ingest[y]; #ifdef TC_DEBUG - OS_printf("\t mac[%d] = 0x%02x\n", y-x, tc_frame.tc_sec_trailer.mac[y-x]); + OS_printf("\t mac[%d] = 0x%02x\n", y-x, tc_sdls_processed_frame->tc_sec_trailer.mac[y-x]); #endif } x = x + MAC_SIZE; // FECF - tc_frame.tc_sec_trailer.fecf = ((uint8)ingest[x] << 8) | ((uint8)ingest[x+1]); - Crypto_FECF(tc_frame.tc_sec_trailer.fecf, ingest, (tc_frame.tc_header.fl - 2)); + tc_sdls_processed_frame->tc_sec_trailer.fecf = ((uint8)ingest[x] << 8) | ((uint8)ingest[x+1]); + Crypto_FECF(tc_sdls_processed_frame->tc_sec_trailer.fecf, ingest, (tc_sdls_processed_frame->tc_header.fl - 2),tc_sdls_processed_frame); // Initialize the key - //itc_gcm128_init(&sa[tc_frame.tc_sec_header.spi].gcm_ctx, (const unsigned char*) &ek_ring[sa[tc_frame.tc_sec_header.spi].ekid]); + //itc_gcm128_init(&sa[tc_sdls_processed_frame->tc_sec_header.spi].gcm_ctx, (const unsigned char*) &ek_ring[sa[tc_sdls_processed_frame->tc_sec_header.spi].ekid]); gcry_error = gcry_cipher_open( &(tmp_hd), @@ -2929,16 +2951,16 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) return status; } #ifdef DEBUG - OS_printf("Key ID = %d, 0x", sa[tc_frame.tc_sec_header.spi].ekid); + OS_printf("Key ID = %d, 0x", sa[tc_sdls_processed_frame->tc_sec_header.spi].ekid); for(int y = 0; y < KEY_SIZE; y++) { - OS_printf("%02x", ek_ring[sa[tc_frame.tc_sec_header.spi].ekid].value[y]); + OS_printf("%02x", ek_ring[sa[tc_sdls_processed_frame->tc_sec_header.spi].ekid].value[y]); } OS_printf("\n"); #endif gcry_error = gcry_cipher_setkey( tmp_hd, - &(ek_ring[sa[tc_frame.tc_sec_header.spi].ekid].value[0]), + &(ek_ring[sa[tc_sdls_processed_frame->tc_sec_header.spi].ekid].value[0]), KEY_SIZE ); if((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) @@ -2949,8 +2971,8 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) } gcry_error = gcry_cipher_setiv( tmp_hd, - &(sa[tc_frame.tc_sec_header.spi].iv[0]), - sa[tc_frame.tc_sec_header.spi].iv_len + &(sa[tc_sdls_processed_frame->tc_sec_header.spi].iv[0]), + sa[tc_sdls_processed_frame->tc_sec_header.spi].iv_len ); if((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { @@ -2962,9 +2984,9 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) OS_printf("AAD = 0x"); #endif // Prepare additional authenticated data (AAD) - for (y = 0; y < sa[tc_frame.tc_sec_header.spi].abm_len; y++) + for (y = 0; y < sa[tc_sdls_processed_frame->tc_sec_header.spi].abm_len; y++) { - ingest[y] = (uint8) ((uint8)ingest[y] & (uint8)sa[tc_frame.tc_sec_header.spi].abm[y]); + ingest[y] = (uint8) ((uint8)ingest[y] & (uint8)sa[tc_sdls_processed_frame->tc_sec_header.spi].abm[y]); #ifdef MAC_DEBUG OS_printf("%02x", (uint8) ingest[y]); #endif @@ -2975,10 +2997,10 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) gcry_error = gcry_cipher_decrypt( tmp_hd, - &(tc_frame.tc_pdu[0]), // plaintext output - Crypto_Get_tcPayloadLength(), // length of data + &(tc_sdls_processed_frame->tc_pdu[0]), // plaintext output + tc_sdls_processed_frame->tc_pdu_len, // length of data &(ingest[20]), // ciphertext input - Crypto_Get_tcPayloadLength() // in data length + tc_sdls_processed_frame->tc_pdu_len // in data length ); if((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { @@ -2988,7 +3010,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) } gcry_error = gcry_cipher_checktag( tmp_hd, - &(tc_frame.tc_sec_trailer.mac[0]), // tag input + &(tc_sdls_processed_frame->tc_sec_trailer.mac[0]), // tag input MAC_SIZE // tag size ); if((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) @@ -2998,13 +3020,13 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) OS_printf("Actual MAC = 0x"); for (int z = 0; z < MAC_SIZE; z++) { - OS_printf("%02x",tc_frame.tc_sec_trailer.mac[z]); + OS_printf("%02x",tc_sdls_processed_frame->tc_sec_trailer.mac[z]); } OS_printf("\n"); gcry_error = gcry_cipher_gettag( tmp_hd, - &(tc_frame.tc_sec_trailer.mac[0]), // tag output + &(tc_sdls_processed_frame->tc_sec_trailer.mac[0]), // tag output MAC_SIZE // tag size ); if((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) @@ -3015,7 +3037,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) OS_printf("Expected MAC = 0x"); for (int z = 0; z < MAC_SIZE; z++) { - OS_printf("%02x",tc_frame.tc_sec_trailer.mac[z]); + OS_printf("%02x",tc_sdls_processed_frame->tc_sec_trailer.mac[z]); } OS_printf("\n"); status = OS_ERROR; @@ -3029,7 +3051,7 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) // Increment the IV for next time #ifdef INCREMENT - Crypto_increment(sa[tc_frame.tc_sec_header.spi].iv, IV_SIZE); + Crypto_increment(sa[tc_sdls_processed_frame->tc_sec_header.spi].iv, IV_SIZE); #endif } else @@ -3038,17 +3060,17 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) OS_printf(KBLU "CLEAR TC Received!\n" RESET); #endif - for (y = 10; y <= (tc_frame.tc_header.fl - 2); y++) + for (y = 10; y <= (tc_sdls_processed_frame->tc_header.fl - 2); y++) //tfhdr+seghdr+sechdr=5+1+6=12 { - tc_frame.tc_pdu[y - 10] = (uint8)ingest[y]; + tc_sdls_processed_frame->tc_pdu[y - 10] = (uint8)ingest[y]; } // FECF - tc_frame.tc_sec_trailer.fecf = ((uint8)ingest[y] << 8) | ((uint8)ingest[y+1]); - Crypto_FECF((int) tc_frame.tc_sec_trailer.fecf, ingest, (tc_frame.tc_header.fl - 2)); + tc_sdls_processed_frame->tc_sec_trailer.fecf = ((uint8)ingest[y] << 8) | ((uint8)ingest[y+1]); + Crypto_FECF((int) tc_sdls_processed_frame->tc_sec_trailer.fecf, ingest, (tc_sdls_processed_frame->tc_header.fl - 2),tc_sdls_processed_frame); } #ifdef TC_DEBUG - Crypto_tcPrint(&tc_frame); + Crypto_tcPrint(tc_sdls_processed_frame); #endif // Zero ingest @@ -3056,64 +3078,108 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) { ingest[x] = 0; } - - if ((tc_frame.tc_pdu[0] == 0x18) && (tc_frame.tc_pdu[1] == 0x80)) - // Crypto Lib Application ID + + + if(!TC_PROCESS_SDLS_PDUS) //If we don't want to process frame data for SDLS PDUs, only reverse security & return content. { + // CCSDS Pass-through #ifdef DEBUG - OS_printf(KGRN "Received SDLS command: " RESET); + OS_printf(KGRN "CCSDS Pass-through \n" RESET); #endif - // CCSDS Header - sdls_frame.hdr.pvn = (tc_frame.tc_pdu[0] & 0xE0) >> 5; - sdls_frame.hdr.type = (tc_frame.tc_pdu[0] & 0x10) >> 4; - sdls_frame.hdr.shdr = (tc_frame.tc_pdu[0] & 0x08) >> 3; - sdls_frame.hdr.appID = ((tc_frame.tc_pdu[0] & 0x07) << 8) | tc_frame.tc_pdu[1]; - sdls_frame.hdr.seq = (tc_frame.tc_pdu[2] & 0xC0) >> 6; - sdls_frame.hdr.pktid = ((tc_frame.tc_pdu[2] & 0x3F) << 8) | tc_frame.tc_pdu[3]; - sdls_frame.hdr.pkt_length = (tc_frame.tc_pdu[4] << 8) | tc_frame.tc_pdu[5]; - - // CCSDS PUS - sdls_frame.pus.shf = (tc_frame.tc_pdu[6] & 0x80) >> 7; - sdls_frame.pus.pusv = (tc_frame.tc_pdu[6] & 0x70) >> 4; - sdls_frame.pus.ack = (tc_frame.tc_pdu[6] & 0x0F); - sdls_frame.pus.st = tc_frame.tc_pdu[7]; - sdls_frame.pus.sst = tc_frame.tc_pdu[8]; - sdls_frame.pus.sid = (tc_frame.tc_pdu[9] & 0xF0) >> 4; - sdls_frame.pus.spare = (tc_frame.tc_pdu[9] & 0x0F); - - // SDLS TLV PDU - sdls_frame.pdu.type = (tc_frame.tc_pdu[10] & 0x80) >> 7; - sdls_frame.pdu.uf = (tc_frame.tc_pdu[10] & 0x40) >> 6; - sdls_frame.pdu.sg = (tc_frame.tc_pdu[10] & 0x30) >> 4; - sdls_frame.pdu.pid = (tc_frame.tc_pdu[10] & 0x0F); - sdls_frame.pdu.pdu_len = (tc_frame.tc_pdu[11] << 8) | tc_frame.tc_pdu[12]; - for (x = 13; x < (13 + sdls_frame.hdr.pkt_length); x++) - { - sdls_frame.pdu.data[x-13] = tc_frame.tc_pdu[x]; + if (PUS_HDR) { + for (x = 0; x < (tc_sdls_processed_frame->tc_header.fl - 11); x++) { + ingest[x] = tc_sdls_processed_frame->tc_pdu[x]; + #ifdef CCSDS_DEBUG + OS_printf("tc_sdls_processed_frame->tc_pdu[%d] = 0x%02x\n", x, tc_sdls_processed_frame->tc_pdu[x]); + #endif + *len_ingest = x; + } + } else { + for (x = 0; x < (tc_sdls_processed_frame->tc_header.fl); x++) { //with no PUS header, entire PDU is data + ingest[x] = tc_sdls_processed_frame->tc_pdu[x]; + #ifdef CCSDS_DEBUG + OS_printf("tc_sdls_processed_frame->tc_pdu[%d] = 0x%02x\n", x, tc_sdls_processed_frame->tc_pdu[x]); + #endif + *len_ingest = x; + } } - - #ifdef CCSDS_DEBUG - Crypto_ccsdsPrint(&sdls_frame); - #endif - - // Determine type of PDU - *len_ingest = Crypto_PDU(ingest); } - else - { // CCSDS Pass-through - #ifdef DEBUG - OS_printf(KGRN "CCSDS Pass-through \n" RESET); - #endif - // TODO: Remove PUS Header - for (x = 0; x < (tc_frame.tc_header.fl - 11); x++) + else //Process SDLS PDU + { + if (PUS_HDR) + { + if ((tc_sdls_processed_frame->tc_pdu[0] == 0x18) && (tc_sdls_processed_frame->tc_pdu[1] == 0x80)) + // Crypto Lib Application ID + { + #ifdef DEBUG + OS_printf(KGRN "Received SDLS command: " RESET); + #endif + // CCSDS Header + sdls_frame.hdr.pvn = (tc_sdls_processed_frame->tc_pdu[0] & 0xE0) >> 5; + sdls_frame.hdr.type = (tc_sdls_processed_frame->tc_pdu[0] & 0x10) >> 4; + sdls_frame.hdr.shdr = (tc_sdls_processed_frame->tc_pdu[0] & 0x08) >> 3; + sdls_frame.hdr.appID = + ((tc_sdls_processed_frame->tc_pdu[0] & 0x07) << 8) | tc_sdls_processed_frame->tc_pdu[1]; + sdls_frame.hdr.seq = (tc_sdls_processed_frame->tc_pdu[2] & 0xC0) >> 6; + sdls_frame.hdr.pktid = + ((tc_sdls_processed_frame->tc_pdu[2] & 0x3F) << 8) | tc_sdls_processed_frame->tc_pdu[3]; + sdls_frame.hdr.pkt_length = (tc_sdls_processed_frame->tc_pdu[4] << 8) | tc_sdls_processed_frame->tc_pdu[5]; + + // CCSDS PUS + sdls_frame.pus.shf = (tc_sdls_processed_frame->tc_pdu[6] & 0x80) >> 7; + sdls_frame.pus.pusv = (tc_sdls_processed_frame->tc_pdu[6] & 0x70) >> 4; + sdls_frame.pus.ack = (tc_sdls_processed_frame->tc_pdu[6] & 0x0F); + sdls_frame.pus.st = tc_sdls_processed_frame->tc_pdu[7]; + sdls_frame.pus.sst = tc_sdls_processed_frame->tc_pdu[8]; + sdls_frame.pus.sid = (tc_sdls_processed_frame->tc_pdu[9] & 0xF0) >> 4; + sdls_frame.pus.spare = (tc_sdls_processed_frame->tc_pdu[9] & 0x0F); + + // SDLS TLV PDU + sdls_frame.pdu.type = (tc_sdls_processed_frame->tc_pdu[10] & 0x80) >> 7; + sdls_frame.pdu.uf = (tc_sdls_processed_frame->tc_pdu[10] & 0x40) >> 6; + sdls_frame.pdu.sg = (tc_sdls_processed_frame->tc_pdu[10] & 0x30) >> 4; + sdls_frame.pdu.pid = (tc_sdls_processed_frame->tc_pdu[10] & 0x0F); + sdls_frame.pdu.pdu_len = (tc_sdls_processed_frame->tc_pdu[11] << 8) | tc_sdls_processed_frame->tc_pdu[12]; + for (x = 13; x < (13 + sdls_frame.hdr.pkt_length); x++) { + sdls_frame.pdu.data[x - 13] = tc_sdls_processed_frame->tc_pdu[x]; + } + + #ifdef CCSDS_DEBUG + Crypto_ccsdsPrint(&sdls_frame); + #endif + + // Determine type of PDU + *len_ingest = Crypto_PDU(ingest, tc_sdls_processed_frame); + } + } + else if (tc_sdls_processed_frame->tc_header.vcid == TC_SDLS_EP_VCID) //TC SDLS PDU with no packet layer { - ingest[x] = tc_frame.tc_pdu[x]; + #ifdef DEBUG + OS_printf(KGRN "Received SDLS command: " RESET); + #endif + // No Packet HDR or PUS in these frames + // SDLS TLV PDU + sdls_frame.pdu.type = (tc_sdls_processed_frame->tc_pdu[0] & 0x80) >> 7; + sdls_frame.pdu.uf = (tc_sdls_processed_frame->tc_pdu[0] & 0x40) >> 6; + sdls_frame.pdu.sg = (tc_sdls_processed_frame->tc_pdu[0] & 0x30) >> 4; + sdls_frame.pdu.pid = (tc_sdls_processed_frame->tc_pdu[0] & 0x0F); + sdls_frame.pdu.pdu_len = (tc_sdls_processed_frame->tc_pdu[1] << 8) | tc_sdls_processed_frame->tc_pdu[2]; + for (x = 3; x < (3 + tc_sdls_processed_frame->tc_header.fl); x++) { + //Todo - Consider how this behaves with large OTAR PDUs that are larger than 1 TC in size. Most likely fails. Must consider Uplink Sessions (sequence numbers). + sdls_frame.pdu.data[x - 3] = tc_sdls_processed_frame->tc_pdu[x]; + } + #ifdef CCSDS_DEBUG - OS_printf("tc_frame.tc_pdu[%d] = 0x%02x\n", x, tc_frame.tc_pdu[x]); + Crypto_ccsdsPrint(&sdls_frame); #endif + + // Determine type of PDU + *len_ingest = Crypto_PDU(ingest, tc_sdls_processed_frame); } - *len_ingest = x; - } + else { + //TODO - Process SDLS PDU with Packet Layer without PUS_HDR + } + }//End Process SDLS PDU #ifdef OCF_DEBUG Crypto_fsrPrint(&report); @@ -3126,7 +3192,6 @@ int32 Crypto_TC_ProcessSecurity( char* ingest, int* len_ingest) return status; } - int32 Crypto_TM_ApplySecurity( char* ingest, int* len_ingest) // Accepts CCSDS message in ingest, and packs into TM before encryption {