diff options
author | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2014-01-06 18:18:04 +0000 |
---|---|---|
committer | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2014-01-06 18:18:04 +0000 |
commit | f026d8a8076c24f42192c1540b0e348a8292f3fc (patch) | |
tree | 1be35f1b077ee745345ec8b4760a94399c7c0e33 | |
parent | 7bf44dcd97c60ae359b11ca91ef45868869c3831 (diff) |
Call deciphering and integrity checking appropriately for
SecurityModeCommand and SecurityModeResponse.
Also show when integrity has been checked and found to be correct.
svn path=/trunk/; revision=54620
-rw-r--r-- | epan/dissectors/packet-pdcp-lte.c | 34 | ||||
-rw-r--r-- | epan/dissectors/packet-pdcp-lte.h | 2 |
2 files changed, 30 insertions, 6 deletions
diff --git a/epan/dissectors/packet-pdcp-lte.c b/epan/dissectors/packet-pdcp-lte.c index 6e799d6dcb..80c21fef66 100644 --- a/epan/dissectors/packet-pdcp-lte.c +++ b/epan/dissectors/packet-pdcp-lte.c @@ -1322,19 +1322,32 @@ static gboolean dissect_pdcp_lte_heur(tvbuff_t *tvb, packet_info *pinfo, /* Called from control protocol to configure security algorithms for the given UE */ void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_security_info_t *security_info) { + /* Use for this frame so can check integrity on SecurityCommandRequest frame */ + /* 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; /* And add into security table */ g_hash_table_insert(pdcp_security_hash, GUINT_TO_POINTER((guint)ueid), p_security); + + /* 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; + g_hash_table_insert(pdcp_security_result_hash, + get_ueid_frame_hash_key(ueid, security_info->configuration_frame, TRUE), + p_frame_security); } #if HAVE_LIBGCRYPT /* 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, - enum pdcp_plane plane, gboolean *deciphered) + enum pdcp_plane plane, gboolean will_be_deciphered, + gboolean *deciphered) { unsigned char ctr_block[16]; gcry_cipher_hd_t cypher_hd; @@ -1359,6 +1372,11 @@ static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset return tvb; } + /* Don't decipher if not yet past SecurityModeResponse */ + if (!will_be_deciphered) { + return tvb; + } + /* Set CTR */ memset(ctr_block, 0, 16); /* Only first 5 bytes set */ @@ -1419,7 +1437,8 @@ static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo, int *offset #else static tvbuff_t *decipher_payload(tvbuff_t *tvb, packet_info *pinfo _U_, int *offset _U_, pdu_security_settings_t *pdu_security_settings _U_, - enum pdcp_plane plane _U_, gboolean *deciphered _U_) + enum pdcp_plane plane _U_, gboolean will_be_deciphered _U_, + gboolean *deciphered _U_) { return tvb; } @@ -1608,10 +1627,11 @@ static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree if (!pinfo->fd->flags.visited) { /* Look up current state by UEID */ current_security = (pdcp_security_info_t*)g_hash_table_lookup(pdcp_security_hash, - GUINT_TO_POINTER((guint)p_pdcp_info->ueid)); + GUINT_TO_POINTER((guint)p_pdcp_info->ueid)); if (current_security != NULL) { /* Store any result for this frame in the result table */ pdcp_security_info_t *security_to_store = wmem_new(wmem_file_scope(), pdcp_security_info_t); + /* Take a deep copy of the settings */ *security_to_store = *current_security; g_hash_table_insert(pdcp_security_result_hash, get_ueid_frame_hash_key(p_pdcp_info->ueid, pinfo->fd->num, TRUE), @@ -1887,7 +1907,8 @@ static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree /* Check pdu_security_settings - may need to do deciphering before calling further dissectors on payload */ - payload_tvb = decipher_payload(tvb, pinfo, &offset, &pdu_security_settings, p_pdcp_info->plane, &payload_deciphered); + payload_tvb = decipher_payload(tvb, pinfo, &offset, &pdu_security_settings, p_pdcp_info->plane, + pdu_security ? pdu_security->seen_next_ul_pdu: FALSE, &payload_deciphered); if (p_pdcp_info->plane == SIGNALING_PLANE) { guint32 data_length; @@ -1903,7 +1924,7 @@ static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree } /* RRC data is all but last 4 bytes. - Call lte-rrc dissector (according to direction and channel type) */ + Call lte-rrc dissector (according to direction and channel type) if we have valid data */ if ((global_pdcp_dissect_signalling_plane_as_rrc) && ((pdu_security == NULL) || (pdu_security->ciphering == 0) || payload_deciphered || !pdu_security->seen_next_ul_pdu)){ /* Get appropriate dissector handle */ @@ -1960,6 +1981,9 @@ static void dissect_pdcp_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree "MAC-I Digest wrong expected %08x but found %08x", calculated_digest, mac); } + else { + proto_item_append_text(mac_ti, " [Matches calculated result]"); + } } col_append_fstr(pinfo->cinfo, COL_INFO, " MAC=0x%08x (%u bytes data)", diff --git a/epan/dissectors/packet-pdcp-lte.h b/epan/dissectors/packet-pdcp-lte.h index ed4f3b1d1b..b10cdda65b 100644 --- a/epan/dissectors/packet-pdcp-lte.h +++ b/epan/dissectors/packet-pdcp-lte.h @@ -60,7 +60,7 @@ enum security_ciphering_algorithm_e { eea0, eea1, eea2 }; typedef struct pdcp_security_info_t { guint32 configuration_frame; - gboolean seen_next_ul_pdu; + gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */ enum security_integrity_algorithm_e integrity; enum security_ciphering_algorithm_e ciphering; } pdcp_security_info_t; |