summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-wireguard.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-wireguard.c')
-rw-r--r--epan/dissectors/packet-wireguard.c353
1 files changed, 177 insertions, 176 deletions
diff --git a/epan/dissectors/packet-wireguard.c b/epan/dissectors/packet-wireguard.c
index ff4e09ee..43abb62e 100644
--- a/epan/dissectors/packet-wireguard.c
+++ b/epan/dissectors/packet-wireguard.c
@@ -30,51 +30,52 @@
#include <wsutil/wsgcrypt.h>
#include <wsutil/curve25519.h>
#include <wsutil/wslog.h>
+#include <wsutil/array.h>
#include <epan/secrets.h>
#include <wiretap/secrets-types.h>
void proto_reg_handoff_wg(void);
void proto_register_wg(void);
-static int proto_wg = -1;
-static int hf_wg_type = -1;
-static int hf_wg_reserved = -1;
-static int hf_wg_sender = -1;
-static int hf_wg_ephemeral = -1;
-static int hf_wg_encrypted_static = -1;
-static int hf_wg_static = -1;
-static int hf_wg_encrypted_timestamp = -1;
-static int hf_wg_timestamp_tai64_label = -1;
-static int hf_wg_timestamp_nanoseconds = -1;
-static int hf_wg_timestamp_value = -1;
-static int hf_wg_mac1 = -1;
-static int hf_wg_mac2 = -1;
-static int hf_wg_receiver = -1;
-static int hf_wg_encrypted_empty = -1;
-static int hf_wg_handshake_ok = -1;
-static int hf_wg_nonce = -1;
-static int hf_wg_encrypted_cookie = -1;
-static int hf_wg_counter = -1;
-static int hf_wg_encrypted_packet = -1;
-static int hf_wg_stream = -1;
-static int hf_wg_response_in = -1;
-static int hf_wg_response_to = -1;
-static int hf_wg_receiver_pubkey = -1;
-static int hf_wg_receiver_pubkey_known_privkey = -1;
-static int hf_wg_ephemeral_known_privkey = -1;
-static int hf_wg_static_known_pubkey = -1;
-static int hf_wg_static_known_privkey = -1;
-
-static gint ett_wg = -1;
-static gint ett_timestamp = -1;
-static gint ett_key_info = -1;
-
-static expert_field ei_wg_bad_packet_length = EI_INIT;
-static expert_field ei_wg_keepalive = EI_INIT;
-static expert_field ei_wg_decryption_error = EI_INIT;
-static expert_field ei_wg_decryption_unsupported = EI_INIT;
-
-static gboolean pref_dissect_packet = TRUE;
+static int proto_wg;
+static int hf_wg_type;
+static int hf_wg_reserved;
+static int hf_wg_sender;
+static int hf_wg_ephemeral;
+static int hf_wg_encrypted_static;
+static int hf_wg_static;
+static int hf_wg_encrypted_timestamp;
+static int hf_wg_timestamp_tai64_label;
+static int hf_wg_timestamp_nanoseconds;
+static int hf_wg_timestamp_value;
+static int hf_wg_mac1;
+static int hf_wg_mac2;
+static int hf_wg_receiver;
+static int hf_wg_encrypted_empty;
+static int hf_wg_handshake_ok;
+static int hf_wg_nonce;
+static int hf_wg_encrypted_cookie;
+static int hf_wg_counter;
+static int hf_wg_encrypted_packet;
+static int hf_wg_stream;
+static int hf_wg_response_in;
+static int hf_wg_response_to;
+static int hf_wg_receiver_pubkey;
+static int hf_wg_receiver_pubkey_known_privkey;
+static int hf_wg_ephemeral_known_privkey;
+static int hf_wg_static_known_pubkey;
+static int hf_wg_static_known_privkey;
+
+static int ett_wg;
+static int ett_timestamp;
+static int ett_key_info;
+
+static expert_field ei_wg_bad_packet_length;
+static expert_field ei_wg_keepalive;
+static expert_field ei_wg_decryption_error;
+static expert_field ei_wg_decryption_unsupported;
+
+static bool pref_dissect_packet = true;
static const char *pref_keylog_file;
static dissector_handle_t ip_handle;
@@ -106,7 +107,7 @@ static const value_string wg_type_names[] = {
*/
typedef struct {
#define WG_KEY_LEN 32
- guchar data[WG_KEY_LEN];
+ unsigned char data[WG_KEY_LEN];
} wg_qqword;
/*
@@ -146,7 +147,7 @@ typedef struct wg_ekey {
* Maps the public key to the "wg_skey_t" structure.
* Keys are populated from the UAT and key log file.
*/
-static GHashTable *wg_static_keys = NULL;
+static GHashTable *wg_static_keys;
/*
* Set of ephemeral keys (for decryption). Maps the public key to the
@@ -193,12 +194,12 @@ static const value_string wg_key_uat_type_vals[] = {
};
typedef struct {
- guint key_type; /* See "wg_key_uat_type_vals". */
+ unsigned key_type; /* See "wg_key_uat_type_vals". */
char *key;
} wg_key_uat_record_t;
static wg_key_uat_record_t *wg_key_records;
-static guint num_wg_key_records;
+static unsigned num_wg_key_records;
/*
* Input keying material for key derivation/decryption during the handshake.
@@ -211,7 +212,7 @@ static guint num_wg_key_records;
typedef struct {
const wg_skey_t *initiator_skey; /* Spub_i based on Initiation.static (decrypted, null if decryption failed) */
const wg_skey_t *responder_skey; /* Spub_r based on Initiation.MAC1 (+Spriv_r if available) */
- guint8 timestamp[12]; /* Initiation.timestamp (decrypted) */
+ uint8_t timestamp[12]; /* Initiation.timestamp (decrypted) */
bool timestamp_ok : 1; /* Whether the timestamp was successfully decrypted */
bool empty_ok : 1; /* Whether the empty field was successfully decrypted */
@@ -239,8 +240,8 @@ static wg_qqword hash_of_c_identifier;
typedef struct {
address initiator_address;
address responder_address;
- guint16 initiator_port;
- guint16 responder_port;
+ uint16_t initiator_port;
+ uint16_t responder_port;
} wg_initial_info_t;
/*
@@ -252,9 +253,9 @@ typedef struct {
* XXX record timestamps (time since last message, for validating timers).
*/
typedef struct {
- guint32 stream; /* Session identifier (akin to udp.stream). */
- guint32 initiator_frame;
- guint32 response_frame; /* Responder or Cookie Reply message. */
+ uint32_t stream; /* Session identifier (akin to udp.stream). */
+ uint32_t initiator_frame;
+ uint32_t response_frame; /* Responder or Cookie Reply message. */
wg_initial_info_t initial; /* Valid only on the first pass. */
wg_handshake_state_t *hs; /* Handshake state to enable decryption. */
} wg_session_t;
@@ -262,12 +263,12 @@ typedef struct {
/* Per-packet state. */
typedef struct {
wg_session_t *session;
- gboolean receiver_is_initiator; /* Whether this transport data packet is sent to an Initiator. */
+ bool receiver_is_initiator; /* Whether this transport data packet is sent to an Initiator. */
} wg_packet_info_t;
/* Map from Sender/Receiver IDs to a list of session information. */
static wmem_map_t *sessions;
-static guint32 wg_session_count;
+static uint32_t wg_session_count;
/* Key conversion routines. {{{ */
@@ -282,7 +283,7 @@ set_private_key(wg_qqword *privkey, const wg_qqword *inkey)
}
/* Whether a private key is initialized (see set_private_key). */
-static inline gboolean
+static inline bool
has_private_key(const wg_qqword *secret)
{
return !!(secret->data[31] & 64);
@@ -317,33 +318,33 @@ dh_x25519(wg_qqword *shared_secret, const wg_qqword *priv, const wg_qqword *pub)
static const char *
pubkey_to_string(const wg_qqword *pubkey)
{
- gchar *str = g_base64_encode(pubkey->data, WG_KEY_LEN);
- gchar *ret = wmem_strdup(wmem_packet_scope(), str);
+ char *str = g_base64_encode(pubkey->data, WG_KEY_LEN);
+ char *ret = wmem_strdup(wmem_packet_scope(), str);
g_free(str);
return ret;
}
-static gboolean
+static bool
decode_base64_key(wg_qqword *out, const char *str)
{
- gsize out_len;
- gchar tmp[45];
+ size_t out_len;
+ char tmp[45];
if (strlen(str) + 1 != sizeof(tmp)) {
- return FALSE;
+ return false;
}
memcpy(tmp, str, sizeof(tmp));
g_base64_decode_inplace(tmp, &out_len);
if (out_len != WG_KEY_LEN) {
- return FALSE;
+ return false;
}
memcpy(out->data, tmp, WG_KEY_LEN);
- return TRUE;
+ return true;
}
/* Key conversion routines. }}} */
static gboolean
-wg_pubkey_equal(gconstpointer v1, gconstpointer v2)
+wg_pubkey_equal(const void *v1, const void *v2)
{
const wg_qqword *pubkey1 = (const wg_qqword *)v1;
const wg_qqword *pubkey2 = (const wg_qqword *)v2;
@@ -360,7 +361,7 @@ wg_mac1_key(const wg_qqword *static_public, wg_qqword *mac_key_out)
{
gcry_md_hd_t hd;
if (gcry_md_open(&hd, GCRY_MD_BLAKE2S_256, 0) == 0) {
- const char wg_label_mac1[] = "mac1----";
+ static const char wg_label_mac1[] = "mac1----";
gcry_md_write(hd, wg_label_mac1, strlen(wg_label_mac1));
gcry_md_write(hd, static_public->data, sizeof(wg_qqword));
memcpy(mac_key_out->data, gcry_md_read(hd, 0), sizeof(wg_qqword));
@@ -374,11 +375,11 @@ wg_mac1_key(const wg_qqword *static_public, wg_qqword *mac_key_out)
/*
* Verify that MAC(mac_key, data) matches "mac_output".
*/
-static gboolean
+static bool
wg_mac_verify(const wg_qqword *mac_key,
- const guchar *data, guint data_len, const guint8 mac_output[16])
+ const unsigned char *data, unsigned data_len, const uint8_t mac_output[16])
{
- gboolean ok = FALSE;
+ bool ok = false;
gcry_md_hd_t hd;
if (gcry_md_open(&hd, GCRY_MD_BLAKE2S_128, 0) == 0) {
gcry_error_t r;
@@ -415,9 +416,9 @@ wg_mix_hash(wg_qqword *h, const void *data, size_t data_len)
* Computes KDF_n(key, input) where n is the number of derived keys.
*/
static void
-wg_kdf(const wg_qqword *key, const guint8 *input, guint input_len, guint n, wg_qqword *out)
+wg_kdf(const wg_qqword *key, const uint8_t *input, unsigned input_len, unsigned n, wg_qqword *out)
{
- guint8 prk[32]; /* Blake2s_256 hash output. */
+ uint8_t prk[32]; /* Blake2s_256 hash output. */
gcry_error_t err;
err = hkdf_extract(GCRY_MD_BLAKE2S_256, key->data, sizeof(wg_qqword), input, input_len, prk);
DISSECTOR_ASSERT(err == 0);
@@ -428,13 +429,13 @@ wg_kdf(const wg_qqword *key, const guint8 *input, guint input_len, guint n, wg_q
/*
* Must be called before attempting decryption.
*/
-static gboolean
+static bool
wg_decrypt_init(void)
{
if (gcry_md_test_algo(GCRY_MD_BLAKE2S_128) != 0 ||
gcry_md_test_algo(GCRY_MD_BLAKE2S_256) != 0 ||
gcry_cipher_test_algo(GCRY_CIPHER_CHACHA20) != 0) {
- return FALSE;
+ return false;
}
static const char construction[] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
gcry_md_hash_buffer(GCRY_MD_BLAKE2S_256, hash_of_construction.data, construction, strlen(construction));
@@ -442,7 +443,7 @@ wg_decrypt_init(void)
static const char wg_identifier[] = "WireGuard v1 zx2c4 Jason@zx2c4.com";
memcpy(&hash_of_c_identifier, hash_of_construction.data, sizeof(wg_qqword));
wg_mix_hash(&hash_of_c_identifier, wg_identifier, strlen(wg_identifier));
- return TRUE;
+ return true;
}
static gcry_cipher_hd_t
@@ -473,22 +474,22 @@ wg_handshake_state_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t e
gcry_cipher_close(hs->responder_recv_cipher);
hs->responder_recv_cipher = NULL;
}
- return FALSE;
+ return false;
}
/*
* Decrypt ciphertext using the ChaCha20-Poly1305 cipher. The auth tag must be
* included with the ciphertext.
*/
-static gboolean
-wg_aead_decrypt(gcry_cipher_hd_t hd, guint64 counter, const guchar *ctext, guint ctext_len, const guchar *aad, guint aad_len, guchar *out, guint out_len)
+static bool
+wg_aead_decrypt(gcry_cipher_hd_t hd, uint64_t counter, const unsigned char *ctext, unsigned ctext_len, const unsigned char *aad, unsigned aad_len, unsigned char *out, unsigned out_len)
{
DISSECTOR_ASSERT(ctext_len >= AUTH_TAG_LENGTH);
ctext_len -= AUTH_TAG_LENGTH;
- const guchar *auth_tag = ctext + ctext_len;
+ const unsigned char *auth_tag = ctext + ctext_len;
counter = GUINT64_TO_LE(counter);
- guchar nonce[12] = { 0 };
+ unsigned char nonce[12] = { 0 };
memcpy(nonce + 4, &counter, 8);
return gcry_cipher_setiv(hd, nonce, sizeof(nonce)) == 0 &&
@@ -501,14 +502,14 @@ wg_aead_decrypt(gcry_cipher_hd_t hd, guint64 counter, const guchar *ctext, guint
* Decrypt ciphertext using the ChaCha20-Poly1305 cipher. The auth tag must be
* included with the ciphertext.
*/
-static gboolean
-aead_decrypt(const wg_qqword *key, guint64 counter, const guchar *ctext, guint ctext_len, const guchar *aad, guint aad_len, guchar *out, guint out_len)
+static bool
+aead_decrypt(const wg_qqword *key, uint64_t counter, const unsigned char *ctext, unsigned ctext_len, const unsigned char *aad, unsigned aad_len, unsigned char *out, unsigned out_len)
{
DISSECTOR_ASSERT(ctext_len >= AUTH_TAG_LENGTH);
gcry_cipher_hd_t hd = wg_create_cipher(key);
DISSECTOR_ASSERT(hd);
- gboolean ok = wg_aead_decrypt(hd, counter, ctext, ctext_len, aad, aad_len, out, out_len);
+ bool ok = wg_aead_decrypt(hd, counter, ctext, ctext_len, aad, aad_len, out, out_len);
gcry_cipher_close(hd);
return ok;
}
@@ -518,7 +519,7 @@ aead_decrypt(const wg_qqword *key, guint64 counter, const guchar *ctext, guint c
* Add a static public or private key to "wg_static_keys".
*/
static void
-wg_add_static_key(const wg_qqword *tmp_key, gboolean is_private)
+wg_add_static_key(const wg_qqword *tmp_key, bool is_private)
{
if (!wg_decryption_supported) {
return;
@@ -582,10 +583,10 @@ wg_add_psk(wg_ekey_t *ekey, const wg_qqword *psk)
}
/*
- * Retrieves the next PSK to try and returns TRUE if one is found or FALSE if
+ * Retrieves the next PSK to try and returns true if one is found or false if
* there are no more to try.
*/
-static gboolean
+static bool
wg_psk_iter_next(wg_psk_iter_context *psk_iter, const wg_handshake_state_t *hs,
wg_qqword *psk_out)
{
@@ -607,15 +608,15 @@ wg_psk_iter_next(wg_psk_iter_context *psk_iter, const wg_handshake_state_t *hs,
case WG_PSK_ITER_STATE_RESPONDER:
memset(psk_out->data, 0, WG_KEY_LEN);
psk_iter->state = WG_PSK_ITER_STATE_EXIT;
- return TRUE;
+ return true;
case WG_PSK_ITER_STATE_EXIT:
- return FALSE;
+ return false;
}
}
*psk_out = psk->psk_data;
psk_iter->next_psk = psk->next;
- return TRUE;
+ return true;
}
/* PSK handling. }}} */
@@ -631,7 +632,7 @@ wg_keylog_reset(void)
}
}
-static void wg_keylog_process_lines(const void *data, guint datalen);
+static void wg_keylog_process_lines(const void *data, unsigned datalen);
static void
wg_keylog_read(void)
@@ -683,12 +684,12 @@ wg_keylog_read(void)
break;
}
- wg_keylog_process_lines((const guint8 *)buf, (guint)strlen(buf));
+ wg_keylog_process_lines((const uint8_t *)buf, (unsigned)strlen(buf));
}
}
static void
-wg_keylog_process_lines(const void *data, guint datalen)
+wg_keylog_process_lines(const void *data, unsigned datalen)
{
const char *next_line = (const char *)data;
const char *line_end = next_line + datalen;
@@ -696,13 +697,13 @@ wg_keylog_process_lines(const void *data, guint datalen)
/* Note: line is NOT nul-terminated. */
const char *line = next_line;
next_line = (const char *)memchr(line, '\n', line_end - line);
- gssize linelen;
+ ssize_t linelen;
if (next_line) {
linelen = next_line - line;
next_line++; /* drop LF */
} else {
- linelen = (gssize)(line_end - line);
+ linelen = (ssize_t)(line_end - line);
}
if (linelen > 0 && line[linelen - 1] == '\r') {
linelen--; /* drop CR */
@@ -721,7 +722,7 @@ wg_keylog_process_lines(const void *data, guint datalen)
p = (const char *)memchr(p0, '=', line_end - p);
if (p && p0 != p) {
/* Extract "key-type" from "key-type = key-value" */
- gsize key_type_len = p - p0;
+ size_t key_type_len = p - p0;
while (key_type_len && p0[key_type_len - 1] == ' ') {
--key_type_len;
}
@@ -734,7 +735,7 @@ wg_keylog_process_lines(const void *data, guint datalen)
while (p < line_end && *p == ' ') {
++p;
}
- gsize key_value_len = (line + linelen) - p;
+ size_t key_value_len = (line + linelen) - p;
if (key_value_len && key_value_len < sizeof(key_value)) {
memcpy(key_value, p, key_value_len);
}
@@ -748,9 +749,9 @@ wg_keylog_process_lines(const void *data, guint datalen)
}
if (!strcmp(key_type, "LOCAL_STATIC_PRIVATE_KEY")) {
- wg_add_static_key(&key, TRUE);
+ wg_add_static_key(&key, true);
} else if (!strcmp(key_type, "REMOTE_STATIC_PUBLIC_KEY")) {
- wg_add_static_key(&key, FALSE);
+ wg_add_static_key(&key, false);
} else if (!strcmp(key_type, "LOCAL_EPHEMERAL_PRIVATE_KEY")) {
wg_keylog_last_ekey = wg_add_ephemeral_privkey(&key);
} else if (!strcmp(key_type, "PRESHARED_KEY")) {
@@ -788,10 +789,10 @@ wg_key_uat_record_update_cb(void *r, char **error)
/* Check for valid base64-encoding. */
if (!decode_base64_key(&key, rec->key)) {
*error = g_strdup("Invalid key");
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void
@@ -821,12 +822,12 @@ wg_key_uat_apply(void)
wg_keylog_reset();
/* Convert base64-encoded strings to wg_skey_t and derive pubkey. */
- for (guint i = 0; i < num_wg_key_records; i++) {
+ for (unsigned i = 0; i < num_wg_key_records; i++) {
wg_key_uat_record_t *rec = &wg_key_records[i];
wg_qqword tmp_key; /* Either public or private, not sure yet. */
/* Populate public (and private) keys. */
- gboolean decoded = decode_base64_key(&tmp_key, rec->key);
+ bool decoded = decode_base64_key(&tmp_key, rec->key);
DISSECTOR_ASSERT(decoded);
wg_add_static_key(&tmp_key, rec->key_type == WG_KEY_UAT_PRIVATE);
}
@@ -842,7 +843,7 @@ wg_key_uat_reset(void)
}
}
-UAT_VS_DEF(wg_key_uat, key_type, wg_key_uat_record_t, guint, WG_KEY_UAT_PUBLIC, "Public")
+UAT_VS_DEF(wg_key_uat, key_type, wg_key_uat_record_t, unsigned, WG_KEY_UAT_PUBLIC, "Public")
UAT_CSTRING_CB_DEF(wg_key_uat, key, wg_key_uat_record_t)
/* UAT and key configuration. }}} */
@@ -858,8 +859,8 @@ wg_process_initiation(tvbuff_t *tvb, wg_handshake_state_t *hs)
DISSECTOR_ASSERT(hs->initiator_skey == NULL);
wg_qqword decrypted_static = {{ 0 }};
- const gboolean has_Spriv_r = has_private_key(&hs->responder_skey->priv_key);
- const gboolean has_Epriv_i = has_private_key(&hs->initiator_ekey->priv_key);
+ const bool has_Spriv_r = has_private_key(&hs->responder_skey->priv_key);
+ const bool has_Epriv_i = has_private_key(&hs->initiator_ekey->priv_key);
// Either Spriv_r or Epriv_i + Spriv_i are needed. If the first two are not
// available, fail early. Spriv_i will be looked up later.
@@ -869,9 +870,9 @@ wg_process_initiation(tvbuff_t *tvb, wg_handshake_state_t *hs)
const wg_qqword *ephemeral = (const wg_qqword *)tvb_get_ptr(tvb, 8, WG_KEY_LEN);
#define WG_ENCRYPTED_STATIC_LENGTH (32 + AUTH_TAG_LENGTH)
- const guint8 *encrypted_static = (const guint8 *)tvb_get_ptr(tvb, 40, WG_ENCRYPTED_STATIC_LENGTH);
+ const uint8_t *encrypted_static = (const uint8_t *)tvb_get_ptr(tvb, 40, WG_ENCRYPTED_STATIC_LENGTH);
#define WG_ENCRYPTED_TIMESTAMP_LENGTH (12 + AUTH_TAG_LENGTH)
- const guint8 *encrypted_timestamp = (const guint8 *)tvb_get_ptr(tvb, 88, WG_ENCRYPTED_TIMESTAMP_LENGTH);
+ const uint8_t *encrypted_timestamp = (const uint8_t *)tvb_get_ptr(tvb, 88, WG_ENCRYPTED_TIMESTAMP_LENGTH);
wg_qqword c_and_k[2], h;
wg_qqword *c = &c_and_k[0], *k = &c_and_k[1];
@@ -927,7 +928,7 @@ wg_process_initiation(tvbuff_t *tvb, wg_handshake_state_t *hs)
if (!aead_decrypt(k, 0, encrypted_timestamp, WG_ENCRYPTED_TIMESTAMP_LENGTH, h.data, sizeof(wg_qqword), hs->timestamp, sizeof(hs->timestamp))) {
return;
}
- hs->timestamp_ok = TRUE;
+ hs->timestamp_ok = true;
// h = Hash(h || msg.timestamp)
wg_mix_hash(&h, encrypted_timestamp, WG_ENCRYPTED_TIMESTAMP_LENGTH);
@@ -952,9 +953,9 @@ wg_process_response(tvbuff_t *tvb, wg_handshake_state_t *hs)
DISSECTOR_ASSERT(!hs->initiator_recv_cipher);
DISSECTOR_ASSERT(!hs->responder_recv_cipher);
- const gboolean has_Epriv_i = has_private_key(&hs->initiator_ekey->priv_key);
- const gboolean has_Spriv_i = has_private_key(&hs->initiator_skey->priv_key);
- const gboolean has_Epriv_r = has_private_key(&hs->responder_ekey->priv_key);
+ const bool has_Epriv_i = has_private_key(&hs->initiator_ekey->priv_key);
+ const bool has_Spriv_i = has_private_key(&hs->initiator_skey->priv_key);
+ const bool has_Epriv_r = has_private_key(&hs->responder_ekey->priv_key);
// Either Epriv_i + Spriv_i or Epriv_r + Epub_i + Spub_i are required.
if (!(has_Epriv_i && has_Spriv_i) && !has_Epriv_r) {
@@ -962,7 +963,7 @@ wg_process_response(tvbuff_t *tvb, wg_handshake_state_t *hs)
}
const wg_qqword *ephemeral = (const wg_qqword *)tvb_get_ptr(tvb, 12, WG_KEY_LEN);
- const guint8 *encrypted_empty = (const guint8 *)tvb_get_ptr(tvb, 44, AUTH_TAG_LENGTH);
+ const uint8_t *encrypted_empty = (const uint8_t *)tvb_get_ptr(tvb, 44, AUTH_TAG_LENGTH);
wg_qqword ctk[3], h;
wg_qqword *c = &ctk[0], *t = &ctk[1], *k = &ctk[2];
@@ -1007,7 +1008,7 @@ wg_process_response(tvbuff_t *tvb, wg_handshake_state_t *hs)
*c = c_before_psk;
continue;
}
- hs->empty_ok = TRUE;
+ hs->empty_ok = true;
break;
}
if (!hs->empty_ok) {
@@ -1027,7 +1028,7 @@ wg_process_response(tvbuff_t *tvb, wg_handshake_state_t *hs)
static void
-wg_sessions_insert(guint32 id, wg_session_t *session)
+wg_sessions_insert(uint32_t id, wg_session_t *session)
{
wmem_list_t *list = (wmem_list_t *)wmem_map_lookup(sessions, GUINT_TO_POINTER(id));
if (!list) {
@@ -1047,25 +1048,25 @@ wg_session_new(void)
/* Updates the peer address based on the source address. */
static void
-wg_session_update_address(wg_session_t *session, packet_info *pinfo, gboolean sender_is_initiator)
+wg_session_update_address(wg_session_t *session, packet_info *pinfo, bool sender_is_initiator)
{
DISSECTOR_ASSERT(!PINFO_FD_VISITED(pinfo));
if (sender_is_initiator) {
copy_address_wmem(wmem_file_scope(), &session->initial.initiator_address, &pinfo->src);
- session->initial.initiator_port = (guint16)pinfo->srcport;
+ session->initial.initiator_port = (uint16_t)pinfo->srcport;
} else {
copy_address_wmem(wmem_file_scope(), &session->initial.responder_address, &pinfo->src);
- session->initial.responder_port = (guint16)pinfo->srcport;
+ session->initial.responder_port = (uint16_t)pinfo->srcport;
}
}
/* Finds an initiation message based on the given Receiver ID that was not
* previously associated with a responder message. Returns the session if a
- * matching initation message can be found or NULL otherwise.
+ * matching initiation message can be found or NULL otherwise.
*/
static wg_session_t *
-wg_sessions_lookup_initiation(packet_info *pinfo, guint32 receiver_id)
+wg_sessions_lookup_initiation(packet_info *pinfo, uint32_t receiver_id)
{
DISSECTOR_ASSERT(!PINFO_FD_VISITED(pinfo));
@@ -1102,7 +1103,7 @@ wg_sessions_lookup_initiation(packet_info *pinfo, guint32 receiver_id)
/* Finds a session with a completed handshake that matches the Receiver ID. */
static wg_session_t *
-wg_sessions_lookup(packet_info *pinfo, guint32 receiver_id, gboolean *receiver_is_initiator)
+wg_sessions_lookup(packet_info *pinfo, uint32_t receiver_id, bool *receiver_is_initiator)
{
DISSECTOR_ASSERT(!PINFO_FD_VISITED(pinfo));
@@ -1120,10 +1121,10 @@ wg_sessions_lookup(packet_info *pinfo, guint32 receiver_id, gboolean *receiver_i
}
if (session->initial.initiator_port == pinfo->destport &&
addresses_equal(&session->initial.initiator_address, &pinfo->dst)) {
- *receiver_is_initiator = TRUE;
+ *receiver_is_initiator = true;
} else if (session->initial.responder_port == pinfo->destport &&
addresses_equal(&session->initial.responder_address, &pinfo->dst)) {
- *receiver_is_initiator = FALSE;
+ *receiver_is_initiator = false;
} else {
/* Both peers do not match the destination, ignore. */
continue;
@@ -1140,7 +1141,7 @@ wg_sessions_lookup(packet_info *pinfo, guint32 receiver_id, gboolean *receiver_i
* TODO on PINFO_FD_VISITED, reuse previously discovered keys from session?
*/
static const wg_skey_t *
-wg_mac1_key_probe(tvbuff_t *tvb, gboolean is_initiation)
+wg_mac1_key_probe(tvbuff_t *tvb, bool is_initiation)
{
const int mac1_offset = is_initiation ? 116 : 60;
@@ -1149,19 +1150,19 @@ wg_mac1_key_probe(tvbuff_t *tvb, gboolean is_initiation)
return NULL;
}
- guint8 *mac1_msgdata = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0, mac1_offset);
- const guint8 *mac1_output = tvb_get_ptr(tvb, mac1_offset, 16);
+ uint8_t *mac1_msgdata = (uint8_t *)tvb_memdup(wmem_packet_scope(), tvb, 0, mac1_offset);
+ const uint8_t *mac1_output = tvb_get_ptr(tvb, mac1_offset, 16);
// MAC1 is computed over a message with three reserved bytes set to zero.
mac1_msgdata[1] = mac1_msgdata[2] = mac1_msgdata[3] = 0;
// Find public key that matches the 16-byte MAC1 field.
GHashTableIter iter;
- gpointer value;
+ void *value;
g_hash_table_iter_init(&iter, wg_static_keys);
while (g_hash_table_iter_next(&iter, NULL, &value)) {
const wg_skey_t *skey = (wg_skey_t *)value;
- if (wg_mac_verify(&skey->mac1_key, mac1_msgdata, (guint)mac1_offset, mac1_output)) {
+ if (wg_mac_verify(&skey->mac1_key, mac1_msgdata, (unsigned)mac1_offset, mac1_output)) {
return skey;
}
}
@@ -1177,7 +1178,7 @@ static wg_handshake_state_t *
wg_prepare_handshake_keys(const wg_skey_t *skey_r, tvbuff_t *tvb)
{
wg_handshake_state_t *hs;
- gboolean has_r_keys = skey_r && has_private_key(&skey_r->priv_key);
+ bool has_r_keys = skey_r && has_private_key(&skey_r->priv_key);
wg_ekey_t *ekey_i = (wg_ekey_t *)wmem_map_lookup(wg_ephemeral_keys, tvb_get_ptr(tvb, 8, WG_KEY_LEN));
// If neither private keys are available, do not create a session.
@@ -1217,25 +1218,25 @@ wg_prepare_handshake_responder_keys(wg_handshake_state_t *hs, tvbuff_t *tvb)
/* Converts a TAI64 label to the seconds since the Unix epoch.
* See https://cr.yp.to/libtai/tai64.html */
-static gboolean tai64n_to_unix(guint64 tai64_label, guint32 nanoseconds, nstime_t *nstime)
+static bool tai64n_to_unix(uint64_t tai64_label, uint32_t nanoseconds, nstime_t *nstime)
{
- const guint64 pow2_62 = 1ULL << 62;
+ const uint64_t pow2_62 = 1ULL << 62;
if (tai64_label < pow2_62 || tai64_label >= (1ULL << 63) || nanoseconds > 999999999) {
// Seconds before 1970 and values larger than 2^63 (reserved) cannot
// be represented. Nanoseconds must also be valid.
- return FALSE;
+ return false;
}
// TODO this can result in loss of precision
nstime->secs = (time_t)(tai64_label - pow2_62);
nstime->nsecs = (int)nanoseconds;
- return TRUE;
+ return true;
}
static void
-wg_dissect_key_extra(proto_tree *tree, tvbuff_t *tvb, const wg_qqword *pubkey, gboolean is_ephemeral)
+wg_dissect_key_extra(proto_tree *tree, tvbuff_t *tvb, const wg_qqword *pubkey, bool is_ephemeral)
{
- guint32 has_private = FALSE;
+ uint32_t has_private = false;
proto_item *ti;
if (is_ephemeral) {
@@ -1255,11 +1256,11 @@ wg_dissect_key_extra(proto_tree *tree, tvbuff_t *tvb, const wg_qqword *pubkey, g
static void
-wg_dissect_pubkey(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_ephemeral)
+wg_dissect_pubkey(proto_tree *tree, tvbuff_t *tvb, int offset, bool is_ephemeral)
{
- const guint8 *pubkey = tvb_get_ptr(tvb, offset, 32);
- gchar *str = g_base64_encode(pubkey, 32);
- gchar *key_str = wmem_strdup(wmem_packet_scope(), str);
+ const uint8_t *pubkey = tvb_get_ptr(tvb, offset, 32);
+ char *str = g_base64_encode(pubkey, 32);
+ char *key_str = wmem_strdup(wmem_packet_scope(), str);
g_free(str);
int hf_id = is_ephemeral ? hf_wg_ephemeral : hf_wg_static;
@@ -1283,14 +1284,14 @@ wg_dissect_decrypted_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tr
new_tvb = tvb_new_child_real_data(tvb, hs->initiator_skey->pub_key.data, WG_KEY_LEN, WG_KEY_LEN);
add_new_data_source(pinfo, new_tvb, "Decrypted Static");
- wg_dissect_pubkey(wg_tree, new_tvb, 0, FALSE);
+ wg_dissect_pubkey(wg_tree, new_tvb, 0, false);
}
static void
wg_dissect_decrypted_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, wg_handshake_state_t *hs)
{
- guint64 tai64_label;
- guint32 nanoseconds;
+ uint64_t tai64_label;
+ uint32_t nanoseconds;
nstime_t nstime;
proto_item *ti;
tvbuff_t *new_tvb;
@@ -1302,8 +1303,8 @@ wg_dissect_decrypted_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
new_tvb = tvb_new_child_real_data(tvb, hs->timestamp, sizeof(hs->timestamp), sizeof(hs->timestamp));
add_new_data_source(pinfo, new_tvb, "Decrypted Timestamp");
- tai64_label = tvb_get_guint64(new_tvb, 0, ENC_BIG_ENDIAN);
- nanoseconds = tvb_get_guint32(new_tvb, 8, ENC_BIG_ENDIAN);
+ tai64_label = tvb_get_uint64(new_tvb, 0, ENC_BIG_ENDIAN);
+ nanoseconds = tvb_get_uint32(new_tvb, 8, ENC_BIG_ENDIAN);
if (tai64n_to_unix(tai64_label, nanoseconds, &nstime)) {
ti = proto_tree_add_time(tree, hf_wg_timestamp_value, new_tvb, 0, 12, &nstime);
tree = proto_item_add_subtree(ti, ett_timestamp);
@@ -1313,7 +1314,7 @@ wg_dissect_decrypted_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
}
static void
-wg_dissect_decrypted_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo, guint64 counter, gint plain_length)
+wg_dissect_decrypted_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo, uint64_t counter, int plain_length)
{
wg_handshake_state_t *hs = wg_pinfo->session->hs;
gcry_cipher_hd_t cipher = wg_pinfo->receiver_is_initiator ? hs->initiator_recv_cipher : hs->responder_recv_cipher;
@@ -1322,10 +1323,10 @@ wg_dissect_decrypted_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tr
}
DISSECTOR_ASSERT(plain_length >= 0);
- const gint ctext_len = plain_length + AUTH_TAG_LENGTH;
- const guchar *ctext = tvb_get_ptr(tvb, 16, ctext_len);
- guchar *plain = (guchar *)wmem_alloc0(pinfo->pool, (guint)plain_length);
- if (!wg_aead_decrypt(cipher, counter, ctext, (guint)ctext_len, NULL, 0, plain, (guint)plain_length)) {
+ const int ctext_len = plain_length + AUTH_TAG_LENGTH;
+ const unsigned char *ctext = tvb_get_ptr(tvb, 16, ctext_len);
+ unsigned char *plain = (unsigned char *)wmem_alloc0(pinfo->pool, (unsigned)plain_length);
+ if (!wg_aead_decrypt(cipher, counter, ctext, (unsigned)ctext_len, NULL, 0, plain, (unsigned)plain_length)) {
proto_tree_add_expert(wg_tree, pinfo, &ei_wg_decryption_error, tvb, 16, ctext_len);
return;
}
@@ -1333,7 +1334,7 @@ wg_dissect_decrypted_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tr
return;
}
- tvbuff_t *new_tvb = tvb_new_child_real_data(tvb, plain, (guint)plain_length, plain_length);
+ tvbuff_t *new_tvb = tvb_new_child_real_data(tvb, plain, (unsigned)plain_length, plain_length);
add_new_data_source(pinfo, new_tvb, "Decrypted Packet");
proto_tree *tree = proto_item_get_parent(wg_tree);
@@ -1364,11 +1365,11 @@ wg_dissect_mac1_pubkey(proto_tree *tree, tvbuff_t *tvb, const wg_skey_t *skey)
static int
wg_dissect_handshake_initiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo)
{
- guint32 sender_id;
+ uint32_t sender_id;
proto_item *ti;
wg_keylog_read();
- const wg_skey_t *skey_r = wg_mac1_key_probe(tvb, TRUE);
+ const wg_skey_t *skey_r = wg_mac1_key_probe(tvb, true);
wg_handshake_state_t *hs = NULL;
if (!PINFO_FD_VISITED(pinfo)) {
@@ -1384,7 +1385,7 @@ wg_dissect_handshake_initiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *w
proto_tree_add_item_ret_uint(wg_tree, hf_wg_sender, tvb, 4, 4, ENC_LITTLE_ENDIAN, &sender_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", sender=0x%08X", sender_id);
- wg_dissect_pubkey(wg_tree, tvb, 8, TRUE);
+ wg_dissect_pubkey(wg_tree, tvb, 8, true);
proto_tree_add_item(wg_tree, hf_wg_encrypted_static, tvb, 40, 32 + AUTH_TAG_LENGTH, ENC_NA);
wg_dissect_decrypted_static(tvb, pinfo, wg_tree, hs);
proto_tree_add_item(wg_tree, hf_wg_encrypted_timestamp, tvb, 88, 12 + AUTH_TAG_LENGTH, ENC_NA);
@@ -1398,7 +1399,7 @@ wg_dissect_handshake_initiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *w
* considered part of the same "session"? */
wg_session_t *session = wg_session_new();
session->initiator_frame = pinfo->num;
- wg_session_update_address(session, pinfo, TRUE);
+ wg_session_update_address(session, pinfo, true);
session->hs = hs;
wg_sessions_insert(sender_id, session);
wg_pinfo->session = session;
@@ -1419,12 +1420,12 @@ wg_dissect_handshake_initiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *w
static int
wg_dissect_handshake_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo)
{
- guint32 sender_id, receiver_id;
+ uint32_t sender_id, receiver_id;
proto_item *ti;
wg_session_t *session;
wg_keylog_read();
- const wg_skey_t *skey_i = wg_mac1_key_probe(tvb, FALSE);
+ const wg_skey_t *skey_i = wg_mac1_key_probe(tvb, false);
proto_tree_add_item_ret_uint(wg_tree, hf_wg_sender, tvb, 4, 4, ENC_LITTLE_ENDIAN, &sender_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", sender=0x%08X", sender_id);
@@ -1441,7 +1442,7 @@ wg_dissect_handshake_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_
session = wg_pinfo ? wg_pinfo->session : NULL;
}
- wg_dissect_pubkey(wg_tree, tvb, 12, TRUE);
+ wg_dissect_pubkey(wg_tree, tvb, 12, true);
proto_tree_add_item(wg_tree, hf_wg_encrypted_empty, tvb, 44, 16, ENC_NA);
if (session && session->hs) {
ti = proto_tree_add_boolean(wg_tree, hf_wg_handshake_ok, tvb, 0, 0, !!session->hs->empty_ok);
@@ -1456,7 +1457,7 @@ wg_dissect_handshake_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_
* and somehow mark that this response is related but not correct. */
if (session) {
session->response_frame = pinfo->num;
- wg_session_update_address(session, pinfo, FALSE);
+ wg_session_update_address(session, pinfo, false);
wg_sessions_insert(sender_id, session);
wg_pinfo->session = session;
}
@@ -1474,7 +1475,7 @@ wg_dissect_handshake_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_
static int
wg_dissect_handshake_cookie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo)
{
- guint32 receiver_id;
+ uint32_t receiver_id;
proto_item *ti;
proto_tree_add_item_ret_uint(wg_tree, hf_wg_receiver, tvb, 4, 4, ENC_LITTLE_ENDIAN, &receiver_id);
@@ -1488,7 +1489,7 @@ wg_dissect_handshake_cookie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tr
session = wg_sessions_lookup_initiation(pinfo, receiver_id);
if (session) {
session->response_frame = pinfo->num;
- wg_session_update_address(session, pinfo, FALSE);
+ wg_session_update_address(session, pinfo, false);
wg_pinfo->session = session;
}
/* XXX check for cookie reply from Initiator to Responder */
@@ -1509,8 +1510,8 @@ wg_dissect_handshake_cookie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tr
static int
wg_dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packet_info_t *wg_pinfo)
{
- guint32 receiver_id;
- guint64 counter;
+ uint32_t receiver_id;
+ uint64_t counter;
proto_item *ti;
proto_tree_add_item_ret_uint(wg_tree, hf_wg_receiver, tvb, 4, 4, ENC_LITTLE_ENDIAN, &receiver_id);
@@ -1518,7 +1519,7 @@ wg_dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packe
proto_tree_add_item_ret_uint64(wg_tree, hf_wg_counter, tvb, 8, 8, ENC_LITTLE_ENDIAN, &counter);
col_append_fstr(pinfo->cinfo, COL_INFO, ", counter=%" PRIu64, counter);
- gint packet_length = tvb_captured_length_remaining(tvb, 16);
+ int packet_length = tvb_captured_length_remaining(tvb, 16);
if (packet_length < AUTH_TAG_LENGTH) {
proto_tree_add_expert(wg_tree, pinfo, &ei_wg_bad_packet_length, tvb, 16, packet_length);
return 16 + packet_length;
@@ -1534,7 +1535,7 @@ wg_dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packe
wg_session_t *session;
if (!PINFO_FD_VISITED(pinfo)) {
- gboolean receiver_is_initiator;
+ bool receiver_is_initiator;
session = wg_sessions_lookup(pinfo, receiver_id, &receiver_is_initiator);
if (session) {
wg_session_update_address(session, pinfo, !receiver_is_initiator);
@@ -1556,8 +1557,8 @@ wg_dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *wg_tree, wg_packe
return 16 + packet_length;
}
-static gboolean
-wg_is_valid_message_length(guint8 message_type, guint length)
+static bool
+wg_is_valid_message_length(uint8_t message_type, unsigned length)
{
switch (message_type) {
case WG_TYPE_HANDSHAKE_INITIATION:
@@ -1569,7 +1570,7 @@ wg_is_valid_message_length(guint8 message_type, guint length)
case WG_TYPE_TRANSPORT_DATA:
return length >= 32;
default:
- return FALSE;
+ return false;
}
}
@@ -1578,11 +1579,11 @@ dissect_wg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_item *ti;
proto_tree *wg_tree;
- guint32 message_type;
+ uint32_t message_type;
const char *message_type_str;
wg_packet_info_t *wg_pinfo;
- message_type = tvb_get_guint8(tvb, 0);
+ message_type = tvb_get_uint8(tvb, 0);
message_type_str = try_val_to_str(message_type, wg_type_names);
if (!message_type_str)
return 0;
@@ -1633,8 +1634,8 @@ dissect_wg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
DISSECTOR_ASSERT_NOT_REACHED();
}
-static gboolean
-dissect_wg_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+static bool
+dissect_wg_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
/*
* Heuristics to detect the WireGuard protocol:
@@ -1646,24 +1647,24 @@ dissect_wg_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
* purposes, so this condition is not checked here for most messages.
* It is checked for data messages to avoid false positives.
*/
- guint32 message_type;
- gboolean reserved_is_zeroes;
+ uint32_t message_type;
+ bool reserved_is_zeroes;
if (tvb_reported_length(tvb) < 4)
- return FALSE;
+ return false;
- message_type = tvb_get_guint8(tvb, 0);
+ message_type = tvb_get_uint8(tvb, 0);
reserved_is_zeroes = tvb_get_ntoh24(tvb, 1) == 0;
if (!wg_is_valid_message_length(message_type, tvb_reported_length(tvb))) {
- return FALSE;
+ return false;
}
switch (message_type) {
case WG_TYPE_COOKIE_REPLY:
case WG_TYPE_TRANSPORT_DATA:
if (!reserved_is_zeroes)
- return FALSE;
+ return false;
break;
}
@@ -1680,8 +1681,8 @@ dissect_wg_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
conversation_set_dissector(conversation, wg_handle);
}
- dissect_wg(tvb, pinfo, tree, NULL);
- return TRUE;
+ dissect_wg(tvb, pinfo, tree, data);
+ return true;
}
static void
@@ -1846,7 +1847,7 @@ proto_register_wg(void)
},
};
- static gint *ett[] = {
+ static int *ett[] = {
&ett_wg,
&ett_timestamp,
&ett_key_info,
@@ -1893,7 +1894,7 @@ proto_register_wg(void)
uat_t *wg_keys_uat = uat_new("WireGuard static keys",
sizeof(wg_key_uat_record_t),
"wg_keys", /* filename */
- TRUE, /* from_profile */
+ true, /* from_profile */
&wg_key_records, /* data_ptr */
&num_wg_key_records, /* numitems_ptr */
UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
@@ -1920,7 +1921,7 @@ proto_register_wg(void)
"\"<key-type> = <base64-encoded-key>\" (without quotes, leading spaces and spaces around '=' are ignored).\n"
"<key-type> is one of: LOCAL_STATIC_PRIVATE_KEY, REMOTE_STATIC_PUBLIC_KEY, "
"LOCAL_EPHEMERAL_PRIVATE_KEY or PRESHARED_KEY.",
- &pref_keylog_file, FALSE);
+ &pref_keylog_file, false);
wg_decryption_supported = wg_decrypt_init();
/* We require libgcrypt 1.8.0, so if the algorithms aren't supported