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