summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-rf4ce-secur.h
blob: 84735bc8e5969ade6282be7320a088892c582cc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
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 */