summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-rf4ce-secur.h
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-rf4ce-secur.h')
-rw-r--r--epan/dissectors/packet-rf4ce-secur.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rf4ce-secur.h b/epan/dissectors/packet-rf4ce-secur.h
new file mode 100644
index 00000000..84735bc8
--- /dev/null
+++ b/epan/dissectors/packet-rf4ce-secur.h
@@ -0,0 +1,216 @@
+/* packet-rf4ce-secur.h
+ * Security related functions and objects for RF4CE dissector
+ * Copyright (C) Atmosic 2023
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef PACKET_RF4CE_SECUR_H
+#define PACKET_RF4CE_SECUR_H
+
+#include <stdbool.h>
+#include "config.h"
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/uat.h>
+#include <epan/value_string.h>
+
+#define RF4CE_IEEE_ADDR_LEN 8
+#define RF4CE_SHORT_ADDR_LEN 2
+
+#define RF4CE_MIN_NWK_LENGTH 5
+#define RF4CE_MAX_NWK_LENGTH 148
+
+#define RF4CE_VENDOR_SECRET_STORAGE_SIZE 64
+#define RF4CE_NWK_KEY_STORAGE_SIZE 64
+#define RF4CE_ADDR_TABLE_SIZE (RF4CE_NWK_KEY_STORAGE_SIZE * 2)
+
+#define RF4CE_NWK_KEY_SEED_DATA_LENGTH 80
+
+#define RF4CE_CCM_M 4
+#define RF4CE_CCM_L 2
+#define RF4CE_CCM_NONCE_LEN (15 - RF4CE_CCM_L)
+#define RF4CE_SECUR_CONTROL 5
+#define SEC_STR_LEN 16
+#define KEY_LEN SEC_STR_LEN
+
+typedef struct keypair_context_s {
+ uint8_t nwk_key_seed_latest[RF4CE_NWK_KEY_SEED_DATA_LENGTH];
+ uint8_t nwk_key_seed_prev[RF4CE_NWK_KEY_SEED_DATA_LENGTH];
+ uint8_t nwk_key_seed[RF4CE_NWK_KEY_SEED_DATA_LENGTH];
+ uint8_t controller_addr[RF4CE_IEEE_ADDR_LEN];
+ uint8_t target_addr[RF4CE_IEEE_ADDR_LEN];
+ uint8_t nwk_key_exchange_transfer_expected;
+ uint8_t nwk_key_exchange_transfer_received;
+} keypair_context_t;
+
+#define RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_A_LENGTH 8
+#define RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_B_LENGTH 8
+
+#define RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_AB_LENGTH \
+ (RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_A_LENGTH \
+ + RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_B_LENGTH)
+
+#define RF4CE_PROFILE_CMD_KEY_EXCHANGE_TAG_A_LENGTH 4
+#define RF4CE_PROFILE_CMD_KEY_EXCHANGE_TAG_B_LENGTH 4
+
+#define RF4CE_KEY_EXCHANGE_CONTEXT_LENGTH 9
+#define RF4CE_KEY_EXCHANGE_LABEL_LENGTH (2 * (RF4CE_IEEE_ADDR_LEN))
+
+#define RF4CE_CMAC_ARG_2_LENGTH \
+ (RF4CE_KEY_EXCHANGE_CONTEXT_LENGTH \
+ + RF4CE_KEY_EXCHANGE_LABEL_LENGTH \
+ + KEY_LEN)
+
+/* RF4CE GDP 2.0 spec, part 7.4.2 Key generation
+ * Context shall be set to the ASCII representation of the nine character string (including a space
+ * after "RF4CE" but without quotes and without null termination) "RF4CE GDP".
+ */
+#define CONTEXT_STR "RF4CE GDP"
+#define CONTEXT_STR_LEN 9
+
+extern uint8_t DEFAULT_SECRET[SEC_STR_LEN];
+
+typedef struct key_exchange_context_s {
+ uint8_t rand_a[RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_A_LENGTH];
+ uint8_t rand_b[RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_B_LENGTH];
+ uint8_t mac_a[RF4CE_IEEE_ADDR_LEN]; /* target address */
+ uint8_t mac_b[RF4CE_IEEE_ADDR_LEN]; /* controller address */
+ bool is_proc_started;
+} key_exchange_context_t;
+
+typedef struct
+#if defined(_MSC_VER)
+# pragma pack(push, 1)
+#else
+__attribute__((__packed__))
+#endif
+rf4ce_key_dk_tag_s
+{
+ uint8_t a[RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_A_LENGTH];
+ uint8_t b[RF4CE_PROFILE_CMD_KEY_EXCHANGE_RAND_B_LENGTH];
+} rf4ce_key_dk_tag_t;
+#ifdef _MSC_VER
+# pragma pack(pop)
+#endif
+
+typedef struct
+#if defined(_MSC_VER)
+# pragma pack(push, 1)
+#else
+__attribute__((__packed__))
+#endif
+rf4ce_key_context_s
+{
+ uint8_t context[CONTEXT_STR_LEN];
+ uint8_t mac_a[RF4CE_IEEE_ADDR_LEN];
+ uint8_t mac_b[RF4CE_IEEE_ADDR_LEN];
+ uint8_t pairing_key[KEY_LEN];
+}
+rf4ce_key_context_t;
+#ifdef _MSC_VER
+# pragma pack(pop)
+#endif
+
+void rf4ce_aes_cmac(unsigned char *input, unsigned long length, unsigned char *key, unsigned char *mac_value);
+
+typedef struct addr_entry_s {
+ uint8_t ieee_addr[RF4CE_IEEE_ADDR_LEN];
+ uint16_t short_addr;
+ bool is_used;
+} addr_entry_t;
+
+typedef struct nwk_key_entry_s {
+ uint8_t nwk_key[KEY_LEN];
+ addr_entry_t *controller_addr_ent;
+ addr_entry_t *target_addr_ent;
+ bool key_from_gui;
+ bool is_used;
+ bool is_pairing_key;
+} nwk_key_entry_t;
+
+typedef struct vendor_secret_entry_s {
+ uint8_t secret[SEC_STR_LEN];
+ bool is_used;
+} vendor_secret_entry_t;
+
+typedef struct uat_security_record_s {
+ char *sec_str;
+ uint8_t type;
+ char *label;
+} uat_security_record_t;
+
+void keypair_context_init(const uint8_t *controller_ieee, const uint8_t *target_ieee, uint8_t expected_transfer_count);
+void keypair_context_update_seed(uint8_t *seed, uint8_t seed_seqn);
+
+void nwk_key_storage_add_entry(uint8_t *nwk_key, addr_entry_t *controller_addr_ent, addr_entry_t *target_addr_ent, bool key_from_gui, bool is_pairing_key);
+void nwk_key_storage_release_entry(uint8_t *nwk_key, bool key_from_gui);
+
+void rf4ce_addr_table_add_addrs(const void *ieee_addr, uint16_t short_addr);
+bool rf4ce_addr_table_get_ieee_addr(uint8_t *ieee_addr, packet_info *pinfo, bool is_src);
+addr_entry_t *rf4ce_addr_table_get_addr_entry_by_ieee(uint8_t *ieee_addr);
+
+void key_exchange_context_init(void);
+
+void key_exchange_context_start_procedure(void);
+void key_exchange_context_stop_procedure(void);
+bool key_exchange_context_is_procedure_started(void);
+
+void key_exchange_context_set_rand_a(uint8_t *rand_a);
+void key_exchange_context_set_rand_b(uint8_t *rand_b);
+
+void key_exchange_context_set_mac_a(uint8_t *mac_a);
+void key_exchange_context_set_mac_b(uint8_t *mac_b);
+
+void key_exchange_calc_key(uint32_t tag_b_pack);
+
+void vendor_secret_storage_add_entry(uint8_t *secret);
+void vendor_secret_storage_release_entry(uint8_t *secret);
+
+void rf4ce_secur_cleanup(void);
+
+typedef struct
+#if defined(_MSC_VER)
+# pragma pack(push, 1)
+#else
+__attribute__((__packed__))
+#endif
+rf4ce_secur_ccm_nonce_s
+{
+ uint8_t source_address[RF4CE_IEEE_ADDR_LEN]; /*!< Extended Source */
+ uint32_t frame_counter; /*!< Frame Counter */
+ uint8_t secur_control; /*!< Security Control Field */
+} rf4ce_secur_ccm_nonce_t;
+#ifdef _MSC_VER
+# pragma pack(pop)
+#endif
+
+typedef struct
+#if defined(_MSC_VER)
+# pragma pack(push, 1)
+#else
+__attribute__((__packed__))
+#endif
+rf4ce_secur_ccm_auth_s
+{
+ uint8_t frame_control; /*!< Security Control Field */
+ uint32_t frame_counter; /*!< Frame Counter */
+ uint8_t dest_address[RF4CE_IEEE_ADDR_LEN]; /*!< Extended Source */
+} rf4ce_secur_ccm_auth_t;
+#ifdef _MSC_VER
+# pragma pack(pop)
+#endif
+
+bool decrypt_data(
+ const uint8_t *in,
+ uint8_t *out,
+ uint16_t payload_offset,
+ uint16_t *len,
+ uint8_t src_ieee[RF4CE_IEEE_ADDR_LEN],
+ uint8_t dst_ieee[RF4CE_IEEE_ADDR_LEN]);
+
+#endif /* PACKET_RF4CE_SECUR_H */