1 /*
2 * Copyright (c) 2017 Intel Corporation
3 * Copyright (c) 2020 Lingao Meng
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROV_H_
9 #define ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROV_H_
10
11 #include "prov_bearer.h"
12
13 #define PROV_ERR_NONE 0x00
14 #define PROV_ERR_NVAL_PDU 0x01
15 #define PROV_ERR_NVAL_FMT 0x02
16 #define PROV_ERR_UNEXP_PDU 0x03
17 #define PROV_ERR_CFM_FAILED 0x04
18 #define PROV_ERR_RESOURCES 0x05
19 #define PROV_ERR_DECRYPT 0x06
20 #define PROV_ERR_UNEXP_ERR 0x07
21 #define PROV_ERR_ADDR 0x08
22 #define PROV_ERR_INVALID_DATA 0x09
23
24 #define AUTH_METHOD_NO_OOB 0x00
25 #define AUTH_METHOD_STATIC 0x01
26 #define AUTH_METHOD_OUTPUT 0x02
27 #define AUTH_METHOD_INPUT 0x03
28
29 #define OUTPUT_OOB_BLINK 0x00
30 #define OUTPUT_OOB_BEEP 0x01
31 #define OUTPUT_OOB_VIBRATE 0x02
32 #define OUTPUT_OOB_NUMBER 0x03
33 #define OUTPUT_OOB_STRING 0x04
34
35 #define INPUT_OOB_PUSH 0x00
36 #define INPUT_OOB_TWIST 0x01
37 #define INPUT_OOB_NUMBER 0x02
38 #define INPUT_OOB_STRING 0x03
39
40 #define PUB_KEY_NO_OOB 0x00
41 #define PUB_KEY_OOB 0x01
42
43 #define PROV_INVITE 0x00
44 #define PROV_CAPABILITIES 0x01
45 #define PROV_START 0x02
46 #define PROV_PUB_KEY 0x03
47 #define PROV_INPUT_COMPLETE 0x04
48 #define PROV_CONFIRM 0x05
49 #define PROV_RANDOM 0x06
50 #define PROV_DATA 0x07
51 #define PROV_COMPLETE 0x08
52 #define PROV_FAILED 0x09
53
54 #define PROV_NO_PDU 0xff
55
56 #define PDU_LEN_INVITE 1
57 #define PDU_LEN_CAPABILITIES 11
58 #define PDU_LEN_START 5
59 #define PDU_LEN_PUB_KEY 64
60 #define PDU_LEN_INPUT_COMPLETE 0
61 #define PDU_LEN_CONFIRM 32 /* Max size */
62 #define PDU_LEN_RANDOM 32 /* Max size */
63 #define PDU_LEN_DATA 33
64 #define PDU_LEN_COMPLETE 0
65 #define PDU_LEN_FAILED 1
66
67 #define PDU_OP_LEN 1
68
69 #define PROV_ALG_P256 0x00
70
71 #define PROV_IO_OOB_SIZE_MAX 8 /* in bytes */
72
73 #define PRIV_KEY_SIZE 32
74 #define PUB_KEY_SIZE PDU_LEN_PUB_KEY
75 #define DH_KEY_SIZE 32
76
77 #define PROV_BUF(name, len) \
78 NET_BUF_SIMPLE_DEFINE(name, PROV_BEARER_BUF_HEADROOM + PDU_OP_LEN + len + \
79 PROV_BEARER_BUF_TAILROOM)
80
81 #if IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)
82 #define PROV_AUTH_MAX_LEN 32
83 #else
84 #define PROV_AUTH_MAX_LEN 16
85 #endif
86
87 enum {
88 LINK_ACTIVE, /* Link has been opened */
89 WAIT_NUMBER, /* Waiting for number input from user */
90 WAIT_STRING, /* Waiting for string input from user */
91 NOTIFY_INPUT_COMPLETE, /* Notify that input has been completed. */
92 PROVISIONER, /* The link was opened as provisioner */
93 OOB_PUB_KEY, /* OOB Public key used */
94 PUB_KEY_SENT, /* Public key has been sent */
95 REMOTE_PUB_KEY, /* Remote key has been received */
96 INPUT_COMPLETE, /* Device input completed */
97 WAIT_CONFIRM, /* Wait for send confirm */
98 WAIT_AUTH, /* Wait for auth response */
99 OOB_STATIC_KEY, /* OOB Static Authentication */
100 REPROVISION, /* The link was opened as a reprovision target */
101 COMPLETE, /* The provisioning process completed. */
102
103 NUM_FLAGS,
104 };
105
106 /** Provisioning role */
107 struct bt_mesh_prov_role {
108 void (*link_opened)(void);
109
110 void (*link_closed)(enum prov_bearer_link_status status);
111
112 void (*error)(uint8_t reason);
113
114 void (*input_complete)(void);
115
116 void (*op[10])(const uint8_t *data);
117 };
118
119 struct bt_mesh_prov_link {
120 ATOMIC_DEFINE(flags, NUM_FLAGS);
121
122 const struct prov_bearer *bearer;
123 const struct bt_mesh_prov_role *role;
124
125 uint16_t addr; /* Assigned address */
126
127 uint8_t algorithm; /* Authen algorithm */
128 uint8_t oob_method; /* Authen method */
129 uint8_t oob_action; /* Authen action */
130 uint8_t oob_size; /* Authen size */
131 uint8_t auth[PROV_AUTH_MAX_LEN]; /* Authen value */
132
133 uint8_t dhkey[DH_KEY_SIZE]; /* Calculated DHKey */
134 uint8_t expect; /* Next expected PDU */
135
136 uint8_t conf[PROV_AUTH_MAX_LEN]; /* Local/Remote Confirmation */
137 uint8_t rand[PROV_AUTH_MAX_LEN]; /* Local Random */
138
139 uint8_t conf_salt[PROV_AUTH_MAX_LEN]; /* ConfirmationSalt */
140 uint8_t conf_key[PROV_AUTH_MAX_LEN]; /* ConfirmationKey */
141 /* ConfirmationInput fields: */
142 struct {
143 uint8_t invite[PDU_LEN_INVITE];
144 uint8_t capabilities[PDU_LEN_CAPABILITIES];
145 uint8_t start[PDU_LEN_START];
146 uint8_t pub_key_provisioner[PDU_LEN_PUB_KEY]; /* big-endian */
147 uint8_t pub_key_device[PDU_LEN_PUB_KEY]; /* big-endian */
148 } conf_inputs;
149 uint8_t prov_salt[16]; /* Provisioning Salt */
150 };
151
152 extern struct bt_mesh_prov_link bt_mesh_prov_link;
153 extern const struct bt_mesh_prov *bt_mesh_prov;
154
bt_mesh_prov_send(struct net_buf_simple * buf,prov_bearer_send_complete_t cb)155 static inline int bt_mesh_prov_send(struct net_buf_simple *buf,
156 prov_bearer_send_complete_t cb)
157 {
158 return bt_mesh_prov_link.bearer->send(buf, cb, NULL);
159 }
160
bt_mesh_prov_buf_init(struct net_buf_simple * buf,uint8_t type)161 static inline void bt_mesh_prov_buf_init(struct net_buf_simple *buf, uint8_t type)
162 {
163 net_buf_simple_reserve(buf, PROV_BEARER_BUF_HEADROOM);
164 net_buf_simple_add_u8(buf, type);
165 }
166
167
bt_mesh_prov_auth_size_get(void)168 static inline uint8_t bt_mesh_prov_auth_size_get(void)
169 {
170 return bt_mesh_prov_link.algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM ? 16 : 32;
171 }
172
173 int bt_mesh_prov_reset_state(void);
174
175 bool bt_mesh_prov_active(void);
176
177 int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8_t size);
178
179 int bt_mesh_pb_remote_open(struct bt_mesh_rpr_cli *cli,
180 const struct bt_mesh_rpr_node *srv, const uint8_t uuid[16],
181 uint16_t net_idx, uint16_t addr);
182
183 int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli,
184 struct bt_mesh_rpr_node *srv,
185 uint16_t addr, bool composition_change);
186
187 const struct bt_mesh_prov *bt_mesh_prov_get(void);
188
189 void bt_mesh_prov_complete(uint16_t net_idx, uint16_t addr);
190 void bt_mesh_prov_reset(void);
191
192 const struct prov_bearer_cb *bt_mesh_prov_bearer_cb_get(void);
193
194 void bt_mesh_pb_adv_recv(struct net_buf_simple *buf);
195
196 int bt_mesh_prov_init(const struct bt_mesh_prov *prov);
197
198 #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROV_H_ */
199