Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/core/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,17 +1219,31 @@ int32_t Crypto_Process_Extended_Procedure_Pdu(TC_t *tc_sdls_processed_frame, uin
#endif
// No Packet HDR or PUS in these frames
// SDLS TLV PDU
sdls_frame.hdr.type = (tc_sdls_processed_frame->tc_pdu[0] & 0x80) >> 7;
sdls_frame.tlv_pdu.hdr.type = (tc_sdls_processed_frame->tc_pdu[0] & 0x80) >> 7;
sdls_frame.tlv_pdu.hdr.uf = (tc_sdls_processed_frame->tc_pdu[0] & 0x40) >> 6;
sdls_frame.tlv_pdu.hdr.sg = (tc_sdls_processed_frame->tc_pdu[0] & 0x30) >> 4;
sdls_frame.tlv_pdu.hdr.pid = (tc_sdls_processed_frame->tc_pdu[0] & 0x0F);
sdls_frame.tlv_pdu.hdr.pdu_len =
(tc_sdls_processed_frame->tc_pdu[1] << 8) | tc_sdls_processed_frame->tc_pdu[2];
for (int x = 3; x < (3 + tc_sdls_processed_frame->tc_header.fl); x++)

if (tc_sdls_processed_frame->tc_pdu_len < SDLS_TLV_HDR_SIZE)
{
return CRYPTO_LIB_ERR_BAD_TLV_LENGTH;
}

uint16_t max_tlv = tc_sdls_processed_frame->tc_pdu_len - SDLS_TLV_HDR_SIZE;
uint16_t declared_tlv_bytes =
(sdls_frame.tlv_pdu.hdr.pdu_len + (BYTE_LEN - 1)) / BYTE_LEN;
if ((declared_tlv_bytes > max_tlv) || (declared_tlv_bytes > TLV_DATA_SIZE))
{
return CRYPTO_LIB_ERR_BAD_TLV_LENGTH;
}

for (uint16_t x = 0; x < declared_tlv_bytes; 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.tlv_pdu.data[x - 3] = tc_sdls_processed_frame->tc_pdu[x];
sdls_frame.tlv_pdu.data[x] = tc_sdls_processed_frame->tc_pdu[x + SDLS_TLV_HDR_SIZE];
}

#ifdef CCSDS_DEBUG
Expand Down
26 changes: 18 additions & 8 deletions src/core/crypto_key_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,30 @@ int32_t Crypto_Key_OTAR(void)
int y;
int32_t status = CRYPTO_LIB_SUCCESS;

int pdu_keys = ((sdls_frame.tlv_pdu.hdr.pdu_len / BYTE_LEN) - SDLS_KEYID_LEN - SDLS_IV_LEN - MAC_SIZE) /
(SDLS_KEYID_LEN + SDLS_KEY_LEN);
const int pdu_len_bits = sdls_frame.tlv_pdu.hdr.pdu_len;
const int pdu_len_bytes = pdu_len_bits / BYTE_LEN;
const int fixed_len = SDLS_KEYID_LEN + SDLS_IV_LEN + MAC_SIZE;
const int key_block_len = SDLS_KEYID_LEN + SDLS_KEY_LEN;

if ((pdu_len_bits % BYTE_LEN != 0) || (pdu_len_bytes < fixed_len) || (pdu_len_bytes > TLV_DATA_SIZE) ||
((pdu_len_bytes - fixed_len) % key_block_len != 0))
{
return CRYPTO_LIB_ERR_OTAR_BAD_TLV_LENGTH;
}

int pdu_keys = (pdu_len_bytes - fixed_len) / key_block_len;
if (pdu_keys > SDLS_EKB_LEN)
{
return CRYPTO_LIB_ERR_OTAR_BAD_TLV_LENGTH;
}

int w;
crypto_key_t *ekp = NULL;

#ifdef DEBUG
int expected_pdu_len = SDLS_KEYID_LEN + SDLS_IV_LEN + ((SDLS_KEYID_LEN + SDLS_KEY_LEN) * pdu_keys) + MAC_SIZE;
int expected_pdu_len = fixed_len + (key_block_len * pdu_keys);
printf("Expected PDU Length: %d (%d keys)\n", expected_pdu_len, pdu_keys);
#endif
if ((sdls_frame.tlv_pdu.hdr.pdu_len / BYTE_LEN) <
SDLS_KEYID_LEN + SDLS_IV_LEN + ((SDLS_KEYID_LEN + SDLS_KEY_LEN) * pdu_keys) + MAC_SIZE)
{
return CRYPTO_LIB_ERR_OTAR_BAD_TLV_LENGTH;
}

// Master Key ID
packet.mkid = (sdls_frame.tlv_pdu.data[0] << BYTE_LEN) | (sdls_frame.tlv_pdu.data[1]);
Expand Down
47 changes: 40 additions & 7 deletions test/unit/ut_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,19 +269,52 @@ UTEST(CRYPTO_C, PDU_SWITCH)
/**
* @brief Unit Test: Crypto Extended Procedures PDU Test
**/
/**
* @brief Unit Test: No-packet EP reply type is parsed into the TLV header
**/
UTEST(CRYPTO_C, EXT_PROC_PDU_NO_PACKET_REPLY_TYPE)
{
TC_t tc_frame = {0};

tc_frame.tc_sec_header.spi = SPI_MIN;
tc_frame.tc_header.vcid = TC_SDLS_EP_VCID;
tc_frame.tc_pdu_len = SDLS_TLV_HDR_SIZE;
tc_frame.tc_pdu[0] = 0x80; // Procedure type = reply

sdls_frame.tlv_pdu.hdr.type = PDU_TYPE_COMMAND;

int32_t status = Crypto_Process_Extended_Procedure_Pdu(&tc_frame, NULL, 0);
ASSERT_EQ(CRYPTO_LIB_SUCCESS, status);
ASSERT_EQ(PDU_TYPE_REPLY, (uint8_t)sdls_frame.tlv_pdu.hdr.type);
}

UTEST(CRYPTO_C, EXT_PROC_PDU_REJECTS_OVERSIZED_DECLARED_TLV)
{
TC_t tc_frame = {0};

tc_frame.tc_sec_header.spi = SPI_MIN;
tc_frame.tc_header.vcid = TC_SDLS_EP_VCID;
tc_frame.tc_pdu_len = SDLS_TLV_HDR_SIZE + 4;
tc_frame.tc_pdu[0] = PID_OTAR;
tc_frame.tc_pdu[1] = 0;
tc_frame.tc_pdu[2] = 64; // Declares eight bytes, but only four are present.

int32_t status = Crypto_Process_Extended_Procedure_Pdu(&tc_frame, NULL, tc_frame.tc_pdu_len);
ASSERT_EQ(CRYPTO_LIB_ERR_BAD_TLV_LENGTH, status);
}

UTEST(CRYPTO_C, EXT_PROC_PDU)
{
remove("sa_save_file.bin");
uint8_t *ingest = NULL;
TC_t *tc_frame = NULL;
tc_frame = malloc(sizeof(uint8_t) * TC_SIZE);
int32_t status = CRYPTO_LIB_ERROR;
TC_t tc_frame = {0};
int32_t status = CRYPTO_LIB_ERROR;
crypto_config_tc.has_pus_hdr = TC_NO_PUS_HDR;
tc_frame->tc_header.vcid = TC_SDLS_EP_VCID;
tc_frame->tc_header.fl = 1;
tc_frame.tc_sec_header.spi = SPI_MIN;
tc_frame.tc_header.vcid = TC_SDLS_EP_VCID;
tc_frame.tc_pdu_len = SDLS_TLV_HDR_SIZE;

status = Crypto_Process_Extended_Procedure_Pdu(tc_frame, ingest, TC_SIZE);
free(tc_frame);
status = Crypto_Process_Extended_Procedure_Pdu(&tc_frame, ingest, TC_SIZE);
ASSERT_EQ(status, CRYPTO_LIB_SUCCESS);
}
#endif // CRYPTO_EPROC
Expand Down
6 changes: 6 additions & 0 deletions test/unit/ut_ep_key_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
#include "sa_interface.h"
#include "utest.h"

UTEST(EP_KEY_MGMT, OTAR_REJECTS_OVERSIZED_TLV)
{
sdls_frame.tlv_pdu.hdr.pdu_len = (TLV_DATA_SIZE + 1) * BYTE_LEN;
ASSERT_EQ(CRYPTO_LIB_ERR_OTAR_BAD_TLV_LENGTH, Crypto_Key_OTAR());
}

UTEST(EP_KEY_MGMT, OTAR_0_140_142)
{
remove("sa_save_file.bin");
Expand Down