Send news of SecurityModeFailure to PDCP dissector, which will attempt to roll back...
authormartinm <martinm@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 27 Jan 2014 12:06:46 +0000 (12:06 +0000)
committermartinm <martinm@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 27 Jan 2014 12:06:46 +0000 (12:06 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@54978 f5534014-38df-0310-8fa8-9805f1628bb7

asn1/lte-rrc/lte-rrc.cnf
epan/dissectors/packet-lte-rrc.c
epan/dissectors/packet-pdcp-lte.c
epan/dissectors/packet-pdcp-lte.h

index 65240555bae46ad98b29669d7656e98a95e0dc74..12ab434bce37789263b11342c93d19ca2d9b4894 100644 (file)
@@ -1092,9 +1092,19 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
 
   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
 
@@ -1510,6 +1520,7 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
     /* 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
 
@@ -1520,6 +1531,10 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
 %(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) {
index a480d0f5f2b6316a62fb6e27b2291d0920e3067a..3687f394aeffe931cf019de595e89740216a7158 100644 (file)
@@ -18812,6 +18812,7 @@ dissect_lte_rrc_RRCConnectionSetup(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t
     /* 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);
@@ -22299,6 +22300,10 @@ dissect_lte_rrc_SecurityAlgorithmConfig(tvbuff_t *tvb _U_, int offset _U_, asn1_
 
   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) {
@@ -27943,11 +27948,21 @@ static const per_sequence_t SecurityModeFailure_sequence[] = {
 
 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;
 }
index abd58b37495e443fbe8ec2715b04dd6b297f0e5f..06991f3c23b37d082e18745a4e22786e2b0943ea 100644 (file)
@@ -44,7 +44,8 @@
    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"
@@ -1328,22 +1329,55 @@ void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_security_info_t *securi
     /* 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,
index b10cdda65bf3499f33ee14c1cfc7ee2e9e580404..c0b758d2f32c0fc754b5a13ede572d9240edc09c 100644 (file)
@@ -60,9 +60,14 @@ enum security_ciphering_algorithm_e { eea0, eea1, eea2 };
 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;
 
 
@@ -175,3 +180,7 @@ typedef struct pdcp_lte_info
 /* 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);
+
+