summaryrefslogtreecommitdiff
path: root/src/libs/mynewt-nimble/nimble/host/src/ble_sm_priv.h
blob: 27e75aa1d9115859a77b890ba2524f7bdfb838ce (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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#ifndef H_BLE_SM_PRIV_
#define H_BLE_SM_PRIV_

#include <inttypes.h>
#include "syscfg/syscfg.h"
#include "os/queue.h"
#include "nimble/nimble_opt.h"

#ifdef __cplusplus
extern "C" {
#endif

struct ble_gap_sec_state;
struct hci_le_lt_key_req;
struct hci_encrypt_change;

#define BLE_SM_MTU                  65

#define BLE_SM_OP_PAIR_REQ                      0x01
#define BLE_SM_OP_PAIR_RSP                      0x02
#define BLE_SM_OP_PAIR_CONFIRM                  0x03
#define BLE_SM_OP_PAIR_RANDOM                   0x04
#define BLE_SM_OP_PAIR_FAIL                     0x05
#define BLE_SM_OP_ENC_INFO                      0x06
#define BLE_SM_OP_MASTER_ID                     0x07
#define BLE_SM_OP_IDENTITY_INFO                 0x08
#define BLE_SM_OP_IDENTITY_ADDR_INFO            0x09
#define BLE_SM_OP_SIGN_INFO                     0x0a
#define BLE_SM_OP_SEC_REQ                       0x0b
#define BLE_SM_OP_PAIR_PUBLIC_KEY               0x0c
#define BLE_SM_OP_PAIR_DHKEY_CHECK              0x0d
#define BLE_SM_OP_PAIR_KEYPRESS_NOTIFY          0x0e

struct ble_sm_hdr {
    uint8_t opcode;
    uint8_t data[0];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x01/0x02 [req/rsp])         | 1                 |
 * | IO Capability                      | 1                 |
 * | OOB data flag                      | 1                 |
 * | AuthReq                            | 1                 |
 * | Maximum Encryption Key Size        | 1                 |
 * | Initiator Key Distribution         | 1                 |
 * | Responder Key Distribution         | 1                 |
 */

struct ble_sm_pair_cmd {
    uint8_t io_cap;
    uint8_t oob_data_flag;
    uint8_t authreq;
    uint8_t max_enc_key_size;
    uint8_t init_key_dist;
    uint8_t resp_key_dist;
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x03)                        | 1                 |
 * | Confirm Value                      | 16                |
 */

struct ble_sm_pair_confirm {
    uint8_t value[16];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x04)                        | 1                 |
 * | Random Value                       | 16                |
 */
struct ble_sm_pair_random {
    uint8_t value[16];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x05)                        | 1                 |
 * | Reason                             | 1                 |
 */
struct ble_sm_pair_fail {
    uint8_t reason;
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x06)                        | 1                 |
 * | ltk                                | 16                |
 */
struct ble_sm_enc_info {
    uint8_t ltk[16];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x07)                        | 1                 |
 * | EDIV                               | 2                 |
 * | RAND                               | 8                 |
 */
struct ble_sm_master_id {
    uint16_t ediv;
    uint64_t rand_val;
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x08)                        | 1                 |
 * | irk                                | 16                |
 */
struct ble_sm_id_info {
    uint8_t irk[16];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x09)                        | 1                 |
 * | addr_type                          | 1                 |
 * | address                            | 6                 |
 */
struct ble_sm_id_addr_info {
    uint8_t addr_type;
    uint8_t bd_addr[6];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x0A)                        | 1                 |
 * | csrk                               | 16                |
 */
struct ble_sm_sign_info {
    uint8_t sig_key[16];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x0B)                        | 1                 |
 * | authreq                            | 1                 |
 */
struct ble_sm_sec_req {
    uint8_t authreq;
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x0c)                        | 1                 |
 * | Public Key X                       | 32                |
 * | Public Key Y                       | 32                |
 */
struct ble_sm_public_key {
    uint8_t x[32];
    uint8_t y[32];
} __attribute__((packed));

/**
 * | Parameter                          | Size (octets)     |
 * +------------------------------------+-------------------+
 * | (Code=0x0d)                        | 1                 |
 * | DHKey Check                        | 16                |
 */
struct ble_sm_dhkey_check {
    uint8_t value[16];
} __attribute__((packed));

#if NIMBLE_BLE_SM

#define BLE_SM_PROC_STATE_NONE              ((uint8_t)-1)

#define BLE_SM_PROC_STATE_PAIR              0
#define BLE_SM_PROC_STATE_CONFIRM           1
#define BLE_SM_PROC_STATE_RANDOM            2
#define BLE_SM_PROC_STATE_LTK_START         3
#define BLE_SM_PROC_STATE_LTK_RESTORE       4
#define BLE_SM_PROC_STATE_ENC_START         5
#define BLE_SM_PROC_STATE_ENC_RESTORE       6
#define BLE_SM_PROC_STATE_KEY_EXCH          7
#define BLE_SM_PROC_STATE_SEC_REQ           8
#define BLE_SM_PROC_STATE_PUBLIC_KEY        9
#define BLE_SM_PROC_STATE_DHKEY_CHECK       10
#define BLE_SM_PROC_STATE_CNT               11

#define BLE_SM_PROC_F_INITIATOR             0x01
#define BLE_SM_PROC_F_IO_INJECTED           0x02
#define BLE_SM_PROC_F_ADVANCE_ON_IO         0x04
#define BLE_SM_PROC_F_AUTHENTICATED         0x08
#define BLE_SM_PROC_F_SC                    0x10
#define BLE_SM_PROC_F_BONDING               0x20

#define BLE_SM_KE_F_ENC_INFO                0x01
#define BLE_SM_KE_F_MASTER_ID               0x02
#define BLE_SM_KE_F_ID_INFO                 0x04
#define BLE_SM_KE_F_ADDR_INFO               0x08
#define BLE_SM_KE_F_SIGN_INFO               0x10

typedef uint8_t ble_sm_proc_flags;

struct ble_sm_keys {
    unsigned ltk_valid:1;
    unsigned ediv_rand_valid:1;
    unsigned irk_valid:1;
    unsigned csrk_valid:1;
    unsigned addr_valid:1;
    uint16_t ediv;
    uint64_t rand_val;
    uint8_t addr_type;
    uint8_t key_size;
    uint8_t ltk[16];    /* Little endian. */
    uint8_t irk[16];    /* Little endian. */
    uint8_t csrk[16];   /* Little endian. */
    uint8_t addr[6];    /* Little endian. */
};

struct ble_sm_proc {
    STAILQ_ENTRY(ble_sm_proc) next;

    ble_npl_time_t exp_os_ticks;
    ble_sm_proc_flags flags;
    uint16_t conn_handle;
    uint8_t pair_alg;
    uint8_t state;
    uint8_t rx_key_flags;
    uint8_t key_size;

    uint8_t pair_req[sizeof(struct ble_sm_hdr) + sizeof(struct ble_sm_pair_cmd)];
    uint8_t pair_rsp[sizeof(struct ble_sm_hdr) + sizeof(struct ble_sm_pair_cmd)];
    uint8_t tk[16];
    uint8_t confirm_peer[16];
    uint8_t randm[16];
    uint8_t rands[16];
    uint8_t ltk[16]; /* Little endian. */
    struct ble_sm_keys our_keys;
    struct ble_sm_keys peer_keys;

#if MYNEWT_VAL(BLE_SM_SC)
    /* Secure connections. */
    uint8_t passkey_bits_exchanged;
    uint8_t ri;
    struct ble_sm_public_key pub_key_peer;
    uint8_t mackey[16];
    uint8_t dhkey[32];
    const struct ble_sm_sc_oob_data *oob_data_local;
    const struct ble_sm_sc_oob_data *oob_data_remote;
#endif
};

struct ble_sm_result {
    int app_status;
    uint8_t sm_err;
    struct ble_gap_passkey_params passkey_params;
    void *state_arg;
    unsigned execute : 1;
    unsigned enc_cb : 1;
    unsigned bonded : 1;
    unsigned restore : 1;
};

#if MYNEWT_VAL(BLE_HS_DEBUG)
void ble_sm_dbg_set_next_pair_rand(uint8_t *next_pair_rand);
void ble_sm_dbg_set_next_ediv(uint16_t next_ediv);
void ble_sm_dbg_set_next_master_id_rand(uint64_t next_master_id_rand);
void ble_sm_dbg_set_next_ltk(uint8_t *next_ltk);
void ble_sm_dbg_set_next_csrk(uint8_t *next_csrk);
void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey);
#endif

int ble_sm_num_procs(void);

int ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2,
                  uint8_t *out);
int ble_sm_alg_c1(const uint8_t *k, const uint8_t *r,
                  const uint8_t *preq, const uint8_t *pres,
                  uint8_t iat, uint8_t rat,
                  const uint8_t *ia, const uint8_t *ra,
                  uint8_t *out_enc_data);
int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x,
                  uint8_t z, uint8_t *out_enc_data);
int ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x,
                  const uint8_t *y, uint32_t *passkey);
int ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2,
                  uint8_t a1t, const uint8_t *a1, uint8_t a2t,
                  const uint8_t *a2, uint8_t *mackey, uint8_t *ltk);
int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2,
                  const uint8_t *r, const uint8_t *iocap, uint8_t a1t,
                  const uint8_t *a1, uint8_t a2t, const uint8_t *a2,
                  uint8_t *check);
int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x,
                         const uint8_t *peer_pub_key_y,
                         const uint8_t *our_priv_key, uint8_t *out_dhkey);
int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv);
void ble_sm_alg_ecc_init(void);

void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev);
void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev);
int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev);

#if MYNEWT_VAL(BLE_SM_LEGACY)
int ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action);
void ble_sm_lgcy_confirm_exec(struct ble_sm_proc *proc,
                              struct ble_sm_result *res);
void ble_sm_lgcy_random_exec(struct ble_sm_proc *proc,
                             struct ble_sm_result *res);
void ble_sm_lgcy_random_rx(struct ble_sm_proc *proc,
                           struct ble_sm_result *res);
#else
#define ble_sm_lgcy_io_action(proc, action) (BLE_HS_ENOTSUP)
#define ble_sm_lgcy_confirm_exec(proc, res)
#define ble_sm_lgcy_random_exec(proc, res)
#define ble_sm_lgcy_random_rx(proc, res)
#endif

#if MYNEWT_VAL(BLE_SM_SC)
int ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action);
void ble_sm_sc_confirm_exec(struct ble_sm_proc *proc,
                            struct ble_sm_result *res);
void ble_sm_sc_random_exec(struct ble_sm_proc *proc,
                           struct ble_sm_result *res);
void ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res);
void ble_sm_sc_public_key_exec(struct ble_sm_proc *proc,
                               struct ble_sm_result *res,
                               void *arg);
void ble_sm_sc_public_key_rx(uint16_t conn_handle, struct os_mbuf **rxom,
                             struct ble_sm_result *res);
void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc,
                                struct ble_sm_result *res, void *arg);
void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **rxom,
                              struct ble_sm_result *res);
bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc,
                              bool oob_data_local_present,
                              bool oob_data_remote_present);
void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res);
void ble_sm_sc_init(void);
#else
#define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP)
#define ble_sm_sc_confirm_exec(proc, res)
#define ble_sm_sc_random_exec(proc, res)
#define ble_sm_sc_random_rx(proc, res)
#define ble_sm_sc_public_key_exec(proc, res, arg)
#define ble_sm_sc_public_key_rx(conn_handle, op, om, res)
#define ble_sm_sc_dhkey_check_exec(proc, res, arg)
#define ble_sm_sc_dhkey_check_rx(conn_handle, op, om, res)
#define ble_sm_sc_init()

#endif

struct ble_sm_proc *ble_sm_proc_find(uint16_t conn_handle, uint8_t state,
                                     int is_initiator,
                                     struct ble_sm_proc **out_prev);
int ble_sm_gen_pair_rand(uint8_t *pair_rand);
uint8_t *ble_sm_our_pair_rand(struct ble_sm_proc *proc);
uint8_t *ble_sm_peer_pair_rand(struct ble_sm_proc *proc);
int ble_sm_ioact_state(uint8_t action);
int ble_sm_proc_can_advance(struct ble_sm_proc *proc);
void ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res);
void ble_sm_confirm_advance(struct ble_sm_proc *proc);
void ble_sm_ia_ra(struct ble_sm_proc *proc,
                  uint8_t *out_iat, uint8_t *out_ia,
                  uint8_t *out_rat, uint8_t *out_ra);

int32_t ble_sm_timer(void);
void ble_sm_connection_broken(uint16_t conn_handle);
int ble_sm_pair_initiate(uint16_t conn_handle);
int ble_sm_slave_initiate(uint16_t conn_handle);
int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size,
                        const uint8_t *ltk, uint16_t ediv,
                        uint64_t rand_val, int auth);
int ble_sm_init(void);
#else

#define ble_sm_enc_change_rx(evt) ((void)(evt))
#define ble_sm_ltk_req_rx(evt) ((void)(evt))
#define ble_sm_enc_key_refresh_rx(evt) ((void)(evt))

#define ble_sm_timer() BLE_HS_FOREVER
#define ble_sm_connection_broken(conn_handle)
#define ble_sm_pair_initiate(conn_handle)   BLE_HS_ENOTSUP
#define ble_sm_slave_initiate(conn_handle)  BLE_HS_ENOTSUP
#define ble_sm_enc_initiate(conn_handle, keysize, ltk, ediv, rand_val, auth) \
        BLE_HS_ENOTSUP

#define ble_sm_init() 0

#endif

struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle);
void *ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom);
int ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom);

#ifdef __cplusplus
}
#endif

#endif