col_append_str(actx->pinfo->cinfo, COL_INFO, "SecurityModeComplete");
-#.FN_HDR SecurityModeFailure
+#.FN_BODY SecurityModeFailure
+ mac_lte_info *p_mac_lte_info;
+%(DEFAULT_BODY)s
+ /* Look for UE identifier */
+ p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
+
+ if (p_mac_lte_info != NULL) {
+ /* Inform PDCP that the UE failed to execute the securityModeCommand */
+ set_pdcp_lte_security_algorithms_failed(p_mac_lte_info->ueid);
+ }
col_append_str(actx->pinfo->cinfo, COL_INFO, "SecurityModeFailure");
+
#.FN_HDR UECapabilityInformation
/* We do release the configuration here instead of RRC Connection Release message */
/* as the UE could have locally dropped the previous RRC Connection */
set_mac_lte_drx_config_release(p_mac_lte_info->ueid, actx->pinfo);
+ /* TODO: also release PDCP security config here */
}
%(DEFAULT_BODY)s
%(DEFAULT_BODY)s
p_security_algorithms = private_data_pdcp_security_algorithms(actx);
p_security_algorithms->configuration_frame = actx->pinfo->fd->num;
+ p_security_algorithms->previous_configuration_frame = 0;
+ p_security_algorithms->previous_integrity = eia0;
+ p_security_algorithms->previous_ciphering = eea0;
+
/* Look for UE identifier */
p_pdcp_lte_info = (pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_pdcp_lte, 0);
if (p_pdcp_lte_info != NULL) {
/* We do release the configuration here instead of RRC Connection Release message */
/* as the UE could have locally dropped the previous RRC Connection */
set_mac_lte_drx_config_release(p_mac_lte_info->ueid, actx->pinfo);
+ /* TODO: also release PDCP security config here */
}
offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
ett_lte_rrc_RRCConnectionSetup, RRCConnectionSetup_sequence);
p_security_algorithms = private_data_pdcp_security_algorithms(actx);
p_security_algorithms->configuration_frame = actx->pinfo->fd->num;
+ p_security_algorithms->previous_configuration_frame = 0;
+ p_security_algorithms->previous_integrity = eia0;
+ p_security_algorithms->previous_ciphering = eea0;
+
/* Look for UE identifier */
p_pdcp_lte_info = (pdcp_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_pdcp_lte, 0);
if (p_pdcp_lte_info != NULL) {
static int
dissect_lte_rrc_SecurityModeFailure(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
+ mac_lte_info *p_mac_lte_info;
+ offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
+ ett_lte_rrc_SecurityModeFailure, SecurityModeFailure_sequence);
+
+ /* Look for UE identifier */
+ p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
+
+ if (p_mac_lte_info != NULL) {
+ /* Inform PDCP that the UE failed to execute the securityModeCommand */
+ set_pdcp_lte_security_algorithms_failed(p_mac_lte_info->ueid);
+ }
col_append_str(actx->pinfo->cinfo, COL_INFO, "SecurityModeFailure");
+
- offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
- ett_lte_rrc_SecurityModeFailure, SecurityModeFailure_sequence);
return offset;
}
Note that the use of this algorithm is restricted, and that an administrative charge
may be applicable if you use it (see e.g. http://www.gsma.com/technicalprojects/fraud-security/security-algorithms).
A version of Wireshark with this enabled would not be distributable. */
-/* #define HAVE_SNOW3G */
+#define HAVE_SNOW3G
+#include <epan/snow3g_algorithm.h>
#include "packet-rlc-lte.h"
#include "packet-pdcp-lte.h"
/* N.B. won't work for internal, non-RRC signalling methods... */
pdcp_security_info_t *p_frame_security;
- /* Copy security struct */
- pdcp_security_info_t *p_security = wmem_new(wmem_file_scope(), pdcp_security_info_t);
- *p_security = *security_info;
+ /* Create or update current settings, by UEID */
+ pdcp_security_info_t* ue_security =
+ (pdcp_security_info_t*)g_hash_table_lookup(pdcp_security_hash,
+ GUINT_TO_POINTER((guint)ueid));
+ if (ue_security == NULL) {
+ /* Copy whole security struct */
+ ue_security = wmem_new(wmem_file_scope(), pdcp_security_info_t);
+ *ue_security = *security_info;
- /* And add into security table */
- g_hash_table_insert(pdcp_security_hash, GUINT_TO_POINTER((guint)ueid), p_security);
+ /* And add into security table */
+ g_hash_table_insert(pdcp_security_hash, GUINT_TO_POINTER((guint)ueid), ue_security);
+ }
+ else {
+ /* Just update existing entry already in table */
+ ue_security->previous_configuration_frame = ue_security->configuration_frame;
+ ue_security->previous_integrity = ue_security->integrity;
+ ue_security->previous_ciphering = ue_security->ciphering;
+
+ ue_security->configuration_frame = security_info->configuration_frame;
+ ue_security->integrity = security_info->integrity;
+ ue_security->ciphering = security_info->ciphering;
+ ue_security->seen_next_ul_pdu = FALSE;
+ }
- /* Add an entry for this PDU already to use these settings, as otherwise it won't be present
+ /* Also add an entry for this PDU already to use these settings, as otherwise it won't be present
when we query it on the first pass. */
p_frame_security = wmem_new(wmem_file_scope(), pdcp_security_info_t);
- *p_frame_security = *p_security;
+ *p_frame_security = *ue_security;
g_hash_table_insert(pdcp_security_result_hash,
- get_ueid_frame_hash_key(ueid, security_info->configuration_frame, TRUE),
+ get_ueid_frame_hash_key(ueid, ue_security->configuration_frame, TRUE),
p_frame_security);
}
+/* UE failed to process SecurityModeCommand so go back to previous security settings */
+void set_pdcp_lte_security_algorithms_failed(guint16 ueid)
+{
+ /* Look up current state by UEID */
+ pdcp_security_info_t* ue_security =
+ (pdcp_security_info_t*)g_hash_table_lookup(pdcp_security_hash,
+ GUINT_TO_POINTER((guint)ueid));
+ if (ue_security != NULL) {
+ /* TODO: could remove from table if previous_configuration_frame is 0 */
+ /* Go back to previous state */
+ ue_security->configuration_frame = ue_security->previous_configuration_frame;
+ ue_security->integrity = ue_security->previous_integrity;
+ ue_security->ciphering = ue_security->previous_ciphering;
+ }
+}
+
/* Decipher payload if algorithm is supported and plausible inputs are available */
static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset,
pdu_security_settings_t *pdu_security_settings,
typedef struct pdcp_security_info_t
{
guint32 configuration_frame;
- gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */
+ gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */
enum security_integrity_algorithm_e integrity;
enum security_ciphering_algorithm_e ciphering;
+
+ /* Store previous settings so can revert if get SecurityModeFailure */
+ guint32 previous_configuration_frame;
+ enum security_integrity_algorithm_e previous_integrity;
+ enum security_ciphering_algorithm_e previous_ciphering;
} pdcp_security_info_t;
/* Function to configure ciphering & integrity algorithms */
void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_security_info_t *security_info);
+/* Function to indicate securityModeCommand did not complete */
+void set_pdcp_lte_security_algorithms_failed(guint16 ueid);
+
+