Skip to content

Commit 40f2dfc

Browse files
authored
Merge pull request #417 from nasa/208-aos-fhecf-support
208 aos fhecf support
2 parents 405955d + 21dc022 commit 40f2dfc

File tree

8 files changed

+180
-48
lines changed

8 files changed

+180
-48
lines changed

include/crypto.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
/*
6060
** User Prototypes
6161
*/
62+
uint8_t gf_mul(uint8_t a, uint8_t b);
6263

6364
// Crypto Library Configuration functions
6465
extern int32_t Crypto_Config_CryptoLib(uint8_t key_type, uint8_t mc_type, uint8_t sa_type, uint8_t cryptography_type,
@@ -240,6 +241,7 @@ void Crypto_Local_Config(void);
240241
void Crypto_Local_Init(void);
241242
int32_t Crypto_window(uint8_t *actual, uint8_t *expected, int length, int window);
242243
uint16_t Crypto_Calc_FECF(const uint8_t *ingest, int len_ingest);
244+
uint16_t Crypto_Calc_FHECF(uint8_t *data);
243245
void Crypto_Calc_CRC_Init_Table(void);
244246
uint16_t Crypto_Calc_CRC16(uint8_t *data, int size);
245247
int32_t Crypto_Check_Anti_Replay(SecurityAssociation_t *sa_ptr, uint8_t *arsn, uint8_t *iv);
@@ -317,6 +319,7 @@ extern TM_FrameSecurityHeader_t tm_frame_sec_hdr; // Used to reduce bit math dup
317319
// exterm AOS_t aos_frame
318320
extern AOS_FramePrimaryHeader_t aos_frame_pri_hdr;
319321
extern AOS_FrameSecurityHeader_t aos_frame_sec_hdr; // Used to reduce bit math duplication
322+
extern uint8_t parity[4]; // Used in FHECF calc
320323

321324
// Global configuration structs
322325
extern CryptoConfig_t crypto_config;
@@ -357,4 +360,17 @@ extern uint8_t badFECF;
357360
extern uint32_t crc32Table[CRC32TBL_SIZE];
358361
extern uint16_t crc16Table[CRC16TBL_SIZE];
359362

363+
// GF(2^4) field and logarithm tables
364+
static const uint8_t gf_exp[30] = {
365+
1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1,
366+
2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9
367+
};
368+
369+
static const uint8_t gf_log[GF_SIZE] = {
370+
0, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12
371+
};
372+
373+
// Generator polynomial coefficients for g(x) = x^4 + a^3x^3 + ax^2 + a^3x + 1
374+
static const uint8_t gen_poly[RS_PARITY + 1] = {1, 8, 2, 8, 1};
375+
360376
#endif // CRYPTO_H

include/crypto_config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
#define REF_SIZE 250
124124
#define OCF_SIZE 4
125125
#define MAC_SIZE 16 /* bytes */
126+
#define FHECF_SIZE 2
126127
#define FECF_SIZE 2
127128
#define TC_SEGMENT_HDR_SIZE 1
128129
#define ECS_SIZE 4 /* bytes */
@@ -231,6 +232,13 @@
231232
#define TM_CADU_SIZE TM_FRAME_DATA_SIZE
232233
#endif
233234

235+
// AOS Behavior Defines
236+
// FHECF Calculation
237+
#define RS_SYMS 10 // Total symbols in codeword
238+
#define RS_DATA 6 // Data symbols
239+
#define RS_PARITY 4 // Parity symbols
240+
#define GF_SIZE 16 // 2^4
241+
234242
// Logic Behavior Defines
235243
#define CRYPTO_FALSE 0
236244
#define CRYPTO_TRUE 1

include/crypto_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
#define CRYPTO_LIB_ERR_SHPLF_LEN_GREATER_THAN_MAX_PAD_SIZE (-69)
143143
#define CRYPTO_LIB_ERR_INVALID_SVC_TYPE_WITH_ARSN (-70)
144144
#define CRYPTO_LIB_ERR_ARSN_LT_SHSNF (-71)
145+
#define CRYPTO_LIB_ERR_INVALID_FHECF (-72)
145146

146147
#define CRYPTO_CORE_ERROR_CODES_MAX -71
147148

src/core/crypto.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ uint8_t badSPI = 0;
5959
uint8_t badIV = 0;
6060
uint8_t badMAC = 0;
6161
uint8_t badFECF = 0;
62+
// FHECF
63+
uint8_t parity[RS_PARITY];
6264
// CRC
6365
uint32_t crc32Table[CRC32TBL_SIZE];
6466
uint16_t crc16Table[CRC16TBL_SIZE];
@@ -402,6 +404,50 @@ uint16_t Crypto_Calc_CRC16(uint8_t *data, int size)
402404
return crc;
403405
}
404406

407+
uint8_t gf_mul(uint8_t a, uint8_t b)
408+
{
409+
if (a == 0 || b == 0)
410+
{
411+
return 0;
412+
}
413+
else
414+
{
415+
return gf_exp[(gf_log[a] + gf_log[b]) % (GF_SIZE - 1)];
416+
}
417+
}
418+
419+
// Frame Header Error Control Field
420+
// Reference: CCSDS 732.0-B-4 (AOS Space Data Link Protocol) Section 4.1.2.6
421+
uint16_t Crypto_Calc_FHECF(uint8_t *data)
422+
{
423+
uint8_t feedback = 0;
424+
uint16_t result = 0;
425+
int i = 0;
426+
int j = 0;
427+
428+
// RS encoding
429+
memset(parity, 0, RS_PARITY);
430+
for (i = 0; i < RS_DATA; i++)
431+
{
432+
feedback = data[i] ^ parity[0];
433+
memmove(&parity[0], &parity[1], RS_PARITY - 1);
434+
parity[RS_PARITY - 1] = 0;
435+
436+
for (j = 0; j < RS_PARITY; j++)
437+
{
438+
parity[j] ^= gf_mul(feedback, gen_poly[j + 1]);
439+
}
440+
}
441+
#ifdef AOS_DEBUG
442+
for (i = 0; i < RS_PARITY; i++)
443+
{
444+
printf("Parity[%d] = 0x%01x\n", i, parity[i]);
445+
}
446+
#endif
447+
result = (parity[0] << 12) | (parity[1] << 8) | (parity[2] << 4) | (parity[3] << 0);
448+
return result;
449+
}
450+
405451
/*
406452
** Procedures Specifications
407453
*/

src/core/crypto_aos.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,23 @@ int32_t Crypto_AOS_ApplySecurity(uint8_t *pTfBuffer)
189189
// Detect if optional 2 byte FHEC is present
190190
if (current_managed_parameters_struct.aos_has_fhec == AOS_HAS_FHEC)
191191
{
192-
idx += 2;
192+
uint16_t recieved_fhecf = (((pTfBuffer[idx] << 8) & 0xFF00) | (pTfBuffer[idx + 1] & 0x00FF));
193+
#ifdef AOS_DEBUG
194+
printf("Recieved FHECF: %04x\n", recieved_fhecf);
195+
printf(KYEL "Calculating FHECF...\n" RESET);
196+
#endif
197+
uint16_t calculated_fhecf = Crypto_Calc_FHECF(pTfBuffer);
198+
199+
if (recieved_fhecf != calculated_fhecf)
200+
{
201+
status = CRYPTO_LIB_ERR_INVALID_FHECF;
202+
mc_if->mc_log(status);
203+
return status;
204+
}
205+
206+
pTfBuffer[idx] = (calculated_fhecf >> 8) & 0x00FF ;
207+
pTfBuffer[idx+1] = (calculated_fhecf) & 0x00FF ;
208+
idx = 8;
193209
}
194210

195211
// Detect if optional variable length Insert Zone is present
@@ -327,6 +343,7 @@ int32_t Crypto_AOS_ApplySecurity(uint8_t *pTfBuffer)
327343
* ~~~Index currently at start of data field, AKA end of security header~~~
328344
**/
329345
data_loc = idx;
346+
printf("IDX: %d", idx);
330347
// Calculate size of data to be encrypted
331348
pdu_len = current_managed_parameters_struct.max_frame_size - idx - sa_ptr->stmacf_len;
332349
// Check other managed parameter flags, subtract their lengths from data field if present
@@ -911,6 +928,7 @@ int32_t Crypto_AOS_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8
911928
SecurityAssociation_t *sa_ptr = NULL;
912929
uint8_t sa_service_type = -1;
913930
uint8_t spi = -1;
931+
uint8_t aos_hdr_len = 6;
914932

915933
// Bit math to give concise access to values in the ingest
916934
aos_frame_pri_hdr.tfvn = ((uint8_t)p_ingest[0] & 0xC0) >> 6;
@@ -921,7 +939,7 @@ int32_t Crypto_AOS_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8
921939
printf(KYEL "\n----- Crypto_AOS_ProcessSecurity START -----\n" RESET);
922940
#endif
923941

924-
if (len_ingest < 6) // Frame length doesn't even have enough bytes for header -- error out.
942+
if (len_ingest < aos_hdr_len) // Frame length doesn't even have enough bytes for header -- error out.
925943
{
926944
status = CRYPTO_LIB_ERR_INPUT_FRAME_TOO_SHORT_FOR_AOS_STANDARD;
927945
mc_if->mc_log(status);
@@ -974,7 +992,24 @@ int32_t Crypto_AOS_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8
974992
byte_idx = 6;
975993
if (current_managed_parameters_struct.aos_has_fhec == AOS_HAS_FHEC)
976994
{
995+
uint16_t recieved_fhecf = (((p_ingest[aos_hdr_len] << 8) & 0xFF00) | (p_ingest[aos_hdr_len + 1] & 0x00FF));
996+
#ifdef AOS_DEBUG
997+
printf("Recieved FHECF: %04x\n", recieved_fhecf);
998+
printf(KYEL "Calculating FHECF...\n" RESET);
999+
#endif
1000+
uint16_t calculated_fhecf = Crypto_Calc_FHECF(p_ingest);
1001+
1002+
if (recieved_fhecf != calculated_fhecf)
1003+
{
1004+
status = CRYPTO_LIB_ERR_INVALID_FHECF;
1005+
mc_if->mc_log(status);
1006+
return status;
1007+
}
1008+
1009+
p_ingest[byte_idx] = (calculated_fhecf >> 8) & 0x00FF ;
1010+
p_ingest[byte_idx+1] = (calculated_fhecf) & 0x00FF ;
9771011
byte_idx = 8;
1012+
aos_hdr_len = byte_idx;
9781013
}
9791014

9801015
// Determine if Insert Zone exists, increment past it if so
@@ -1105,7 +1140,6 @@ int32_t Crypto_AOS_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8
11051140
#ifdef FECF_DEBUG
11061141
printf(KYEL "FECF CALC MATCHES! - GOOD\n" RESET);
11071142
#endif
1108-
;
11091143
}
11101144
}
11111145
}
@@ -1134,18 +1168,18 @@ int32_t Crypto_AOS_ProcessSecurity(uint8_t *p_ingest, uint16_t len_ingest, uint8
11341168
return status;
11351169
}
11361170

1137-
// Copy over AOS Primary Header (6 bytes)
1138-
memcpy(p_new_dec_frame, &p_ingest[0], 6);
1171+
// Copy over AOS Primary Header (6-8 bytes)
1172+
memcpy(p_new_dec_frame, &p_ingest[0], aos_hdr_len);
11391173

11401174
// Copy over insert zone data, if it exists
11411175
if (current_managed_parameters_struct.aos_has_iz == AOS_HAS_IZ)
11421176
{
1143-
memcpy(p_new_dec_frame + 6, &p_ingest[6], current_managed_parameters_struct.aos_iz_len);
1177+
memcpy(p_new_dec_frame + aos_hdr_len, &p_ingest[aos_hdr_len], current_managed_parameters_struct.aos_iz_len);
11441178
#ifdef AOS_DEBUG
11451179
printf("Copied over the following:\n\t");
11461180
for (int i = 0; i < current_managed_parameters_struct.aos_iz_len; i++)
11471181
{
1148-
printf("%02X", p_ingest[6 + i]);
1182+
printf("%02X", p_ingest[aos_hdr_len + i]);
11491183
}
11501184
printf("\n");
11511185
#endif

src/core/crypto_error.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ char *crypto_enum_errlist_core[] = {(char *)"CRYPTO_LIB_SUCCESS",
9292
(char *)"CRYPTO_LIB_ERR_STMACF_LEN_GREATER_THAN_MAX_MAC_SIZE",
9393
(char *)"CRYPTO_LIB_ERR_SHPLF_LEN_GREATER_THAN_MAX_PAD_SIZE",
9494
(char *)"CRYPTO_LIB_ERR_INVALID_SVC_TYPE_WITH_ARSN",
95-
(char *)"CRYPTO_LIB_ERR_ARSN_LT_SHSNF"};
95+
(char *)"CRYPTO_LIB_ERR_ARSN_LT_SHSNF",
96+
(char *)"CRYPTO_LIB_ERR_INVALID_FHECF"};
9697

9798
char *crypto_enum_errlist_config[] = {
9899
(char *)"CRYPTO_CONFIGURATION_NOT_COMPLETE",

0 commit comments

Comments
 (0)