1 /*
2  * Copyright (C) 2018-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include <genie_provision.h>
8 #include "genie_service.h"
9 
10 #ifdef GENIE_ULTRA_PROV
11 #include <errno.h>
12 #include <tinycrypt/sha256.h>
13 #include <tinycrypt/constants.h>
14 
15 #include <net/buf.h>
16 #include "crypto.h"
17 #include "adv.h"
18 
19 #define BUF_TIMEOUT K_MSEC(400)
20 #define BT_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
21 
22 static uint8_t p_prov_data_key[32];
23 static uint8_t p_ultra_prov_devkey[32];
24 static uint8_t p_confirm[16];
25 #endif
26 
27 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_PROV)
28 #include "common/log.h"
29 
30 static struct k_timer pbadv_timeout_timer;
31 static struct k_timer prov_timeout_timer;
32 
33 static genie_provision_state_e provision_state = GENIE_PROVISION_UNPROV;
34 static uint8_t genie_uuid[GENIE_PROVISON_UUID_LEN];
35 
genie_provision_set_silent_flag(void)36 static void genie_provision_set_silent_flag(void)
37 {
38     genie_uuid[13] |= UNPROV_ADV_FEATURE1_SILENT_ADV;
39 }
40 
genie_provision_clear_silent_flag(void)41 void genie_provision_clear_silent_flag(void)
42 {
43     genie_uuid[13] &= UNPROV_ADV_FEATURE1_SILENT_UNMASK;
44 }
45 
genie_provision_set_state(genie_provision_state_e state)46 int genie_provision_set_state(genie_provision_state_e state)
47 {
48     provision_state = state;
49 
50     return 0;
51 }
52 
genie_provision_get_state(void)53 genie_provision_state_e genie_provision_get_state(void)
54 {
55     return provision_state;
56 }
57 
genie_provision_get_uuid(void)58 uint8_t *genie_provision_get_uuid(void)
59 {
60     int i = 0;
61     genie_triple_t *p_genie_triple = NULL;
62 
63     p_genie_triple = genie_triple_get();
64 
65     // all fields in uuid should be in little-endian
66     // CID: Taobao
67     genie_uuid[0] = CONFIG_MESH_VENDOR_COMPANY_ID & 0xFF;
68     genie_uuid[1] = (CONFIG_MESH_VENDOR_COMPANY_ID >> 8) & 0xFF;
69 
70     // PID
71     // Bit0~Bit3: 0001 (broadcast version)
72     // Bit4:1 (one secret pre device)
73     // Bit5: 1 (OTA support)
74     // Bit6~Bit7: 01 (00:4.0 01:4.2 10:5.0 11:>5.0)
75     genie_uuid[2] = 0x71;
76 
77     // Product ID
78     for (i = 0; i < 4; i++)
79     {
80         genie_uuid[3 + i] = (p_genie_triple->pid >> (i << 3)) & 0xFF;
81     }
82 
83     // mac addr (device name)
84     for (i = 0; i < GENIE_TRIPLE_MAC_SIZE; i++)
85     {
86         genie_uuid[7 + i] = p_genie_triple->mac[GENIE_TRIPLE_MAC_SIZE - 1 - i];
87     }
88 
89     genie_uuid[13] = UNPROV_ADV_FEATURE1_UUID_VERSION;
90 
91 #if defined(BOARD_TG7100B)
92     genie_uuid[14] = UNPROV_ADV_FEATURE2_GENIE_MESH_STACK_V1;
93 #elif defined(BOARD_PHY6220_EVB) || defined(BOARD_TG7120B_EVB)
94     genie_uuid[14] = UNPROV_ADV_FEATURE2_GENIE_MESH_STACK_V2;
95 #elif defined(BOARD_TG7121B_EVB)
96     genie_uuid[14] = UNPROV_ADV_FEATURE2_GENIE_MESH_STACK_V3;
97 #endif
98 
99 #ifdef GENIE_ULTRA_PROV
100     genie_uuid[14] |= UNPROV_ADV_FEATURE2_ULTRA_PROV_FLAG;
101     genie_uuid[14] |= UNPROV_ADV_FEATURE2_AUTH_FLAG;
102 #else
103 #ifndef GENIE_OLD_AUTH
104     genie_uuid[14] |= UNPROV_ADV_FEATURE2_AUTH_FLAG;
105 #endif
106 #endif
107 
108     BT_INFO("uuid: %s", bt_hex(genie_uuid, GENIE_PROVISON_UUID_LEN));
109 
110     return genie_uuid;
111 }
112 
genie_provision_get_saved_data(genie_provision_t * p_genie_provision)113 int genie_provision_get_saved_data(genie_provision_t *p_genie_provision)
114 {
115     genie_storage_status_e ret = GENIE_STORAGE_SUCCESS;
116 
117     if (p_genie_provision == NULL)
118     {
119         return -1;
120     }
121 
122     memset(p_genie_provision, 0, sizeof(genie_provision_t));
123 
124     ret = genie_storage_read_addr(&p_genie_provision->addr);
125     if (ret != GENIE_STORAGE_SUCCESS)
126     {
127         return ret;
128     }
129 
130     ret = genie_storage_read_seq(&p_genie_provision->seq);
131     if (ret != GENIE_STORAGE_SUCCESS)
132     {
133         return ret;
134     }
135 
136     ret = genie_storage_read_devkey(p_genie_provision->devkey);
137     if (ret != GENIE_STORAGE_SUCCESS)
138     {
139         return ret;
140     }
141 
142     ret = genie_storage_read_netkey(&p_genie_provision->netkey);
143     if (ret != GENIE_STORAGE_SUCCESS)
144     {
145         return ret;
146     }
147 
148     ret = genie_storage_read_appkey(&p_genie_provision->appkey);
149     if (ret != GENIE_STORAGE_SUCCESS)
150     {
151         return ret;
152     }
153 
154     return 0;
155 }
156 
157 #ifdef GENIE_ULTRA_PROV
ultra_prov_get_auth(const uint8_t random_hex[16],const uint8_t key[16],uint8_t cfm[16])158 void ultra_prov_get_auth(const uint8_t random_hex[16], const uint8_t key[16], uint8_t cfm[16])
159 {
160     bt_mesh_prov_conf(key, random_hex, genie_crypto_get_auth(random_hex), cfm);
161 
162     BT_DBG("cfm: %s", bt_hex(cfm, 16));
163 }
164 
_ultra_prov_send(uint8_t type,uint8_t * p_msg,uint8_t len)165 static int _ultra_prov_send(uint8_t type, uint8_t *p_msg, uint8_t len)
166 {
167     struct net_buf *buf;
168 
169     buf = bt_mesh_adv_create(0, 0, BUF_TIMEOUT);
170     if (!buf)
171     {
172         BT_ERR("Out of provisioning buffers");
173         return -ENOBUFS;
174     }
175 
176     BT_MESH_ADV(buf)->tiny_adv = 1;
177 
178     net_buf_add_be16(buf, CONFIG_MESH_VENDOR_COMPANY_ID);
179     //VID
180     net_buf_add_u8(buf, 0x0d);
181     net_buf_add_u8(buf, type);
182     net_buf_add_mem(buf, p_msg, len);
183 
184     BT_DBG("send %s", bt_hex(buf->data, buf->len));
185 
186     bt_mesh_adv_send(buf, NULL, NULL);
187     net_buf_unref(buf);
188 
189     return 0;
190 }
191 
genie_provision_ultra_prov_recv_random(uint8_t * buf)192 static void genie_provision_ultra_prov_recv_random(uint8_t *buf)
193 {
194     uint8_t tmp[48];
195     uint8_t random_a[17];
196     uint8_t random_b[17];
197     uint8_t cfm_key[32];
198 
199     int ret;
200     struct tc_sha256_state_struct sha256_ctx;
201     genie_triple_t *p_genie_triple = genie_triple_get();
202 
203     if (buf[0] != p_genie_triple->mac[4] || buf[1] != p_genie_triple->mac[5])
204     {
205         return;
206     }
207     buf += 2;
208 
209     genie_event(GENIE_EVT_SDK_MESH_PROV_START, NULL);
210 
211     memset(p_prov_data_key, 0, sizeof(p_prov_data_key));
212     memset(p_ultra_prov_devkey, 0, sizeof(p_ultra_prov_devkey));
213     memset(p_confirm, 0, sizeof(p_confirm));
214 
215     hextostring(buf, (char *)random_a, 8);
216     random_a[16] = 0;
217     hextostring(buf + 8, (char *)random_b, 8);
218     random_b[16] = 0;
219 
220     sprintf((char *)tmp, "%s%sConfirmationKey", random_a, random_b);
221 
222     BT_DBG("string %s\n", tmp);
223 
224     /* calculate the sha256 of random and
225          * fetch the top 16 bytes as confirmationKey
226          */
227     ret = tc_sha256_init(&sha256_ctx);
228     if (ret != TC_CRYPTO_SUCCESS)
229     {
230         BT_ERR("sha256 init fail\n");
231     }
232 
233     ret = tc_sha256_update(&sha256_ctx, tmp, 47);
234     if (ret != TC_CRYPTO_SUCCESS)
235     {
236         BT_ERR("sha256 udpate fail\n");
237     }
238 
239     ret = tc_sha256_final(cfm_key, &sha256_ctx);
240     if (ret != TC_CRYPTO_SUCCESS)
241     {
242         BT_ERR("sha256 final fail\n");
243     }
244     else
245     {
246         BT_DBG("cfmKey: %s", bt_hex(cfm_key, 16));
247     }
248 
249     //calc cloud cfm
250     memcpy(tmp, buf + 8, 8);
251     memcpy(tmp + 8, buf, 8);
252     ultra_prov_get_auth(tmp, cfm_key, p_confirm);
253 
254     hextostring(p_confirm, (char *)tmp, 16);
255     sprintf((char *)tmp + 32, "SessionKey");
256     BT_DBG("tmp %s\n", tmp);
257     ret = tc_sha256_init(&sha256_ctx);
258     if (ret != TC_CRYPTO_SUCCESS)
259     {
260         BT_ERR("sha256 init fail\n");
261     }
262 
263     ret = tc_sha256_update(&sha256_ctx, tmp, 42);
264     if (ret != TC_CRYPTO_SUCCESS)
265     {
266         BT_ERR("sha256 udpate fail\n");
267     }
268 
269     ret = tc_sha256_final(p_prov_data_key, &sha256_ctx);
270     if (ret != TC_CRYPTO_SUCCESS)
271     {
272         BT_ERR("sha256 final fail\n");
273     }
274     else
275     {
276         BT_DBG("provKkey: %s", bt_hex(p_prov_data_key, 22));
277     }
278 
279     //calc dev key
280     sprintf((char *)tmp + 32, "DeviceKey");
281     BT_DBG("tmp %s\n", tmp);
282     ret = tc_sha256_init(&sha256_ctx);
283     if (ret != TC_CRYPTO_SUCCESS)
284     {
285         BT_ERR("sha256 init fail\n");
286     }
287 
288     ret = tc_sha256_update(&sha256_ctx, tmp, 41);
289     if (ret != TC_CRYPTO_SUCCESS)
290     {
291         BT_ERR("sha256 udpate fail\n");
292     }
293 
294     ret = tc_sha256_final(p_ultra_prov_devkey, &sha256_ctx);
295     if (ret != TC_CRYPTO_SUCCESS)
296     {
297         BT_ERR("sha256 final fail\n");
298     }
299     else
300     {
301         BT_INFO("dk %s", bt_hex(p_ultra_prov_devkey, 16));
302     }
303 
304     memcpy(tmp, buf, 16);
305     ultra_prov_get_auth(tmp, cfm_key, p_confirm);
306 
307     tmp[0] = p_genie_triple->mac[4];
308     tmp[1] = p_genie_triple->mac[5];
309     memcpy(tmp + 2, p_confirm, 16);
310 
311     _ultra_prov_send(GENIE_PROV_STATUS_SEND_CONFIRM_DATA, tmp, 18);
312 }
313 
genie_provision_ultra_prov_recv_data(uint8_t * buf)314 static void genie_provision_ultra_prov_recv_data(uint8_t *buf)
315 {
316     uint8_t i = 0;
317     uint16_t net_idx;
318     uint8_t flags;
319     uint32_t iv_index;
320     uint16_t addr;
321     genie_triple_t *p_genie_triple = genie_triple_get();
322 
323     if (genie_provision_get_state() != GENIE_PROVISION_START)
324     {
325         BT_WARN("I not in provisioning");
326         return;
327     }
328 
329     while (i < 22)
330     {
331         buf[i] ^= p_prov_data_key[i];
332         i++;
333     }
334     BT_DBG("%s", bt_hex(buf, 22));
335 
336     if (buf[0] != p_genie_triple->mac[4] || buf[1] != p_genie_triple->mac[5])
337     {
338         return;
339     }
340     buf += 2;
341 
342     flags = buf[0];
343     net_idx = 0;
344     iv_index = buf[17];
345     addr = sys_get_be16(&buf[18]);
346 
347     BT_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x",
348            net_idx, iv_index, addr);
349 
350     genie_event(GENIE_EVT_SDK_MESH_PROV_DATA, &addr);
351     BT_INFO("nk %s", bt_hex(buf + 1, 16));
352     bt_mesh_provision(buf + 1, net_idx, flags, iv_index, addr, p_ultra_prov_devkey);
353 
354     _ultra_prov_send(GENIE_PROV_STATUS_SEND_COMPLETED, p_genie_triple->mac, 6);
355 }
356 
genie_provision_ultra_prov_handle(uint8_t frame_type,void * frame_buf)357 int genie_provision_ultra_prov_handle(uint8_t frame_type, void *frame_buf)
358 {
359     uint16_t company = 0;
360     uint8_t fixed_byte = 0;
361     uint8_t prov_cmd = 0;
362     struct net_buf_simple *buf = NULL;
363 
364     buf = (struct net_buf_simple *)frame_buf;
365     if (frame_type != GENIE_PROV_ADV_TYPE || buf == NULL)
366     {
367         return -1;
368     }
369 
370     company = net_buf_simple_pull_be16(buf);
371     if (company == CONFIG_MESH_VENDOR_COMPANY_ID)
372     {
373         fixed_byte = net_buf_simple_pull_u8(buf);
374         if (fixed_byte == GENIE_PROV_FIXED_BYTE)
375         {
376             prov_cmd = net_buf_simple_pull_u8(buf);
377             switch (prov_cmd)
378             {
379             case GENIE_PROV_STATUS_RECV_RANDOM:
380                 genie_provision_ultra_prov_recv_random(buf->data);
381                 break;
382             case GENIE_PROV_STATUS_RECV_PROV_DATA:
383                 genie_provision_ultra_prov_recv_data(buf->data);
384                 break;
385             default:
386                 break;
387             }
388         }
389     }
390 
391     return 0;
392 }
393 #endif
394 
_genie_pbadv_timer_cb(void * p_timer,void * args)395 static void _genie_pbadv_timer_cb(void *p_timer, void *args)
396 {
397     genie_event(GENIE_EVT_SDK_MESH_PBADV_TIMEOUT, NULL);
398 }
399 
genie_provision_pbadv_timer_start(uint32_t prov_timeout)400 void genie_provision_pbadv_timer_start(uint32_t prov_timeout)
401 {
402     static uint8_t inited = 0;
403 
404     if (!inited)
405     {
406         k_timer_init(&pbadv_timeout_timer, _genie_pbadv_timer_cb, NULL);
407         inited = 1;
408     }
409 
410     k_timer_start(&pbadv_timeout_timer, prov_timeout);
411 }
412 
genie_provision_pbadv_timer_stop(void)413 void genie_provision_pbadv_timer_stop(void)
414 {
415     k_timer_stop(&pbadv_timeout_timer);
416 }
417 
genie_provision_start_slient_pbadv(void)418 void genie_provision_start_slient_pbadv(void)
419 {
420     genie_provision_set_silent_flag();
421     //bt_mesh_prov_disable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
422     extern void genie_set_silent_unprov_beacon_interval(bool is_silent);
423     genie_set_silent_unprov_beacon_interval(true);
424     bt_mesh_prov_enable(BT_MESH_PROV_ADV);
425 }
426 
_genie_prov_timer_cb(void * p_timer,void * args)427 static void _genie_prov_timer_cb(void *p_timer, void *args)
428 {
429     genie_event(GENIE_EVT_SDK_MESH_PROV_TIMEOUT, NULL);
430 }
431 
genie_provision_prov_timer_start(void)432 void genie_provision_prov_timer_start(void)
433 {
434     static uint8_t inited = 0;
435 
436     if (!inited)
437     {
438         k_timer_init(&prov_timeout_timer, _genie_prov_timer_cb, NULL);
439         inited = 1;
440     }
441     k_timer_start(&prov_timeout_timer, MESH_PROVISIONING_TIMEOUT);
442 }
443 
genie_provision_prov_timer_stop(void)444 void genie_provision_prov_timer_stop(void)
445 {
446     k_timer_stop(&prov_timeout_timer);
447 }
448