diff --git a/include/crypto_config_structs.h b/include/crypto_config_structs.h index f3212382..4242c54c 100644 --- a/include/crypto_config_structs.h +++ b/include/crypto_config_structs.h @@ -84,6 +84,21 @@ typedef enum TC_CHECK_FECF_TRUE } TcCheckFecfBool; +/* +** Used for selecting supported algorithms +*/ +typedef enum +{ + CRYPTO_ACS_NONE, + CRYPTO_AES256_CMAC, + CRYPTO_AES256_GMAC +} AuthCipherSuite; +typedef enum +{ + CRYPTO_ECS_NONE, + CRYPTO_AES256_GCM +} EncCipherSuite; + /* ** Main Crypto Configuration Block */ diff --git a/include/crypto_structs.h b/include/crypto_structs.h index 4693d9dc..59127023 100644 --- a/include/crypto_structs.h +++ b/include/crypto_structs.h @@ -68,8 +68,8 @@ typedef struct uint8_t shsnf_len : 6; // Sec. Header SN Field Length uint8_t shplf_len : 2; // Sec. Header PL Field Length uint8_t stmacf_len : 8; // Sec. Trailer MAC Field Length + uint8_t *ecs; // Encryption Cipher Suite (algorithm / mode ID) uint8_t ecs_len : 8; // Encryption Cipher Suite Length - uint8_t ecs[ECS_SIZE]; // Encryption Cipher Suite (algorithm / mode ID) uint8_t *iv; // Initialization Vector uint8_t acs_len : 8; // Authentication Cipher Suite Length uint8_t acs : 8; // Authentication Cipher Suite (algorithm / mode ID) diff --git a/include/cryptography_interface.h b/include/cryptography_interface.h index e4907f14..c42ffc13 100644 --- a/include/cryptography_interface.h +++ b/include/cryptography_interface.h @@ -36,8 +36,22 @@ typedef struct // Cryptography Interface Functions int32_t (*cryptography_encrypt)(void); int32_t (*cryptography_decrypt)(void); - int32_t (*cryptography_authenticate)(void); - int32_t (*cryptography_validate_authentication)(void); + int32_t (*cryptography_authenticate)(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, // For key index or key references (when key not passed in explicitly via key param) + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs); + int32_t (*cryptography_validate_authentication)(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs); int32_t (*cryptography_aead_encrypt)(uint8_t* data_out, size_t len_data_out, uint8_t* data_in, size_t len_data_in, uint8_t* key, uint32_t len_key, 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 6b816450..14ac534c 100644 --- a/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c +++ b/src/src_cryptography/src_libgcrypt/cryptography_interface_libgcrypt.template.c @@ -27,8 +27,22 @@ static int32_t cryptography_shutdown(void); // Cryptography Interface Functions static int32_t cryptography_encrypt(void); static int32_t cryptography_decrypt(void); -static int32_t cryptography_authenticate(void); -static int32_t cryptography_validate_authentication(void); +static int32_t cryptography_authenticate(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs); +static int32_t cryptography_validate_authentication(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs); static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, uint8_t* data_in, size_t len_data_in, uint8_t* key, uint32_t len_key, @@ -516,14 +530,201 @@ static int32_t cryptography_init(void) return status; } -static int32_t cryptography_shutdown(void) -{ - return CRYPTO_LIB_SUCCESS; -} +static int32_t cryptography_shutdown(void){ return CRYPTO_LIB_SUCCESS; } static int32_t cryptography_encrypt(void){ return CRYPTO_LIB_SUCCESS; } static int32_t cryptography_decrypt(void){ return CRYPTO_LIB_SUCCESS; } -static int32_t cryptography_authenticate(void){ return CRYPTO_LIB_SUCCESS; } -static int32_t cryptography_validate_authentication(void){ return CRYPTO_LIB_SUCCESS; } +static int32_t cryptography_authenticate(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, // For key index or key references (when key not passed in explicitly via key param) + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs) +{ + gcry_error_t gcry_error = GPG_ERR_NO_ERROR; + gcry_mac_hd_t tmp_mac_hd; + int32_t status = CRYPTO_LIB_SUCCESS; + uint8_t* key_ptr = key; + if(sa_ptr != NULL) //Using SA key pointer + { + key_ptr = &(ek_ring[sa_ptr->ekid].value[0]); + } + + // Need to copy the data over, since authentication won't change/move the data directly + if(data_out != NULL) + { + memcpy(data_out, data_in, len_data_in); + } + else + { + return CRYPTO_LIB_ERR_NULL_BUFFER; + } + + // Using to fix warning + len_data_out = len_data_out; + ecs = ecs; + acs = acs; + + gcry_error = gcry_mac_open(&(tmp_mac_hd), GCRY_MAC_CMAC_AES, GCRY_MAC_FLAG_SECURE, NULL); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_open error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_LIBGCRYPT_ERROR; + return status; + } + + gcry_error = gcry_mac_setkey(tmp_mac_hd, key_ptr, len_key); +#ifdef SA_DEBUG + printf(KYEL "Auth MAC Printing Key:\n\t"); + for (uint32_t i = 0; i < len_key; i++) + { + printf("%02X", *(key_ptr + i)); + } + printf("\n"); +#endif + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_setkey error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_LIBGCRYPT_ERROR; + gcry_mac_close(tmp_mac_hd); + return status; + } + + // If MAC needs IV, set it (only for certain ciphers) + if (iv_len > 0) + { + gcry_error = gcry_mac_setiv(tmp_mac_hd, iv, iv_len); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_setiv error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERROR; + return status; + } + } + + gcry_error = gcry_mac_write(tmp_mac_hd, + aad, // additional authenticated data + aad_len // length of AAD + ); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_write error code %d\n" RESET, + gcry_error & GPG_ERR_CODE_MASK); + printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error)); + status = CRYPTO_LIB_ERROR; + return status; + } + + gcry_error = gcry_mac_read(tmp_mac_hd, + mac, // tag output + (size_t *)&mac_size // tag size // TODO - use sa_ptr->abm_len instead of hardcoded mac size? + ); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_read error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_MAC_RETRIEVAL_ERROR; + return status; + } + + // Zeroise any sensitive information + gcry_mac_close(tmp_mac_hd); + return status; +} +static int32_t cryptography_validate_authentication(uint8_t* data_out, size_t len_data_out, + uint8_t* data_in, size_t len_data_in, + uint8_t* key, uint32_t len_key, + SecurityAssociation_t* sa_ptr, + uint8_t* iv, uint32_t iv_len, + uint8_t* mac, uint32_t mac_size, + uint8_t* aad, uint32_t aad_len, + uint8_t ecs, uint8_t acs) +{ + gcry_error_t gcry_error = GPG_ERR_NO_ERROR; + gcry_mac_hd_t tmp_mac_hd; + int32_t status = CRYPTO_LIB_SUCCESS; + uint8_t* key_ptr = key; + if(sa_ptr != NULL) //Using SA key pointer + { + key_ptr = &(ek_ring[sa_ptr->ekid].value[0]); + } + + // Need to copy the data over, since authentication won't change/move the data directly + if(data_out != NULL) + { + memcpy(data_out, data_in, len_data_in); + } + else + { + return CRYPTO_LIB_ERR_NULL_BUFFER; + } + // Using to fix warning + len_data_out = len_data_out; + ecs = ecs; + acs = acs; + + gcry_error = gcry_mac_open(&(tmp_mac_hd), GCRY_MAC_CMAC_AES, GCRY_MAC_FLAG_SECURE, NULL); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_open error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_LIBGCRYPT_ERROR; + return status; + } + + gcry_error = gcry_mac_setkey(tmp_mac_hd, key_ptr, len_key); +#ifdef SA_DEBUG + printf(KYEL "Validate MAC Printing Key:\n\t"); + for (uint32_t i = 0; i < len_key; i++) + { + printf("%02X", *(key_ptr + i)); + } + printf("\n"); +#endif + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_setkey error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_LIBGCRYPT_ERROR; + gcry_mac_close(tmp_mac_hd); + return status; + } + // If MAC needs IV, set it (only for certain ciphers) + if (iv_len > 0) + { + gcry_error = gcry_mac_setiv(tmp_mac_hd, iv, iv_len); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_setiv error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERROR; + return status; + } + } + gcry_error = gcry_mac_write(tmp_mac_hd, + aad, // additional authenticated data + aad_len // length of AAD + ); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_write error code %d\n" RESET, + gcry_error & GPG_ERR_CODE_MASK); + printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error)); + status = CRYPTO_LIB_ERROR; + return status; + } + // Compare computed mac with MAC in frame + gcry_error = gcry_mac_verify(tmp_mac_hd, + mac, // original mac + (size_t)mac_size // tag size + ); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_mac_read error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_MAC_RETRIEVAL_ERROR; + return status; + } + // Zeroise any sensitive information + gcry_mac_close(tmp_mac_hd); + return status; +} static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, uint8_t* data_in, size_t len_data_in, uint8_t* key, uint32_t len_key, @@ -544,7 +745,7 @@ static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, key_ptr = &(ek_ring[sa_ptr->ekid].value[0]); } - gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_CBC_MAC); + gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_NONE); if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_open error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); @@ -553,7 +754,7 @@ static int32_t cryptography_aead_encrypt(uint8_t* data_out, size_t len_data_out, } gcry_error = gcry_cipher_setkey(tmp_hd, key_ptr, len_key); #ifdef SA_DEBUG - printf(KYEL "Printing Key:\n\t"); + printf(KYEL "AEAD MAC: Printing Key:\n\t"); for (uint32_t i = 0; i < len_key; i++) { printf("%02X", *(key_ptr + i)); @@ -694,7 +895,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, key_ptr = &(ek_ring[sa_ptr->ekid].value[0]); } - gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_CBC_MAC); + gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_NONE); if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_open error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); @@ -737,11 +938,18 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, if (decrypt_bool == CRYPTO_TRUE) { gcry_error = gcry_cipher_decrypt(tmp_hd, - data_out, // plaintext output + data_out, // plaintext output len_data_out, // length of data - data_in, // in place decryption - len_data_in // in data length + data_in, // in place decryption + len_data_in // in data length ); + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_cipher_decrypt error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_DECRYPT_ERROR; + gcry_cipher_close(tmp_hd); + return status; + } } else // Authentication only { @@ -749,20 +957,20 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, gcry_error = gcry_cipher_decrypt(tmp_hd,NULL,0, NULL,0); // If authentication only, don't decrypt the data. Just pass the data PDU through. memcpy(data_out, data_in, len_data_in); - } - if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) - { - printf(KRED "ERROR: gcry_cipher_decrypt error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); - status = CRYPTO_LIB_ERR_DECRYPT_ERROR; - gcry_cipher_close(tmp_hd); - return status; + if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) + { + printf(KRED "ERROR: gcry_cipher_decrypt error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + status = CRYPTO_LIB_ERR_DECRYPT_ERROR; + gcry_cipher_close(tmp_hd); + return status; + } } if (authenticate_bool == CRYPTO_TRUE) { gcry_error = gcry_cipher_checktag(tmp_hd, - mac, // tag input - mac_size // tag size + mac, // tag input + mac_size // tag size ); if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { diff --git a/src/src_main/crypto.c b/src/src_main/crypto.c index 88705adb..e125a08d 100644 --- a/src/src_main/crypto.c +++ b/src/src_main/crypto.c @@ -68,9 +68,14 @@ uint8_t Crypto_Is_AEAD_Algorithm(uint32_t cipher_suite_id) // CryptoLib only supports AES-GCM, which is an AEAD (Authenticated Encryption with Associated Data) algorithm, so // return true/1. // TODO - Add cipher suite mapping to which algorithms are AEAD and which are not. - cipher_suite_id = cipher_suite_id; - - return CRYPTO_TRUE; + if(cipher_suite_id == CRYPTO_AES256_GCM) + { + return CRYPTO_TRUE; + } + else + { + return CRYPTO_FALSE; + } } // TODO - Review this. Not sure it quite works how we think diff --git a/src/src_main/crypto_print.c b/src/src_main/crypto_print.c index 296c21a9..12a33e12 100644 --- a/src/src_main/crypto_print.c +++ b/src/src_main/crypto_print.c @@ -196,10 +196,13 @@ void Crypto_saPrint(SecurityAssociation_t *sa) printf("\t shplf_len = 0x%01x \n", sa->shplf_len); printf("\t stmacf_len = 0x%02x \n", sa->stmacf_len); printf("\t ecs_len = 0x%02x \n", sa->ecs_len); - printf("\t ecs[%d] = 0x%02x \n", ECS_SIZE - 4, sa->ecs[ECS_SIZE - 4]); - printf("\t ecs[%d] = 0x%02x \n", ECS_SIZE - 3, sa->ecs[ECS_SIZE - 3]); - printf("\t ecs[%d] = 0x%02x \n", ECS_SIZE - 2, sa->ecs[ECS_SIZE - 2]); - printf("\t ecs[%d] = 0x%02x \n", ECS_SIZE - 1, sa->ecs[ECS_SIZE - 1]); + if (sa->ecs != NULL) + { + for (int i = 0; i < sa->ecs_len; i++) + { + printf("\t ecs[%d] = 0x%02x \n", i, *(sa->ecs + i)); + } + } printf("\t ekid = %d \n", sa->ekid); printf("\t iv_len = 0x%02x \n", sa->shivf_len); if (sa->iv != NULL) @@ -214,7 +217,7 @@ void Crypto_saPrint(SecurityAssociation_t *sa) printf("\t abm_len = 0x%04x \n", sa->abm_len); if (sa->abm != NULL) { - printf("\t abm: \n"); + printf("\t abm = "); for (int i = 0; i < sa->abm_len; i++) { printf("%02x", *(sa->abm + i)); @@ -224,7 +227,7 @@ void Crypto_saPrint(SecurityAssociation_t *sa) printf("\t arc_len = 0x%02x \n", sa->arc_len); if (sa->arc != NULL) { - printf("\t arc: \n"); + printf("\t arc = "); for (int i = 0; i < sa->arc_len; i++) { printf("%02x", *(sa->arc + i)); diff --git a/src/src_main/crypto_tc.c b/src/src_main/crypto_tc.c index 9b6f5618..67e64649 100644 --- a/src/src_main/crypto_tc.c +++ b/src/src_main/crypto_tc.c @@ -177,8 +177,15 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra // Determine Algorithm cipher & mode. // TODO - Parse authentication_cipher, and handle AEAD cases properly if (sa_service_type != SA_PLAINTEXT) { - encryption_cipher = - (sa_ptr->ecs[0] << 24) | (sa_ptr->ecs[1] << 16) | (sa_ptr->ecs[2] << 8) | sa_ptr->ecs[3]; + if (sa_ptr->ecs != NULL) + { + encryption_cipher = *sa_ptr->ecs; + } + // If no pointer, must not be using ECS at all + else + { + encryption_cipher = CRYPTO_ECS_NONE; + } ecs_is_aead_algorithm = Crypto_Is_AEAD_Algorithm(encryption_cipher); } @@ -213,8 +220,9 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra case SA_AUTHENTICATION: // Ingest length + spi_index (2) + shivf_len (varies) + shsnf_len (varies) // + shplf_len + arc_len + pad_size + stmacf_len + // TODO: If ARC is transmitted in the SHSNF field (as in CMAC... don't double count those bytes) *p_enc_frame_len = temp_tc_header.fl + 1 + 2 + sa_ptr->shivf_len + sa_ptr->shsnf_len + sa_ptr->shplf_len + - sa_ptr->arc_len + TC_PAD_SIZE + sa_ptr->stmacf_len; + TC_PAD_SIZE + sa_ptr->stmacf_len; new_enc_frame_header_field_length = (*p_enc_frame_len) - 1; break; case SA_ENCRYPTION: @@ -319,7 +327,6 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra for (int i = 0; i < sa_ptr->shivf_len; i++) { - // TODO: Likely API call // Copy in IV from SA *(p_new_enc_frame + index) = *(sa_ptr->iv + i); index++; @@ -333,18 +340,13 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra ** for an SA, the Sequence Number field shall be zero octets in length. ** Reference CCSDS 3550b1 */ - // Determine if seq num field is needed - // TODO: Likely SA API Call - if (sa_ptr->shsnf_len > 0) + // TODO: Workout ARC vs SN and when they may + // or may not be the same or different field + for (int i = 0; i < sa_ptr->shsnf_len; i++) { - // If using anti-replay counter, increment it - // TODO: Check return code - Crypto_increment(sa_ptr->arc, sa_ptr->shsnf_len); - for (int i = 0; i < sa_ptr->shsnf_len; i++) - { - *(p_new_enc_frame + index) = *(sa_ptr->arc + i); - index++; - } + // Copy in ARC from SA + *(p_new_enc_frame + index) = *(sa_ptr->arc + i); + index++; } // Set security header padding if specified @@ -411,7 +413,7 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra uint8_t* mac_ptr = NULL; uint16_t aad_len = 0; - if ((sa_service_type == SA_AUTHENTICATED_ENCRYPTION || sa_service_type == SA_AUTHENTICATION)) + if (sa_service_type == SA_AUTHENTICATED_ENCRYPTION || sa_service_type == SA_AUTHENTICATION) { mac_loc = TC_FRAME_HEADER_SIZE + segment_hdr_len + SPI_LEN + sa_ptr->shivf_len + sa_ptr->shsnf_len + sa_ptr->shplf_len + tf_payload_len; @@ -464,8 +466,30 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra } else // non aead algorithm { // TODO - implement non-AEAD algorithm logic - cryptography_if->cryptography_encrypt(); - cryptography_if->cryptography_authenticate(); + if (sa_service_type == SA_ENCRYPTION) + { + cryptography_if->cryptography_encrypt(); + } + + if (sa_service_type == SA_AUTHENTICATION) + { + cryptography_if->cryptography_authenticate(&p_new_enc_frame[index], // ciphertext output + (size_t)tf_payload_len, // length of data + (uint8_t*)(p_in_frame + TC_FRAME_HEADER_SIZE + segment_hdr_len), // plaintext input + (size_t)tf_payload_len, // in data length + NULL, // Using SA key reference, key is null + KEY_SIZE, // Length of key. TODO - why is this hard-coded? + sa_ptr, // SA (for key reference) + sa_ptr->iv, // IV + sa_ptr->shivf_len, // IV Length + mac_ptr, // tag output + MAC_SIZE, // tag size // TODO - why is this hard-coded?! + aad, // AAD Input + aad_len, // Length of AAD + *sa_ptr->ecs, // encryption cipher + sa_ptr->acs // authentication cipher + ); + } } } @@ -473,7 +497,8 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra if (sa_service_type != SA_PLAINTEXT) { #ifdef INCREMENT - Crypto_increment(sa_ptr->iv, sa_ptr->shivf_len); + if(sa_ptr->shivf_len > 0){ Crypto_increment(sa_ptr->iv, sa_ptr->shivf_len); } + if(sa_ptr->arc_len > 0){ Crypto_increment(sa_ptr->arc, sa_ptr->arc_len); } #ifdef SA_DEBUG printf(KYEL "Next IV value is:\n\t"); for (int i = 0; i < sa_ptr->shivf_len; i++) @@ -481,6 +506,12 @@ int32_t Crypto_TC_ApplySecurity(const uint8_t *p_in_frame, const uint16_t in_fra printf("%02x", *(sa_ptr->iv + i)); } printf("\n" RESET); + printf(KYEL "Next ARC value is:\n\t"); + for (int i = 0; i < sa_ptr->arc_len; i++) + { + printf("%02x", *(sa_ptr->arc + i)); + } + printf("\n" RESET); #endif #endif } @@ -608,8 +639,7 @@ int32_t Crypto_TC_ProcessSecurity(uint8_t *ingest, int *len_ingest, TC_t *tc_sdl { return status; } - - encryption_cipher = (sa_ptr->ecs[0] << 24) | (sa_ptr->ecs[1] << 16) | (sa_ptr->ecs[2] << 8) | sa_ptr->ecs[3]; + encryption_cipher = *sa_ptr->ecs; ecs_is_aead_algorithm = Crypto_Is_AEAD_Algorithm(encryption_cipher); // Determine SA Service Type @@ -641,7 +671,7 @@ int32_t Crypto_TC_ProcessSecurity(uint8_t *ingest, int *len_ingest, TC_t *tc_sdl // Determine Algorithm cipher & mode. // TODO - Parse authentication_cipher, and handle AEAD cases properly if (sa_service_type != SA_PLAINTEXT) { - encryption_cipher = (sa_ptr->ecs[0] << 24) | (sa_ptr->ecs[1] << 16) | (sa_ptr->ecs[2] << 8) | sa_ptr->ecs[3]; + encryption_cipher = *sa_ptr->ecs; ecs_is_aead_algorithm = Crypto_Is_AEAD_Algorithm(encryption_cipher); } @@ -785,8 +815,7 @@ int32_t Crypto_TC_ProcessSecurity(uint8_t *ingest, int *len_ingest, TC_t *tc_sdl printf(KYEL "TC PDU Calculated Length: %d \n", tc_sdls_processed_frame->tc_pdu_len); #endif - if((sa_service_type == SA_AUTHENTICATION || sa_service_type == SA_ENCRYPTION || sa_service_type == SA_AUTHENTICATED_ENCRYPTION) - && ecs_is_aead_algorithm == CRYPTO_TRUE) + if(sa_service_type != SA_PLAINTEXT && ecs_is_aead_algorithm == CRYPTO_TRUE) { status = cryptography_if->cryptography_aead_decrypt(tc_sdls_processed_frame->tc_pdu, // plaintext output (size_t)(tc_sdls_processed_frame->tc_pdu_len), // length of data @@ -801,15 +830,30 @@ int32_t Crypto_TC_ProcessSecurity(uint8_t *ingest, int *len_ingest, TC_t *tc_sdl sa_ptr->stmacf_len, // tag size aad, // additional authenticated data aad_len, // length of AAD - (sa_ptr->est==1), // Decryption Bool - (sa_ptr->ast==1), // Authentication Bool - (sa_ptr->ast==1) // AAD Bool + (sa_ptr->est), // Decryption Bool + (sa_ptr->ast), // Authentication Bool + (sa_ptr->ast) // AAD Bool ); - }else if (sa_service_type == SA_AUTHENTICATION || sa_service_type == SA_ENCRYPTION || sa_service_type == SA_AUTHENTICATED_ENCRYPTION) // Non aead algorithm + }else if (sa_service_type != SA_PLAINTEXT) // Non aead algorithm { // TODO - implement non-AEAD algorithm logic cryptography_if->cryptography_decrypt(); - cryptography_if->cryptography_validate_authentication(); + cryptography_if->cryptography_validate_authentication(tc_sdls_processed_frame->tc_pdu, // plaintext output + (size_t)(tc_sdls_processed_frame->tc_pdu_len), // length of data + &(ingest[tc_enc_payload_start_index]), // ciphertext input + (size_t)(tc_sdls_processed_frame->tc_pdu_len), // in data length + NULL, // Key + KEY_SIZE, // TODO - This shouldn't be hardcoded + sa_ptr, // SA for key reference + tc_sdls_processed_frame->tc_sec_header.iv, // IV + sa_ptr->shivf_len, // IV Length + tc_sdls_processed_frame->tc_sec_trailer.mac, // Frame Expected Tag + sa_ptr->stmacf_len, // tag size + aad, // additional authenticated data + aad_len, // length of AAD + CRYPTO_ECS_NONE, //encryption cipher + sa_ptr->acs //authentication cipher + ); } else // sa_service_type == SA_PLAINTEXT { diff --git a/src/src_main/sadb_routine_inmemory.template.c b/src/src_main/sadb_routine_inmemory.template.c index 1b9e612c..4b61dfd5 100644 --- a/src/src_main/sadb_routine_inmemory.template.c +++ b/src/src_main/sadb_routine_inmemory.template.c @@ -237,16 +237,15 @@ int32_t sadb_init(void) sa[x].akid = x; sa[x].sa_state = SA_NONE; sa[x].ecs_len = 0; - sa[x].ecs[0] = 0; - sa[x].ecs[1] = 0; - sa[x].ecs[2] = 0; - sa[x].ecs[3] = 0; + sa[x].ecs = NULL; sa[x].shivf_len = IV_SIZE; sa[x].iv = NULL; + sa[x].abm = NULL; + sa[x].abm_len = 0; sa[x].acs_len = 0; - sa[x].acs = 0; + sa[x].acs = CRYPTO_ACS_NONE; sa[x].arc_len = 0; - sa[x].arc = NULL; // calloc and set to 5? + sa[x].arc = NULL; } return status; } @@ -257,8 +256,15 @@ int32_t sadb_init(void) **/ static int32_t sadb_close(void) { - // closing not necessary for inmemory DB. - return CRYPTO_LIB_SUCCESS; + int32_t status = CRYPTO_LIB_SUCCESS; + for (int x = 0; x < NUM_SA; x++) + { + if(sa[x].ecs != NULL) free(sa[x].ecs); + if(sa[x].iv != NULL) free(sa[x].iv); + if(sa[x].abm != NULL) free(sa[x].abm); + if(sa[x].arc != NULL) free(sa[x].arc); + } + return status; } /* @@ -763,7 +769,7 @@ static int32_t sadb_sa_create(void) sa[spi].ecs_len = ((uint8_t)sdls_frame.pdu.data[5]); for (int x = 0; x < sa[spi].ecs_len; x++) { - sa[spi].ecs[x] = ((uint8_t)sdls_frame.pdu.data[count++]); + *(sa[spi].ecs + x) = ((uint8_t)sdls_frame.pdu.data[count++]); } sa[spi].shivf_len = ((uint8_t)sdls_frame.pdu.data[count++]); for (int x = 0; x < sa[spi].shivf_len; x++) diff --git a/test/encryption_test.py b/test/encryption_test.py index f430331e..cbf47897 100644 --- a/test/encryption_test.py +++ b/test/encryption_test.py @@ -1,4 +1,5 @@ from Crypto.Cipher import AES +from Crypto.Hash import CMAC import codecs import sys @@ -22,6 +23,7 @@ def crc16(data : bytearray, offset , length): crc = crc << 1 return crc & 0xFFFF + """ Class: Encryption This class is used to perform AES, GCM encryption in order to provide a truth baseline. @@ -31,6 +33,18 @@ class Encryption: def __init__(self): self.results = 0x00 self.length = 0.0 + + def encrypt_cmac(self, data, key): + data_b = bytes.fromhex(data) + key_b = bytes.fromhex(key) + + cmac_obj = CMAC.new(key_b, ciphermod=AES) + cmac_obj.update(data_b) + + self.results = cmac_obj.hexdigest() + print(self.results) + self.length = len(self.results) + # Function: Encrypt # Encrypts data - given a key, iv, header, and bitmask def encrypt(self, data, key, iv, header, bitmask): @@ -92,7 +106,7 @@ def get_results(self): if __name__ == '__main__': something=Encryption() - something.encrypt("1880d2ca0008197f0b0031000039c5", "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210", "000000000000000000000001", "2003043400FF0004", "00") + something.encrypt_cmac("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445") something.get_len() something.get_results() diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index 16e27cc0..207934e1 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -68,7 +68,8 @@ add_custom_target(gcov ) add_custom_command(TARGET gcov COMMAND echo "=================== GCOV ====================" - COMMAND gcov -b -o ${OBJECT_DIR} crypto_aos.c.gnco crypto_config.c.gnco crypto_key_mgmt.c.gnco crypto_mc.c.gnco crypto_print.c.gnco crypto_tc.c.gnco crypto_tm.c.gnco crypto_user.c.gnco crypto.c.gnco sadb_routine_inmemory.template.c.gnco sadb_routine.c.gnco + #COMMAND gcov -b -o ${OBJECT_DIR} crypto_aos.c.gnco crypto_config.c.gnco crypto_key_mgmt.c.gnco crypto_mc.c.gnco crypto_print.c.gnco crypto_tc.c.gnco crypto_tm.c.gnco crypto_user.c.gnco crypto.c.gnco sadb_routine_inmemory.template.c.gnco sadb_routine.c.gnco + COMMAND gcov -b -o ${OBJECT_DIR} crypto_aos.c.gnco crypto_config.c.gnco crypto_key_mgmt.c.gnco crypto_mc.c.gnco crypto_tc.c.gnco crypto_tm.c.gnco crypto_user.c.gnco crypto.c.gnco sadb_routine_inmemory.template.c.gnco # | grep -A 5 "Adder.cpp" > CoverageSummary.tmp #COMMAND cat CoverageSummary.tmp #COMMAND echo "-- Coverage files have been output to ${PROJECT_BINARY_DIR}/coverage" diff --git a/util/src_util/et_dt_validation.c b/util/src_util/et_dt_validation.c index 3346e7ab..abf138b0 100644 --- a/util/src_util/et_dt_validation.c +++ b/util/src_util/et_dt_validation.c @@ -47,26 +47,14 @@ int EndPython() } /** - * @brief Python Cryptodome Truth Baseline - * Used to generate truth data for Authorized Encryption. Results are compared against TC_ApplySecurity Functionality, - * as well as in reverse using the TC_ProcessSecurity function. - * @param data Hexstring of the plain text to be encrypted - * @param key Hexstring of the key to be used during encryption - * @param iv Hextring of the IV to be used during encryption - * @param header Hextring of the header (AAD) that will be used during encryption - * @param bitmask Hexstring of the bitmask that will be used on the header - * @param expected Ouput character array that will be allocated within this function. Memory must be freed upon - *completion of test. - * @param expected_length The length of the expected character array that is set within this function - * @note The char** expected that is passsed to this function must be freed by the user upon completion of unit test or - *other call. - **/ -void python_auth_encryption(char *data, char *key, char *iv, char *header, char *bitmask, uint8_t **expected, - long *expected_length) + * @brief Python Setup + * Sets up the use of python encryption class within CTests + * */ +void setup_python() { Py_Initialize(); + PyRun_SimpleString("import sys\nsys.path.append('../test')"); PyRun_SimpleString("import sys\nsys.path.append('../../test')"); - pName = PyUnicode_FromString("encryption_test"); pModule = PyImport_Import(pName); if (pModule == NULL) @@ -89,7 +77,50 @@ void python_auth_encryption(char *data, char *key, char *iv, char *header, char EndPython(); return; } +} +/** + * @brief Python Cryptodoem CMAC Truth Baseline + * @param data Hexstring of the plain text + * @param key Hexstring of the key to be used + * @param expected Output character array that will be allocated within this function. Memory must be freed upon completion of the test + * @param expected_length The length of the expected character array this is set within this function + * @note User must free memory themselves. + **/ +void python_cmac(char *data, char *key, uint8_t **expected, long *expected_length) +{ + setup_python(); + + pValue = PyObject_CallMethod(pInstance, "encrypt_cmac", "ss", data, key); + pValue = PyObject_CallMethod(pInstance, "get_len", NULL); + long temp_length = PyLong_AsLong(pValue); + *expected_length = temp_length; + pValue = PyObject_CallMethod(pInstance, "get_results", NULL); + char *temp_expected = PyBytes_AsString(pValue); + *expected = (uint8_t *)malloc(sizeof(uint8_t) * (int)*expected_length); + memcpy(*expected, temp_expected, (int)*expected_length); + return; +} + +/** + * @brief Python Cryptodome Truth Baseline + * Used to generate truth data for Authorized Encryption. Results are compared against TC_ApplySecurity Functionality, + * as well as in reverse using the TC_ProcessSecurity function. + * @param data Hexstring of the plain text to be encrypted + * @param key Hexstring of the key to be used during encryption + * @param iv Hextring of the IV to be used during encryption + * @param header Hextring of the header (AAD) that will be used during encryption + * @param bitmask Hexstring of the bitmask that will be used on the header + * @param expected Ouput character array that will be allocated within this function. Memory must be freed upon + *completion of test. + * @param expected_length The length of the expected character array that is set within this function + * @note The char** expected that is passsed to this function must be freed by the user upon completion of unit test or + *other call. + **/ +void python_auth_encryption(char *data, char *key, char *iv, char *header, char *bitmask, uint8_t **expected, + long *expected_length) +{ + setup_python(); pValue = PyObject_CallMethod(pInstance, "encrypt", "sssss", data, key, iv, header, bitmask); pValue = PyObject_CallMethod(pInstance, "get_len", NULL); @@ -136,14 +167,21 @@ UTEST(ET_VALIDATION, AUTH_ENCRYPTION_TEST) TC_t *tc_sdls_processed_frame; tc_sdls_processed_frame = malloc(sizeof(uint8_t) * TC_SIZE); memset(tc_sdls_processed_frame, 0, (sizeof(uint8_t) * TC_SIZE)); + + // Default SA + // Expose SA 1 for testing + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + // Ensure that Process Security can activate SA 4 return_val = Crypto_TC_ProcessSecurity(activate_sa4_b, &activate_sa4_len, tc_sdls_processed_frame); - printf("Verifying TC_Process Return Value\n"); + //printf("Verifying TC_Process Return Value\n"); ASSERT_EQ(CRYPTO_LIB_SUCCESS, return_val); - // Expose SA 1 for testing - sadb_routine->sadb_get_sa_from_spi(1, &test_association); + // Deactive SA 1 test_association->sa_state = SA_NONE; + // Expose SA 4 for testing sadb_routine->sadb_get_sa_from_spi(4, &test_association); test_association->arc_len = 0; @@ -152,6 +190,8 @@ UTEST(ET_VALIDATION, AUTH_ENCRYPTION_TEST) test_association->ast = 1; test_association->est = 1; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; return_val = Crypto_TC_ApplySecurity(enc_test_ping_b, enc_test_ping_len, &ptr_enc_frame, &enc_frame_len); ASSERT_EQ(CRYPTO_LIB_SUCCESS, return_val); @@ -162,13 +202,16 @@ UTEST(ET_VALIDATION, AUTH_ENCRYPTION_TEST) for (int i = 0; i < expected_length; i++) { - printf("[%d]: %02x -> %02x \n", i, expected[i], ptr_enc_frame[i]); + //printf("[%d]: %02x -> %02x \n", i, expected[i], ptr_enc_frame[i]); ASSERT_EQ(expected[i], ptr_enc_frame[i]); } + Crypto_Shutdown(); + // sadb_routine->sadb_close(); free(activate_sa4_b); free(enc_test_ping_b); free(ptr_enc_frame); free(expected); + free(test_association->ecs); free(tc_sdls_processed_frame); EndPython(); } @@ -207,11 +250,15 @@ UTEST(DT_VALIDATION, AUTH_DECRYPTION_TEST) tc_sdls_processed_frame = malloc(sizeof(uint8_t) * TC_SIZE); memset(tc_sdls_processed_frame, 0, (sizeof(uint8_t) * TC_SIZE)); + // Default SA + // Expose SA 1 for testing + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + // Ensure that Process Security can activate SA 4 return_val = Crypto_TC_ProcessSecurity(activate_sa4_b, &activate_sa4_len, tc_sdls_processed_frame); ASSERT_EQ(CRYPTO_LIB_SUCCESS, return_val); - // Expose SA 1 for testing - sadb_routine->sadb_get_sa_from_spi(1, &test_association); // Deactive SA 1 test_association->sa_state = SA_NONE; @@ -220,27 +267,30 @@ UTEST(DT_VALIDATION, AUTH_DECRYPTION_TEST) sadb_routine->sadb_get_sa_from_spi(4, &test_association); test_association->arc_len = 0; test_association->gvcid_tc_blk.vcid = 1; + test_association->iv = calloc(1, test_association->shivf_len * sizeof(uint8_t)); test_association->iv[11] = 1; test_association->ast = 1; test_association->est = 1; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; return_val = Crypto_TC_ProcessSecurity(dec_test_ping_b, &dec_test_ping_len, tc_sdls_processed_frame); ASSERT_EQ(9, return_val); // 9 is the number of pings in that EP PDU. Crypto_Shutdown(); - printf("PDU:\n\t"); - for (int i = 0; i < tc_sdls_processed_frame->tc_pdu_len; i++) - { - printf("%02x", enc_test_ping_b[i]); - } - printf("\nPF PDU:\n\t"); - for (int i = 0; i < tc_sdls_processed_frame->tc_pdu_len; i++) - { - printf("%02x", tc_sdls_processed_frame->tc_pdu[i]); - } - printf("\n"); + // printf("PDU:\n\t"); + // for (int i = 0; i < tc_sdls_processed_frame->tc_pdu_len; i++) + // { + // printf("%02x", enc_test_ping_b[i]); + // } + // printf("\nPF PDU:\n\t"); + // for (int i = 0; i < tc_sdls_processed_frame->tc_pdu_len; i++) + // { + // printf("%02x", tc_sdls_processed_frame->tc_pdu[i]); + // } + // printf("\n"); for (int i = 0; i < tc_sdls_processed_frame->tc_pdu_len; i++) { ASSERT_EQ(enc_test_ping_b[i], tc_sdls_processed_frame->tc_pdu[i]); @@ -248,7 +298,9 @@ UTEST(DT_VALIDATION, AUTH_DECRYPTION_TEST) free(activate_sa4_b); free(dec_test_ping_b); + free(test_association->ecs); free(tc_sdls_processed_frame); + // sadb_routine->sadb_close(); EndPython(); } @@ -269,6 +321,7 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); Crypto_Init(); + printf("E\n"); SadbRoutine sadb_routine = get_sadb_routine_inmemory(); crypto_key_t* ek_ring = cryptography_if->get_ek_ring(); @@ -291,6 +344,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -301,6 +356,7 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) hex_conversion(buffer_nist_pt_h, (char **)&buffer_nist_pt_b, &buffer_nist_pt_len); // Convert/Set input IV hex_conversion(buffer_nist_iv_h, (char **)&buffer_nist_iv_b, &buffer_nist_iv_len); + test_association->iv = malloc(*buffer_nist_iv_b * sizeof(uint8_t)); memcpy(test_association->iv, buffer_nist_iv_b, buffer_nist_iv_len); // Convert input ciphertext hex_conversion(buffer_nist_ct_h, (char **)&buffer_nist_ct_b, &buffer_nist_ct_len); @@ -312,7 +368,7 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) Crypto_Shutdown(); for (int i = 0; i < buffer_nist_pt_len - 7; i++) { - printf("[%d]: %02x -> %02x \n", i, *(ptr_enc_frame + enc_data_idx), buffer_nist_ct_b[i]); + //printf("[%d]: %02x -> %02x \n", i, *(ptr_enc_frame + enc_data_idx), buffer_nist_ct_b[i]); ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_nist_ct_b[i]); enc_data_idx++; } @@ -321,6 +377,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) free(buffer_nist_iv_b); free(buffer_nist_ct_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -365,6 +423,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; sadb_routine->sadb_get_sa_from_spi(9, &test_association); + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); memcpy(ek_ring[test_association->ekid].value, buffer_nist_key_b, buffer_nist_key_len); @@ -385,7 +445,7 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) for (int i = 0; i < tc_nist_processed_frame->tc_pdu_len; i++) { - printf("[%d]: %02x -> %02x \n", i, buffer_nist_pt_b[i + 5], tc_nist_processed_frame->tc_pdu[i]); + //printf("[%d]: %02x -> %02x \n", i, buffer_nist_pt_b[i + 5], tc_nist_processed_frame->tc_pdu[i]); ASSERT_EQ(buffer_nist_pt_b[i + 5], tc_nist_processed_frame->tc_pdu[i]); } @@ -394,6 +454,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) free(buffer_nist_iv_b); free(buffer_nist_et_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -433,6 +495,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -462,6 +526,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) free(buffer_nist_iv_b); free(buffer_nist_ct_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -504,6 +570,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -534,6 +602,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) free(buffer_nist_iv_b); free(buffer_nist_et_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -574,6 +644,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_2) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -603,6 +675,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_2) free(buffer_nist_iv_b); free(buffer_nist_ct_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -646,6 +720,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_2) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -673,6 +749,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_2) free(buffer_nist_iv_b); free(buffer_nist_et_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -713,6 +791,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_3) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -742,6 +822,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_3) free(buffer_nist_iv_b); free(buffer_nist_ct_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -785,6 +867,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_3) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -812,6 +896,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_3) free(buffer_nist_iv_b); free(buffer_nist_et_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -852,6 +938,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_4) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -881,6 +969,8 @@ UTEST(NIST_ENC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_4) free(buffer_nist_iv_b); free(buffer_nist_ct_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -924,6 +1014,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_4) sadb_routine->sadb_get_sa_from_spi(9, &test_association); test_association->arc_len = 0; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -951,6 +1043,8 @@ UTEST(NIST_DEC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_4) free(buffer_nist_iv_b); free(buffer_nist_et_b); free(buffer_nist_key_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -1009,6 +1103,8 @@ UTEST(NIST_ENC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) test_association->abm_len = 1024; test_association->stmacf_len = 16; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -1043,6 +1139,8 @@ UTEST(NIST_ENC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) free(buffer_nist_key_b); free(buffer_cyber_chef_mac_b); free(buffer_nist_aad_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -1091,6 +1189,8 @@ UTEST(NIST_ENC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) memset(test_association->abm, 0xFF, (test_association->abm_len * sizeof(uint8_t))); // Bitmask test_association->stmacf_len = 16; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -1114,8 +1214,8 @@ UTEST(NIST_ENC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) for (int i = 0; i < buffer_cyber_chef_mac_len; i++) { - printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_cyber_chef_mac_b[i], - *(ptr_enc_frame + enc_data_idx)); + //printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_cyber_chef_mac_b[i], + // *(ptr_enc_frame + enc_data_idx)); ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_cyber_chef_mac_b[i]); enc_data_idx++; } @@ -1125,6 +1225,8 @@ UTEST(NIST_ENC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_1) free(buffer_nist_iv_b); free(buffer_nist_key_b); free(buffer_cyber_chef_mac_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -1180,6 +1282,8 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) test_association->shivf_len = 12; test_association->stmacf_len = 16; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -1197,11 +1301,11 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) hex_conversion(buffer_nist_mac_frame_h, (char **)&buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len); status = Crypto_TC_ProcessSecurity(buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len, tc_nist_processed_frame); - printf("TC_Process returned status %d\n", status); + //printf("TC_Process returned status %d\n", status); // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) // Calc payload index: total length - pt length - #ifdef DEBUG +#ifdef DEBUG printf("Expected MAC: "); for (int i=0; itc_sec_trailer.mac[i]); } printf("\n"); - #endif +#endif #ifdef DEBUG printf("PDU Length: %d \n",tc_nist_processed_frame->tc_pdu_len); @@ -1247,6 +1351,8 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0) free(buffer_cyber_chef_mac_b); free(buffer_nist_mac_frame_b); free(buffer_nist_cp_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -1302,6 +1408,8 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_DATA) test_association->shivf_len = 12; test_association->stmacf_len = 16; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -1319,7 +1427,7 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_DATA) hex_conversion(buffer_nist_mac_frame_h, (char **)&buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len); status = Crypto_TC_ProcessSecurity(buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len, tc_nist_processed_frame); - printf("TC_Process returned status %d\n", status); + //printf("TC_Process returned status %d\n", status); // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) // Calc payload index: total length - pt length @@ -1344,6 +1452,8 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_DATA) free(buffer_cyber_chef_mac_b); free(buffer_nist_mac_frame_b); free(buffer_nist_cp_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); } /** @@ -1399,6 +1509,8 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_MAC) test_association->shivf_len = 12; test_association->stmacf_len = 16; test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_AES256_GCM; // Insert key into keyring of SA 9 hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); @@ -1416,7 +1528,7 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_MAC) hex_conversion(buffer_nist_mac_frame_h, (char **)&buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len); status = Crypto_TC_ProcessSecurity(buffer_nist_mac_frame_b, &buffer_nist_mac_frame_len, tc_nist_processed_frame); - printf("TC_Process returned status %d\n", status); + //printf("TC_Process returned status %d\n", status); // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) // Calc payload index: total length - pt length @@ -1441,6 +1553,363 @@ UTEST(NIST_DEC_MAC_VALIDATION, AES_GCM_256_IV_96_PT_128_TEST_0_BAD_MAC) free(buffer_cyber_chef_mac_b); free(buffer_nist_mac_frame_b); free(buffer_nist_cp_b); + free(test_association->ecs); + // sadb_routine->sadb_close(); +} + +/** + * @brief Unit Test: Test CMAC, bitmask of 0s + **/ +UTEST(NIST_ENC_CMAC_VALIDATION, AES_CMAC_256_PT_128_TEST_0) +{ + uint8_t *ptr_enc_frame = NULL; + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(SADB_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Init(); + SadbRoutine sadb_routine = get_sadb_routine_inmemory(); + crypto_key_t* ek_ring = cryptography_if->get_ek_ring(); + + // NIST supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char *buffer_nist_key_h = "b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445"; + // | Header | NIST CMAC Test Vector |FECF| + char *buffer_frame_pt_h = "2003004600C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258C925"; + // Python truth string passed below is ZEROed out, not including a MAC or FECF which isn't hashed against, but the LENGTH (including fecf) needs to be updated in the Tf Header + // Length is dependent on whatever the variable mac length to be updated in the header + // | Header |SPI| ARSN | NIST CMAC Frame Data | + // "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258"; + // "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Python output MAC + char* buffer_python_mac_h = "7629961f6b92145290ad3e149940511a"; + uint8_t *buffer_frame_pt_b, *buffer_nist_key_b, *buffer_python_mac_b = NULL; + int buffer_frame_pt_len, buffer_nist_key_len, buffer_python_mac_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t *test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sadb_routine->sadb_get_sa_from_spi(9, &test_association); + test_association->ast = 1; + test_association->est = 0; + test_association->arc_len = 0; + test_association->shivf_len = 0; + test_association->shsnf_len = 4; + test_association->arc = 0; + test_association->arc_len = 4; + test_association->arc = calloc(1, test_association->arc_len * sizeof(uint8_t)); + test_association->abm_len = 1024; + memset(test_association->abm, 0x00, (test_association->abm_len * sizeof(uint8_t))); // Bitmask + test_association->stmacf_len = 16; + test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + test_association->acs = CRYPTO_AES256_CMAC; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); + memcpy(ek_ring[test_association->ekid].value, buffer_nist_key_b, buffer_nist_key_len); + + // Convert input plaintext + hex_conversion(buffer_frame_pt_h, (char **)&buffer_frame_pt_b, &buffer_frame_pt_len); + // Convert input mac + hex_conversion(buffer_python_mac_h, (char **)&buffer_python_mac_b, &buffer_python_mac_len); + + Crypto_TC_ApplySecurity(buffer_frame_pt_b, buffer_frame_pt_len, &ptr_enc_frame, &enc_frame_len); + + // Note: For comparison, primarily interested in the MAC + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_python_mac_len - 2; + Crypto_Shutdown(); + + for (int i = 0; i < buffer_python_mac_len; i++) + { + printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_python_mac_b[i], *(ptr_enc_frame + enc_data_idx)); + ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_python_mac_b[i]); + enc_data_idx++; + } + + free(ptr_enc_frame); + free(buffer_frame_pt_b); + free(buffer_nist_key_b); + free(buffer_python_mac_b); + free(test_association->arc); + // sadb_routine->sadb_close(); + // free(test_association); +} + +/** + * @brief Unit Test: Test CMAC, bitmask of 1s + **/ +UTEST(NIST_ENC_CMAC_VALIDATION, AES_CMAC_256_PT_128_TEST_1) +{ + uint8_t *ptr_enc_frame = NULL; + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(SADB_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Init(); + SadbRoutine sadb_routine = get_sadb_routine_inmemory(); + crypto_key_t* ek_ring = cryptography_if->get_ek_ring(); + + // NIST supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char *buffer_nist_key_h = "b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445"; + // | Header | NIST CMAC Test Vector |FECF| + char *buffer_frame_pt_h = "2003004600C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258C925"; + // Python truth string passed below, not including a MAC or FECF which isn't hashed against, but the LENGTH (including fecf) needs to be updated in the Tf Header + // Length is dependent on whatevr the variable mac length to be updated in the header + // | Header |SPI| ARSN | NIST CMAC Frame Data | + // char *buffer_frame_pt_h = "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258"; + // 2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258CF549CC15D63EAB7AD25EB3089D94E6C2D9D + // Python output MAC + char* buffer_python_mac_h = "cf549cc15d63eab7ad25eb3089d94e6c"; + uint8_t *buffer_frame_pt_b, *buffer_nist_key_b, *buffer_python_mac_b = NULL; + int buffer_frame_pt_len, buffer_nist_key_len, buffer_python_mac_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t *test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sadb_routine->sadb_get_sa_from_spi(9, &test_association); + test_association->ast = 1; + test_association->est = 0; + test_association->arc_len = 0; + test_association->shivf_len = 0; + test_association->shsnf_len = 4; + test_association->arc = 0; + test_association->arc_len = 4; + test_association->arc = calloc(1, test_association->arc_len * sizeof(uint8_t)); + test_association->abm_len = 1024; + memset(test_association->abm, 0xFF, (test_association->abm_len * sizeof(uint8_t))); // Bitmask + test_association->stmacf_len = 16; + test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + test_association->acs = CRYPTO_AES256_CMAC; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); + memcpy(ek_ring[test_association->ekid].value, buffer_nist_key_b, buffer_nist_key_len); + + // Convert input plaintext + hex_conversion(buffer_frame_pt_h, (char **)&buffer_frame_pt_b, &buffer_frame_pt_len); + // Convert input mac + hex_conversion(buffer_python_mac_h, (char **)&buffer_python_mac_b, &buffer_python_mac_len); + + Crypto_TC_ApplySecurity(buffer_frame_pt_b, buffer_frame_pt_len, &ptr_enc_frame, &enc_frame_len); + + // Note: For comparison, primarily interested in the MAC + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_python_mac_len - 2; + Crypto_Shutdown(); + + for (int i = 0; i < buffer_python_mac_len; i++) + { + // printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_python_mac_b[i], *(ptr_enc_frame + enc_data_idx)); + ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_python_mac_b[i]); + enc_data_idx++; + } + free(ptr_enc_frame); + free(buffer_frame_pt_b); + free(buffer_nist_key_b); + free(buffer_python_mac_b); + // free(test_association); + // sadb_routine->sadb_close(); +} + +/** + * @brief Unit Test: Test CMAC, bitmask of 0s + **/ +UTEST(NIST_DEC_CMAC_VALIDATION, AES_CMAC_256_PT_128_TEST_0) +{ + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(SADB_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Init(); + SadbRoutine sadb_routine = get_sadb_routine_inmemory(); + crypto_key_t* ek_ring = cryptography_if->get_ek_ring(); + + // NIST supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char *buffer_nist_key_h = "b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445"; + // | Header |SPI| ARSN | NIST CMAC Test Vector | MAC |FECF| + char *buffer_frame_pt_h = "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F193942587629961f6b92145290ad3e149940511a46ce"; + // Python truth string passed below, not including a MAC or FECF which isn't hashed against, but the LENGTH (including fecf) needs to be updated in the Tf Header + // Length is dependent on whatevr the variable mac length to be updated in the header + // | Header |SPI| ARSN | NIST CMAC Frame Data | + // char *buffer_frame_pt_h = "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258"; + // 2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258CF549CC15D63EAB7AD25EB3089D94E6C2D9D + // Zeroed out w. bitmask 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + // Python output MAC + char* buffer_python_mac_h = "7629961f6b92145290ad3e149940511a"; + uint8_t *buffer_frame_pt_b, *buffer_nist_key_b, *buffer_python_mac_b = NULL; + int buffer_frame_pt_len, buffer_nist_key_len, buffer_python_mac_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t *test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sadb_routine->sadb_get_sa_from_spi(9, &test_association); + test_association->ast = 1; + test_association->est = 0; + test_association->arc_len = 0; + test_association->shivf_len = 0; + test_association->shsnf_len = 4; + test_association->arc = 0; + test_association->arc_len = 4; + test_association->arc = calloc(1, test_association->arc_len * sizeof(uint8_t)); + test_association->abm_len = 1024; + memset(test_association->abm, 0x00, (test_association->abm_len * sizeof(uint8_t))); // Bitmask + test_association->stmacf_len = 16; + test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + test_association->acs = CRYPTO_AES256_CMAC; + + TC_t *tc_sdls_processed_frame; + tc_sdls_processed_frame = calloc(1, sizeof(uint8_t) * TC_SIZE); + + // Insert key into keyring of SA 9 + hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); + memcpy(ek_ring[test_association->ekid].value, buffer_nist_key_b, buffer_nist_key_len); + + // Convert input plaintext + hex_conversion(buffer_frame_pt_h, (char **)&buffer_frame_pt_b, &buffer_frame_pt_len); + // Convert input mac + hex_conversion(buffer_python_mac_h, (char **)&buffer_python_mac_b, &buffer_python_mac_len); + + Crypto_TC_ProcessSecurity(buffer_frame_pt_b, &buffer_frame_pt_len, tc_sdls_processed_frame); + + // Note: For comparison, primarily interested in the MAC + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_python_mac_len - 2; + Crypto_Shutdown(); + + for (int i = 0; i < buffer_python_mac_len; i++) + { + printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_python_mac_b[i], (tc_sdls_processed_frame->tc_sec_trailer.mac[i])); + ASSERT_EQ(tc_sdls_processed_frame->tc_sec_trailer.mac[i], buffer_python_mac_b[i]); + enc_data_idx++; + } + + free(tc_sdls_processed_frame); + free(buffer_frame_pt_b); + free(buffer_nist_key_b); + free(buffer_python_mac_b); + // free(test_association->arc); + // free(test_association); + // sadb_routine->sadb_close(); +} + +/** + * @brief Unit Test: Test CMAC, bitmask of 1s + **/ +UTEST(NIST_DEC_CMAC_VALIDATION, AES_CMAC_256_PT_128_TEST_1) +{ + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(SADB_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_NO_SEGMENT_HDRS); + Crypto_Init(); + SadbRoutine sadb_routine = get_sadb_routine_inmemory(); + crypto_key_t* ek_ring = cryptography_if->get_ek_ring(); + + // NIST supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char *buffer_nist_key_h = "b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445"; + // | Header |SPI| ARSN | NIST CMAC Test Vector | MAC |FECF| + char *buffer_frame_pt_h = "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258CF549CC15D63EAB7AD25EB3089D94E6C2D9D"; + // Python truth string passed below, not including a MAC or FECF which isn't hashed against, but the LENGTH (including fecf) needs to be updated in the Tf Header + // Length is dependent on whatevr the variable mac length to be updated in the header + // | Header |SPI| ARSN | NIST CMAC Frame Data | + // char *buffer_frame_pt_h = "2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258"; + // 2003005C00000900000000C66D322247EBF272E6A353F9940B00847CF78E27F2BC0C81A696DB411E47C0E9630137D3FA860A71158E23D80B699E8006E52345FB7273B2E084407F19394258CF549CC15D63EAB7AD25EB3089D94E6C2D9D + // Python output MAC + char* buffer_python_mac_h = "cf549cc15d63eab7ad25eb3089d94e6c"; + uint8_t *buffer_frame_pt_b, *buffer_nist_key_b, *buffer_python_mac_b = NULL; + int buffer_frame_pt_len, buffer_nist_key_len, buffer_python_mac_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t *test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sadb_routine->sadb_get_sa_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sadb_routine->sadb_get_sa_from_spi(9, &test_association); + test_association->ast = 1; + test_association->est = 0; + test_association->arc_len = 0; + test_association->shivf_len = 0; + test_association->shsnf_len = 4; + test_association->arc = 0; + test_association->arc_len = 4; + test_association->arc = calloc(1, test_association->arc_len * sizeof(uint8_t)); + test_association->abm_len = 1024; + memset(test_association->abm, 0xFF, (test_association->abm_len * sizeof(uint8_t))); // Bitmask + test_association->stmacf_len = 16; + test_association->sa_state = SA_OPERATIONAL; + test_association->ecs = calloc(1, test_association->ecs_len * sizeof(uint8_t)); + *test_association->ecs = CRYPTO_ECS_NONE; + test_association->acs = CRYPTO_AES256_CMAC; + + TC_t *tc_sdls_processed_frame; + tc_sdls_processed_frame = calloc(1, sizeof(uint8_t) * TC_SIZE); + + // Insert key into keyring of SA 9 + hex_conversion(buffer_nist_key_h, (char **)&buffer_nist_key_b, &buffer_nist_key_len); + memcpy(ek_ring[test_association->ekid].value, buffer_nist_key_b, buffer_nist_key_len); + + // Convert input plaintext + hex_conversion(buffer_frame_pt_h, (char **)&buffer_frame_pt_b, &buffer_frame_pt_len); + // Convert input mac + hex_conversion(buffer_python_mac_h, (char **)&buffer_python_mac_b, &buffer_python_mac_len); + + Crypto_TC_ProcessSecurity(buffer_frame_pt_b, &buffer_frame_pt_len, tc_sdls_processed_frame); + + // Note: For comparison, primarily interested in the MAC + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_python_mac_len - 2; + Crypto_Shutdown(); + + for (int i = 0; i < buffer_python_mac_len; i++) + { + printf("[%d] Truth: %02x, Actual: %02x\n", enc_data_idx, buffer_python_mac_b[i], (tc_sdls_processed_frame->tc_sec_trailer.mac[i])); + ASSERT_EQ(tc_sdls_processed_frame->tc_sec_trailer.mac[i], buffer_python_mac_b[i]); + enc_data_idx++; + } + + free(tc_sdls_processed_frame); + free(buffer_frame_pt_b); + free(buffer_nist_key_b); + free(buffer_python_mac_b); + // free(test_association->arc); + // free(test_association); + // sadb_routine->sadb_close(); } -UTEST_MAIN(); +UTEST_MAIN(); \ 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 053a6192..09bb038e 100644 --- a/util/src_util/ut_tc_apply.c +++ b/util/src_util/ut_tc_apply.c @@ -107,6 +107,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_ENC) sadb_routine->sadb_get_sa_from_spi(4, &test_association); test_association->sa_state = SA_OPERATIONAL; test_association->ast = 0; + test_association->arc_len = 0; return_val = Crypto_TC_ApplySecurity((uint8_t *)raw_tc_sdls_ping_b, raw_tc_sdls_ping_len, &ptr_enc_frame, &enc_frame_len); @@ -141,6 +142,7 @@ UTEST(TC_APPLY_SECURITY, HAPPY_PATH_AUTH_ENC) test_association->sa_state = SA_NONE; sadb_routine->sadb_get_sa_from_spi(4, &test_association); test_association->sa_state = SA_OPERATIONAL; + test_association->arc_len = 0; return_val = Crypto_TC_ApplySecurity((uint8_t *)raw_tc_sdls_ping_b, raw_tc_sdls_ping_len, &ptr_enc_frame, &enc_frame_len);