Wireshark 5.1.0
The Wireshark network protocol analyzer
Loading...
Searching...
No Matches
mka_ca_stat.h
1/* mka_ca_stat.h
2 * MKA (MACsec Key Agreement) Connectivity Association analysis engine.
3 * Shared by the tshark "-z mka,ca" tap and the Qt MKA CA dialog.
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <[email protected]>
7 * Copyright 1998 Gerald Combs
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12#ifndef __MKA_CA_STAT_H__
13#define __MKA_CA_STAT_H__
14
15#include <glib.h>
16#include <wsutil/nstime.h>
17#include "epan/dissectors/packet-mka.h"
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23#define MKA_CA_MI_LEN 12U
24#define MKA_CA_CKN_LEN 32U
25#define MKA_CA_KI_LEN 16U
26#define MKA_CA_SCI_LEN 8U
27
28/* Classification of a key-formation episode. */
29typedef enum {
30 MKA_FORM_STARTUP, /* key server distributed the first SAK */
31 MKA_FORM_REKEY, /* new SAK with no new peer or key server change */
32 MKA_FORM_NEW_PEER, /* a new/reset peer triggered key distribution */
33 MKA_FORM_KS_CHANGE /* a new or restarted key server distributed the SAK */
34} mka_form_kind_t;
35
36/* One expected peer within a formation episode. */
37typedef struct mka_form_peer_s {
38 uint8_t sci[MKA_CA_SCI_LEN];
39
40 uint8_t mi[MKA_CA_MI_LEN]; /* peer MI at episode trigger time */
41 bool have_mi;
42 bool is_new; /* first formation this peer appears in */
43
44 nstime_t activated; /* first time transmitting with this SAK */
45 bool has_activated;
46 uint32_t activated_frame;
47
48 nstime_t installed; /* first time receiving with this SAK (rx set) */
49 bool has_installed;
50 uint32_t installed_frame;
51
52 nstime_t latest_slot; /* first time this SAK was in the latest slot */
53 bool has_latest_slot;
54
55 nstime_t demoted; /* first time this SAK appears in the old slot */
56 bool has_demoted;
57
58 uint32_t demoted_frame;
59} mka_form_peer_t;
60
61/* A key-formation episode. */
62typedef struct mka_form_s {
63 mka_form_kind_t kind;
64
65 uint8_t ki[MKA_CA_KI_LEN];
66 bool have_ki;
67
68 uint8_t an;
69 uint32_t kn;
70
71 uint32_t trigger_frame;
72 uint32_t end_frame; /* last peer activation/demotion frame */
73 nstime_t trigger_time;
74
75 GHashTable *peers; /* key: SCI -> mka_form_peer_t* */
76
77 bool superseded;
78
79 uint8_t ks_sci[MKA_CA_SCI_LEN];
80 uint8_t ks_mi[MKA_CA_MI_LEN]; /* distributing key server MI */
81
82 uint8_t sak[MKA_MAX_SAK_LEN]; /* unwrapped SAK (if the KEK was known) */
83 unsigned sak_len; /* 0 if the SAK was not unwrapped */
84} mka_form_t;
85
86/* One observed key server identity (SCI + server MI). */
87typedef struct mka_ks_s {
88 uint8_t sci[MKA_CA_SCI_LEN];
89 uint8_t mi[MKA_CA_MI_LEN];
90
91 uint32_t first_frame;
92 uint32_t last_frame;
93 nstime_t first_time;
94} mka_ks_t;
95
96/* One observed MI for a peer SCI, with its first and most recent appearance. */
97typedef struct mka_ca_mi_s {
98 uint8_t mi[MKA_CA_MI_LEN];
99
100 nstime_t first_seen;
101 nstime_t last_seen;
102 uint32_t first_frame;
103 uint32_t last_frame;
104} mka_ca_mi_t;
105
106/* Per-peer state within a CA, keyed by SCI. */
107typedef struct mka_ca_peer_s {
108 uint8_t sci[MKA_CA_SCI_LEN];
109
110 uint8_t mi[MKA_CA_MI_LEN]; /* most recent MI for this SCI */
111 GPtrArray *mis; /* mka_ca_mi_t*, all MIs seen, in order */
112
113 bool key_server;
114 nstime_t last_heard;
115 uint32_t last_frame;
116
117 bool has_sak_use;
118 uint8_t latest_an;
119 bool latest_tx;
120 bool latest_rx;
121 uint8_t latest_ki[MKA_CA_KI_LEN];
122 bool latest_ki_valid;
123
124 uint8_t old_an;
125 bool old_tx;
126 bool old_rx;
127 uint8_t old_ki[MKA_CA_KI_LEN];
128 bool old_ki_valid;
129
130 /* This participant has reported an active (non-zero) key at some point.
131 * For a key server, false before its first key means a fresh startup. */
132 bool had_active_key;
133
134 GPtrArray *live_peers; /* of uint8_t[MKA_CA_MI_LEN] */
135 GPtrArray *potential_peers; /* of uint8_t[MKA_CA_MI_LEN] */
136} mka_ca_peer_t;
137
138/* Per-CA state keyed by the known CKN info pointer. */
139typedef struct mka_ca_s {
140 const mka_ckn_info_t *ckn_info; /* NULL if the CKN is not in the table */
141 uint8_t ckn[MKA_CA_CKN_LEN]; /* raw CKN bytes (CA identity) */
142 unsigned ckn_len;
143 GHashTable *peers; /* key: SCI -> mka_ca_peer_t* */
144 GHashTable *mi_to_sci; /* key: MI -> uint8_t[8] SCI */
145 GPtrArray *forms; /* of mka_form_t* in chronological order */
146 GPtrArray *key_servers; /* of mka_ks_t* in order first seen */
147
148 bool pending_new_peer;
149
150 /* Formation trigger tracking. A formation begins when the key server
151 * responds to recent peer engagement (a non-key-server peer MKPDU,
152 * especially a new/reset MI). ks_response_frame is the key server's first
153 * announcement after the most recent peer engagement; it is used as the
154 * startup / key server change trigger. */
155 uint32_t ks_response_frame;
156 nstime_t ks_response_time;
157 uint8_t ks_response_mi[MKA_CA_MI_LEN];
158 bool have_ks_response;
159
160 /* a peer MKPDU seen since the last KS response */
161 bool peer_engaged;
162
163 /* Key server change trigger: the first announcement of a different key
164 * server SCI (a different device taking over the key server role). */
165 uint32_t ks_change_frame;
166 nstime_t ks_change_time;
167 uint8_t ks_change_sci[MKA_CA_SCI_LEN];
168 bool have_ks_change;
169 uint8_t last_ks_sci[MKA_CA_SCI_LEN];
170 bool have_last_ks_sci;
171
172 /* Startup origin: set when the first MKPDU in the CA is a key server
173 * announcement (the key server initiated, with no prior peer or key server
174 * activity). That frame is the startup trigger. */
175 uint32_t ks_origin_frame;
176 nstime_t ks_origin_time;
177 bool have_ks_origin;
178
179 bool seen_any_mkpdu;
180 bool any_peer_seen;
181 /* A participant reported an active SAK before any distribution was
182 * captured: the group pre-existed, so the first distribution is a rekey. */
183 bool pre_existing_sak;
184 /* The distributing key server was seen announcing with no key of its own:
185 * it started the group from scratch, so the first distribution is startup. */
186 bool ks_fresh_start;
187 /* Frame of the previous SAK distribution, to tell whether a peer engaged
188 * since then (fresh new-peer) versus a stale earlier engagement. */
189 uint32_t last_dist_frame;
190 bool have_last_dist;
191} mka_ca_t;
192
193/* Opaque analysis state. */
194typedef struct mka_ca_stat_s {
195 GHashTable *cas; /* key: ckn_info ptr -> mka_ca_t* */
196 nstime_t start_time; /* earliest MKPDU time seen (capture start) */
197 bool have_start;
198} mka_ca_stat_t;
199
200/* Allocate an empty analysis state. */
201mka_ca_stat_t *mka_ca_stat_new(void);
202
203/* Free an analysis state and all contained data. */
204void mka_ca_stat_free(mka_ca_stat_t *st);
205
206/* Discard all accumulated data, keeping the state usable. */
207void mka_ca_stat_reset(mka_ca_stat_t *st);
208
209/* Fold one MKA CA tap record into the analysis state. */
210void mka_ca_stat_process(mka_ca_stat_t *st, const mka_ca_tap_t *tap);
211
212/* Resolve a peer MI to its SCI within a CA, or NULL if unknown. */
213const uint8_t *mka_ca_lookup_sci(const mka_ca_t *ca, const uint8_t *mi);
214
215/* Key number from a Key Identifier (its trailing 4 bytes, big-endian). */
216uint32_t mka_ki_kn(const uint8_t *ki);
217
218/* Human-readable name for a formation episode kind. */
219const char *mka_form_kind_str(mka_form_kind_t kind);
220
221/* Longest per-peer activation time for an episode, in seconds; negative if
222 * no peer has activated. Sets *all_activated to whether every expected peer
223 * activated, and *num_activated / *num_total to the counts. */
224double mka_form_time(const mka_form_t *form, bool *all_activated, unsigned *num_activated, unsigned *num_total);
225
226#ifdef __cplusplus
227}
228#endif
229
230#endif /* __MKA_CA_STAT_H__ */
Definition mka_ca_stat.h:97
Definition mka_ca_stat.h:107
Definition mka_ca_stat.h:139
Definition mka_ca_stat.h:194
Definition mka_ca_stat.h:37
Definition mka_ca_stat.h:62
Definition mka_ca_stat.h:87
Definition nstime.h:26