xref: /btstack/src/mesh/provisioning_device.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
1 /*
2  * Copyright (C) 2017 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "provisioning_device.c"
39 
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 
45 #include "btstack_memory.h"
46 #include "btstack_event.h"
47 
48 #include "mesh/provisioning_device.h"
49 #include "mesh/mesh_crypto.h"
50 #ifdef ENABLE_MESH_ADV_BEARER
51 #include "mesh/pb_adv.h"
52 #endif
53 #ifdef ENABLE_MESH_GATT_BEARER
54 #include "mesh/pb_gatt.h"
55 #endif
56 #include "mesh/provisioning.h"
57 
58 static void prov_key_generated(void * arg);
59 
60 // remote ecc
61 static uint8_t remote_ec_q[64];
62 static uint8_t dhkey[32];
63 
64 static btstack_packet_handler_t prov_packet_handler;
65 
66 static uint8_t  prov_buffer_out[MESH_PROV_MAX_PROXY_PDU];
67 // ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue || ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
68 static uint8_t  prov_confirmation_inputs[1 + 11 + 5 + 64 + 64];
69 static uint8_t  prov_authentication_method;
70 static uint8_t  prov_public_key_oob_used;
71 static uint8_t  prov_emit_public_key_oob_active;
72 static uint8_t  prov_emit_output_oob_active;
73 static uint8_t  prov_ec_q[64];
74 
75 static const uint8_t * prov_public_key_oob_q;
76 static const uint8_t * prov_public_key_oob_d;
77 
78 // num elements
79 static uint8_t  prov_num_elements = 1;
80 
81 // capabilites
82 static const uint8_t * prov_static_oob_data;
83 
84 static uint16_t  prov_static_oob_len;
85 static uint16_t  prov_output_oob_actions;
86 static uint16_t  prov_input_oob_actions;
87 static uint8_t   prov_public_key_oob_available;
88 static uint8_t   prov_static_oob_available;
89 static uint8_t   prov_output_oob_size;
90 static uint8_t   prov_input_oob_size;
91 static uint8_t   prov_error_code;
92 static uint8_t   prov_waiting_for_outgoing_complete;
93 
94 static uint8_t                      prov_attention_timer_timeout;
95 
96 static btstack_timer_source_t       prov_protocol_timer;
97 
98 static btstack_crypto_aes128_cmac_t prov_cmac_request;
99 static btstack_crypto_random_t      prov_random_request;
100 static btstack_crypto_ecc_p256_t    prov_ecc_p256_request;
101 static btstack_crypto_ccm_t         prov_ccm_request;
102 
103 // ConfirmationDevice
104 static uint8_t confirmation_device[16];
105 // ConfirmationSalt
106 static uint8_t confirmation_salt[16];
107 // ConfirmationKey
108 static uint8_t confirmation_key[16];
109 // RandomDevice
110 static uint8_t random_device[16];
111 // ProvisioningSalt
112 static uint8_t provisioning_salt[16];
113 // AuthValue
114 static uint8_t auth_value[16];
115 // SessionKey
116 static uint8_t session_key[16];
117 // SessionNonce
118 static uint8_t session_nonce[16];
119 // EncProvisioningData
120 static uint8_t enc_provisioning_data[25];
121 // ProvisioningData
122 static uint8_t provisioning_data[25];
123 
124 // received network_key
125 static mesh_network_key_t * network_key;
126 
127 // DeviceKey
128 static uint8_t device_key[16];
129 
130 static uint8_t  flags;
131 
132 static uint32_t iv_index;
133 static uint16_t unicast_address;
134 
135 typedef enum {
136     DEVICE_W4_INVITE,
137     DEVICE_SEND_CAPABILITIES,
138     DEVICE_W4_START,
139     DEVICE_W4_INPUT_OOK,
140     DEVICE_SEND_INPUT_COMPLETE,
141     DEVICE_W4_PUB_KEY,
142     DEVICE_SEND_PUB_KEY,
143     DEVICE_PUB_KEY_SENT,
144     DEVICE_W4_CONFIRM,
145     DEVICE_SEND_CONFIRM,
146     DEVICE_W4_RANDOM,
147     DEVICE_SEND_RANDOM,
148     DEVICE_W4_DATA,
149     DEVICE_SEND_COMPLETE,
150     DEVICE_SEND_ERROR,
151     DEVICE_W4_DONE,
152 } device_state_t;
153 
154 static device_state_t device_state;
155 static uint16_t pb_transport_cid;
156 static mesh_pb_type_t pb_type;
157 
pb_send_pdu(uint16_t transport_cid,const uint8_t * buffer,uint16_t buffer_size)158 static void pb_send_pdu(uint16_t transport_cid, const uint8_t * buffer, uint16_t buffer_size){
159     switch (pb_type){
160 #ifdef ENABLE_MESH_ADV_BEARER
161         case MESH_PB_TYPE_ADV:
162             pb_adv_send_pdu(transport_cid, buffer, buffer_size);
163             break;
164 #endif
165 #ifdef ENABLE_MESH_GATT_BEARER
166         case MESH_PB_TYPE_GATT:
167             pb_gatt_send_pdu(transport_cid, buffer, buffer_size);
168             break;
169 #endif
170         default:
171             break;
172      }
173 }
174 
pb_close_link(uint16_t transport_cid,uint8_t reason)175 static void pb_close_link(uint16_t transport_cid, uint8_t reason){
176     switch (pb_type){
177 #ifdef ENABLE_MESH_ADV_BEARER
178         case MESH_PB_TYPE_ADV:
179             pb_adv_close_link(transport_cid, reason);
180             break;
181 #endif
182 #ifdef ENABLE_MESH_GATT_BEARER
183         case MESH_PB_TYPE_GATT:
184             pb_gatt_close_link(transport_cid, reason);
185             break;
186 #endif
187         default:
188             break;
189     }
190 }
191 
provisioning_emit_event(uint16_t pb_adv_cid,uint8_t mesh_subevent)192 static void provisioning_emit_event(uint16_t pb_adv_cid, uint8_t mesh_subevent){
193     if (!prov_packet_handler) return;
194     uint8_t event[5] = { HCI_EVENT_MESH_META, 3, mesh_subevent};
195     little_endian_store_16(event, 3, pb_adv_cid);
196     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
197 }
198 
provisioning_emit_output_oob_event(uint16_t pb_adv_cid,uint32_t number)199 static void provisioning_emit_output_oob_event(uint16_t pb_adv_cid, uint32_t number){
200     if (!prov_packet_handler) return;
201     uint8_t event[9] = { HCI_EVENT_MESH_META, 7, MESH_SUBEVENT_PB_PROV_START_EMIT_OUTPUT_OOB};
202     little_endian_store_16(event, 3, pb_adv_cid);
203     little_endian_store_32(event, 5, number);
204     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
205 }
206 
provisioning_emit_attention_timer_event(uint16_t pb_adv_cid,uint8_t timer_s)207 static void provisioning_emit_attention_timer_event(uint16_t pb_adv_cid, uint8_t timer_s){
208     if (!prov_packet_handler) return;
209     uint8_t event[6] = { HCI_EVENT_MESH_META, 4, MESH_SUBEVENT_PB_PROV_ATTENTION_TIMER};
210     little_endian_store_16(event, 3, pb_adv_cid);
211     event[5] = timer_s;
212     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
213 }
214 
provisiong_timer_handler(btstack_timer_source_t * ts)215 static void provisiong_timer_handler(btstack_timer_source_t * ts){
216     UNUSED(ts);
217     printf("Provisioning Protocol Timeout -> Close Link!\n");
218     pb_close_link(1, 1);
219 }
220 
221 // The provisioning protocol shall have a minimum timeout of 60 seconds that is reset
222 // each time a provisioning protocol PDU is sent or received
provisioning_timer_start(void)223 static void provisioning_timer_start(void){
224     btstack_run_loop_remove_timer(&prov_protocol_timer);
225     btstack_run_loop_set_timer_handler(&prov_protocol_timer, &provisiong_timer_handler);
226     btstack_run_loop_set_timer(&prov_protocol_timer, PROVISIONING_PROTOCOL_TIMEOUT_MS);
227     btstack_run_loop_add_timer(&prov_protocol_timer);
228 }
229 
provisioning_timer_stop(void)230 static void provisioning_timer_stop(void){
231     btstack_run_loop_remove_timer(&prov_protocol_timer);
232 }
233 
234 
235 // Outgoing Provisioning PDUs
provisioning_send_provisioning_error(void)236 static void provisioning_send_provisioning_error(void){
237     // setup response
238     prov_buffer_out[0] = MESH_PROV_FAILED;
239     prov_buffer_out[1] = prov_error_code;
240     pb_send_pdu(pb_transport_cid, prov_buffer_out, 2);
241 }
242 
provisioning_send_capabilites(void)243 static void provisioning_send_capabilites(void){
244     // setup response
245     prov_buffer_out[0] = MESH_PROV_CAPABILITIES;
246 
247     /* Number of Elements supported */
248     prov_buffer_out[1] = prov_num_elements;
249 
250     /* Supported algorithms - FIPS P-256 Eliptic Curve */
251     big_endian_store_16(prov_buffer_out, 2, 1);
252 
253     /* Public Key Type - Public Key OOB information available */
254     prov_buffer_out[4] = prov_public_key_oob_available;
255 
256     /* Static OOB Type - Static OOB information available */
257     prov_buffer_out[5] = prov_static_oob_available;
258 
259     /* Output OOB Size - max of 8 */
260     prov_buffer_out[6] = prov_output_oob_size;
261 
262     /* Output OOB Action */
263     big_endian_store_16(prov_buffer_out, 7, prov_output_oob_actions);
264 
265     /* Input OOB Size - max of 8*/
266     prov_buffer_out[9] = prov_input_oob_size;
267 
268     /* Input OOB Action */
269     big_endian_store_16(prov_buffer_out, 10, prov_input_oob_actions);
270 
271     // store for confirmation inputs: len 11
272     (void)memcpy(&prov_confirmation_inputs[1], &prov_buffer_out[1], 11);
273 
274     // send
275 
276     pb_send_pdu(pb_transport_cid, prov_buffer_out, 12);
277 }
278 
provisioning_send_public_key(void)279 static void provisioning_send_public_key(void){
280     // setup response
281     prov_buffer_out[0] = MESH_PROV_PUB_KEY;
282     (void)memcpy(&prov_buffer_out[1], prov_ec_q, 64);
283 
284     // store for confirmation inputs: len 64
285     (void)memcpy(&prov_confirmation_inputs[81], &prov_buffer_out[1], 64);
286 
287     // send
288     pb_send_pdu(pb_transport_cid, prov_buffer_out, 65);
289 }
290 
provisioning_send_input_complete(void)291 static void provisioning_send_input_complete(void){
292     // setup response
293     prov_buffer_out[0] = MESH_PROV_INPUT_COMPLETE;
294 
295     // send
296     pb_send_pdu(pb_transport_cid, prov_buffer_out, 17);
297 }
provisioning_send_confirm(void)298 static void provisioning_send_confirm(void){
299     // setup response
300     prov_buffer_out[0] = MESH_PROV_CONFIRM;
301     (void)memcpy(&prov_buffer_out[1], confirmation_device, 16);
302 
303     // send
304     pb_send_pdu(pb_transport_cid, prov_buffer_out, 17);
305 }
306 
provisioning_send_random(void)307 static void provisioning_send_random(void){
308     // setup response
309     prov_buffer_out[0] = MESH_PROV_RANDOM;
310     (void)memcpy(&prov_buffer_out[1], random_device, 16);
311 
312     // send pdu
313     pb_send_pdu(pb_transport_cid, prov_buffer_out, 17);
314 }
315 
provisioning_send_complete(void)316 static void provisioning_send_complete(void){
317     // setup response
318     prov_buffer_out[0] = MESH_PROV_COMPLETE;
319 
320     // send pdu
321     pb_send_pdu(pb_transport_cid, prov_buffer_out, 1);
322 }
323 
provisioning_done(void)324 static void provisioning_done(void){
325     if (prov_emit_public_key_oob_active){
326         prov_emit_public_key_oob_active = 0;
327         provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_STOP_EMIT_PUBLIC_KEY_OOB);
328     }
329     if (prov_emit_output_oob_active){
330         prov_emit_output_oob_active = 0;
331         provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_STOP_EMIT_OUTPUT_OOB);
332     }
333     if (prov_attention_timer_timeout){
334         prov_attention_timer_timeout = 0;
335         provisioning_emit_attention_timer_event(1, 0);
336     }
337     device_state = DEVICE_W4_INVITE;
338 
339     // generate new public key
340     printf("Generate new public key\n");
341     btstack_crypto_ecc_p256_generate_key(&prov_ecc_p256_request, prov_ec_q, &prov_key_generated, NULL);
342 }
343 
provisioning_handle_auth_value_output_oob(void * arg)344 static void provisioning_handle_auth_value_output_oob(void * arg){
345     UNUSED(arg);
346     // limit auth value to single digit
347     auth_value[15] = auth_value[15] % 9 + 1;
348 
349     printf("Output OOB: %u\n", auth_value[15]);
350 
351     // emit output oob value
352     provisioning_emit_output_oob_event(1, auth_value[15]);
353     prov_emit_output_oob_active = 1;
354 }
355 
provisioning_public_key_exchange_complete(void)356 static void provisioning_public_key_exchange_complete(void){
357 
358     // reset auth_value
359     memset(auth_value, 0, sizeof(auth_value));
360 
361     // handle authentication method
362     switch (prov_authentication_method){
363         case 0x00:
364             device_state = DEVICE_W4_CONFIRM;
365             break;
366         case 0x01:
367             (void)memcpy(&auth_value[16 - prov_static_oob_len],
368                          prov_static_oob_data, prov_static_oob_len);
369             device_state = DEVICE_W4_CONFIRM;
370             break;
371         case 0x02:
372             device_state = DEVICE_W4_CONFIRM;
373             printf("Generate random for auth_value\n");
374             // generate single byte of random data to use for authentication
375             btstack_crypto_random_generate(&prov_random_request, &auth_value[15], 1, &provisioning_handle_auth_value_output_oob, NULL);
376             break;
377         case 0x03:
378             // Input OOB
379             printf("Input OOB requested\n");
380             provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_INPUT_OOB_REQUEST);
381             device_state = DEVICE_W4_INPUT_OOK;
382             break;
383         default:
384             break;
385     }
386 }
387 
provisioning_run(void)388 static void provisioning_run(void){
389     printf("provisioning_run: state %x, wait for outgoing complete %u\n", device_state, prov_waiting_for_outgoing_complete);
390     if (prov_waiting_for_outgoing_complete) return;
391     int start_timer = 1;
392     switch (device_state){
393         case DEVICE_SEND_ERROR:
394             start_timer = 0;    // game over
395             device_state = DEVICE_W4_DONE;
396             prov_waiting_for_outgoing_complete = 1;
397             provisioning_send_provisioning_error();
398             break;
399         case DEVICE_SEND_CAPABILITIES:
400             device_state = DEVICE_W4_START;
401             prov_waiting_for_outgoing_complete = 1;
402             provisioning_send_capabilites();
403             break;
404         case DEVICE_SEND_INPUT_COMPLETE:
405             device_state = DEVICE_W4_CONFIRM;
406             prov_waiting_for_outgoing_complete = 1;
407             provisioning_send_input_complete();
408             break;
409         case DEVICE_SEND_PUB_KEY:
410             device_state = DEVICE_PUB_KEY_SENT;
411             prov_waiting_for_outgoing_complete = 1;
412             provisioning_send_public_key();
413             provisioning_public_key_exchange_complete();
414             break;
415         case DEVICE_SEND_CONFIRM:
416             device_state = DEVICE_W4_RANDOM;
417             prov_waiting_for_outgoing_complete = 1;
418             provisioning_send_confirm();
419             break;
420         case DEVICE_SEND_RANDOM:
421             device_state = DEVICE_W4_DATA;
422             prov_waiting_for_outgoing_complete = 1;
423             provisioning_send_random();
424             break;
425         case DEVICE_SEND_COMPLETE:
426             start_timer = 0;    // last message
427             device_state = DEVICE_W4_DONE;
428             prov_waiting_for_outgoing_complete = 1;
429             provisioning_send_complete();
430             break;
431         default:
432             return;
433     }
434     if (start_timer){
435         provisioning_timer_start();
436     }
437 }
438 
provisioning_handle_provisioning_error(uint8_t error_code)439 static void provisioning_handle_provisioning_error(uint8_t error_code){
440     printf("PROVISIONING ERROR\n");
441     provisioning_timer_stop();
442     prov_error_code = error_code;
443     device_state = DEVICE_SEND_ERROR;
444     provisioning_run();
445 }
446 
provisioning_handle_invite(uint8_t * packet,uint16_t size)447 static void provisioning_handle_invite(uint8_t *packet, uint16_t size){
448 
449     if (size != 1) return;
450 
451     // store for confirmation inputs: len 1
452     (void)memcpy(&prov_confirmation_inputs[0], packet, 1);
453 
454     // handle invite message
455     prov_attention_timer_timeout = packet[0];
456     if (prov_attention_timer_timeout){
457         provisioning_emit_attention_timer_event(pb_transport_cid, prov_attention_timer_timeout);
458     }
459 
460     device_state = DEVICE_SEND_CAPABILITIES;
461     provisioning_run();
462 }
463 
provisioning_handle_start(uint8_t * packet,uint16_t size)464 static void provisioning_handle_start(uint8_t * packet, uint16_t size){
465 
466     if (size != 5) return;
467 
468     // validate Algorithm
469     int ok = 1;
470     if (packet[0] > 0x00){
471         ok = 0;
472     }
473     // validate Publik Key
474     if (packet[1] > 0x01){
475         ok = 0;
476     }
477     // validate Authentication Method
478     switch (packet[2]){
479         case 0:
480         case 1:
481             if (packet[3] != 0 || packet[4] != 0){
482                 ok = 0;
483                 break;
484             }
485             break;
486         case 2:
487             if (packet[3] > 0x04 || packet[4] == 0 || packet[4] > 0x08){
488                 ok = 0;
489                 break;
490             }
491             break;
492         case 3:
493             if (packet[3] > 0x03 || packet[4] == 0 || packet[4] > 0x08){
494                 ok = 0;
495                 break;
496             }
497             break;
498         default:
499             // TODO check
500             break;
501     }
502     if (!ok){
503         printf("PROV_START arguments incorrect\n");
504         provisioning_handle_provisioning_error(0x02);
505         return;
506     }
507 
508     // store for confirmation inputs: len 5
509     (void)memcpy(&prov_confirmation_inputs[12], packet, 5);
510 
511     // public key oob
512     prov_public_key_oob_used = packet[1];
513 
514     // authentication method
515     prov_authentication_method = packet[2];
516 
517     // start emit public OOK if specified
518     if (prov_public_key_oob_available && prov_public_key_oob_used){
519         provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_START_EMIT_PUBLIC_KEY_OOB);
520     }
521 
522     printf("PublicKey:  %02x\n", prov_public_key_oob_used);
523     printf("AuthMethod: %02x\n", prov_authentication_method);
524 
525     device_state = DEVICE_W4_PUB_KEY;
526     provisioning_run();
527 }
528 
provisioning_handle_public_key_dhkey(void * arg)529 static void provisioning_handle_public_key_dhkey(void * arg){
530     UNUSED(arg);
531 
532     printf("DHKEY: ");
533     printf_hexdump(dhkey, sizeof(dhkey));
534 
535     // skip sending own public key when public key oob is used
536     if (prov_public_key_oob_available && prov_public_key_oob_used){
537         // just copy key for confirmation inputs
538         (void)memcpy(&prov_confirmation_inputs[81], prov_ec_q, 64);
539         provisioning_public_key_exchange_complete();
540     } else {
541         // queue public key pdu
542         printf("DEVICE_SEND_PUB_KEY\n");
543         device_state = DEVICE_SEND_PUB_KEY;
544     }
545     provisioning_run();
546 }
547 
provisioning_handle_public_key(uint8_t * packet,uint16_t size)548 static void provisioning_handle_public_key(uint8_t *packet, uint16_t size){
549 
550     // validate public key
551     if (size != sizeof(remote_ec_q) || btstack_crypto_ecc_p256_validate_public_key(packet) != 0){
552         printf("Public Key invalid, abort provisioning\n");
553         provisioning_handle_provisioning_error(0x07);   // Unexpected Error
554         return;
555     }
556 
557     // stop emit public OOK if specified and send to crypto module
558     if (prov_public_key_oob_available && prov_public_key_oob_used){
559         provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_STOP_EMIT_PUBLIC_KEY_OOB);
560 
561         printf("Replace generated ECC with Public Key OOB:");
562         (void)memcpy(prov_ec_q, prov_public_key_oob_q, 64);
563         printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
564         btstack_crypto_ecc_p256_set_key(prov_public_key_oob_q, prov_public_key_oob_d);
565     }
566 
567     // store for confirmation inputs: len 64
568     (void)memcpy(&prov_confirmation_inputs[17], packet, 64);
569 
570     // store remote q
571     (void)memcpy(remote_ec_q, packet, sizeof(remote_ec_q));
572 
573     // calculate DHKey
574     btstack_crypto_ecc_p256_calculate_dhkey(&prov_ecc_p256_request, remote_ec_q, dhkey, provisioning_handle_public_key_dhkey, NULL);
575 }
576 
provisioning_handle_confirmation_device_calculated(void * arg)577 static void provisioning_handle_confirmation_device_calculated(void * arg){
578     UNUSED(arg);
579 
580     printf("ConfirmationDevice: ");
581     printf_hexdump(confirmation_device, sizeof(confirmation_device));
582 
583     device_state = DEVICE_SEND_CONFIRM;
584     provisioning_run();
585 }
586 
provisioning_handle_confirmation_random_device(void * arg)587 static void provisioning_handle_confirmation_random_device(void * arg){
588     UNUSED(arg);
589 
590     // re-use prov_confirmation_inputs buffer
591     (void)memcpy(&prov_confirmation_inputs[0], random_device, 16);
592     (void)memcpy(&prov_confirmation_inputs[16], auth_value, 16);
593 
594     // calc confirmation device
595     btstack_crypto_aes128_cmac_message(&prov_cmac_request, confirmation_key, 32, prov_confirmation_inputs, confirmation_device, &provisioning_handle_confirmation_device_calculated, NULL);
596 }
597 
provisioning_handle_confirmation_k1_calculated(void * arg)598 static void provisioning_handle_confirmation_k1_calculated(void * arg){
599     UNUSED(arg);
600 
601     printf("ConfirmationKey:   ");
602     printf_hexdump(confirmation_key, sizeof(confirmation_key));
603 
604     printf("AuthValue: ");
605     printf_hexdump(auth_value, 16);
606 
607     // generate random_device
608     btstack_crypto_random_generate(&prov_random_request,random_device, 16, &provisioning_handle_confirmation_random_device, NULL);
609 }
610 
provisioning_handle_confirmation_s1_calculated(void * arg)611 static void provisioning_handle_confirmation_s1_calculated(void * arg){
612     UNUSED(arg);
613 
614     // ConfirmationSalt
615     printf("ConfirmationSalt:   ");
616     printf_hexdump(confirmation_salt, sizeof(confirmation_salt));
617 
618     // ConfirmationKey
619     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), confirmation_salt, (const uint8_t*) "prck", 4, confirmation_key, &provisioning_handle_confirmation_k1_calculated, NULL);
620 }
621 
provisioning_handle_confirmation(uint8_t * packet,uint16_t size)622 static void provisioning_handle_confirmation(uint8_t *packet, uint16_t size){
623     UNUSED(size);
624     UNUSED(packet);
625 
626     //
627     if (prov_emit_output_oob_active){
628         prov_emit_output_oob_active = 0;
629         provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_STOP_EMIT_OUTPUT_OOB);
630     }
631 
632     // CalculationInputs
633     printf("ConfirmationInputs: ");
634     printf_hexdump(prov_confirmation_inputs, sizeof(prov_confirmation_inputs));
635 
636     // calculate s1
637     btstack_crypto_aes128_cmac_zero(&prov_cmac_request, sizeof(prov_confirmation_inputs), prov_confirmation_inputs, confirmation_salt, &provisioning_handle_confirmation_s1_calculated, NULL);
638 }
639 
640 // PROV_RANDOM
provisioning_handle_random_session_nonce_calculated(void * arg)641 static void provisioning_handle_random_session_nonce_calculated(void * arg){
642     UNUSED(arg);
643 
644     // The nonce shall be the 13 least significant octets == zero most significant octets
645     uint8_t temp[13];
646     (void)memcpy(temp, &session_nonce[3], 13);
647     (void)memcpy(session_nonce, temp, 13);
648 
649     // SessionNonce
650     printf("SessionNonce:   ");
651     printf_hexdump(session_nonce, 13);
652 
653     device_state = DEVICE_SEND_RANDOM;
654     provisioning_run();
655 }
656 
provisioning_handle_random_session_key_calculated(void * arg)657 static void provisioning_handle_random_session_key_calculated(void * arg){
658     UNUSED(arg);
659 
660     // SessionKey
661     printf("SessionKey:   ");
662     printf_hexdump(session_key, sizeof(session_key));
663 
664     // SessionNonce
665     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), provisioning_salt, (const uint8_t*) "prsn", 4, session_nonce, &provisioning_handle_random_session_nonce_calculated, NULL);
666 }
667 
provisioning_handle_random_s1_calculated(void * arg)668 static void provisioning_handle_random_s1_calculated(void * arg){
669 
670     UNUSED(arg);
671 
672     // ProvisioningSalt
673     printf("ProvisioningSalt:   ");
674     printf_hexdump(provisioning_salt, sizeof(provisioning_salt));
675 
676     // SessionKey
677     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), provisioning_salt, (const uint8_t*) "prsk", 4, session_key, &provisioning_handle_random_session_key_calculated, NULL);
678 }
679 
provisioning_handle_random(uint8_t * packet,uint16_t size)680 static void provisioning_handle_random(uint8_t *packet, uint16_t size){
681 
682     UNUSED(size);
683     UNUSED(packet);
684 
685     // TODO: validate Confirmation
686 
687     // calc ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)
688     (void)memcpy(&prov_confirmation_inputs[0], confirmation_salt, 16);
689     (void)memcpy(&prov_confirmation_inputs[16], packet, 16);
690     (void)memcpy(&prov_confirmation_inputs[32], random_device, 16);
691     btstack_crypto_aes128_cmac_zero(&prov_cmac_request, 48, prov_confirmation_inputs, provisioning_salt, &provisioning_handle_random_s1_calculated, NULL);
692 }
693 
694 // PROV_DATA
provisioning_handle_network_dervived(void * arg)695 static void provisioning_handle_network_dervived(void * arg){
696     UNUSED(arg);
697 
698     provisioning_timer_stop();
699 
700     // notify client
701     provisioning_emit_event(1, MESH_SUBEVENT_PB_PROV_COMPLETE);
702 
703     device_state = DEVICE_SEND_COMPLETE;
704     provisioning_run();
705 
706 }
707 
provisioning_handle_data_device_key(void * arg)708 static void provisioning_handle_data_device_key(void * arg){
709     UNUSED(arg);
710 
711     // derive full network key
712     mesh_network_key_derive(&prov_cmac_request, network_key, &provisioning_handle_network_dervived, NULL);
713 }
714 
provisioning_handle_data_ccm(void * arg)715 static void provisioning_handle_data_ccm(void * arg){
716 
717     UNUSED(arg);
718 
719     // TODO: validate MIC?
720     uint8_t mic[8];
721     btstack_crypto_ccm_get_authentication_value(&prov_ccm_request, mic);
722     printf("MIC: ");
723     printf_hexdump(mic, 8);
724 
725     // allocate network key
726     network_key = btstack_memory_mesh_network_key_get();
727 
728     // sort provisoning data
729     (void)memcpy(network_key->net_key, provisioning_data, 16);
730     network_key->netkey_index = big_endian_read_16(provisioning_data, 16);
731     // assume free index available for very first network key
732     network_key->internal_index = mesh_network_key_get_free_index();
733     flags = provisioning_data[18];
734     iv_index = big_endian_read_32(provisioning_data, 19);
735     unicast_address = big_endian_read_16(provisioning_data, 23);
736 
737     // DeviceKey
738     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), provisioning_salt, (const uint8_t*) "prdk", 4, device_key, &provisioning_handle_data_device_key, NULL);
739 }
740 
provisioning_handle_data(uint8_t * packet,uint16_t size)741 static void provisioning_handle_data(uint8_t *packet, uint16_t size){
742 
743     UNUSED(size);
744 
745     (void)memcpy(enc_provisioning_data, packet, 25);
746 
747     // decode response
748     btstack_crypto_ccm_init(&prov_ccm_request, session_key, session_nonce, 25, 0, 8);
749     btstack_crypto_ccm_decrypt_block(&prov_ccm_request, 25, enc_provisioning_data, provisioning_data, &provisioning_handle_data_ccm, NULL);
750 }
751 
provisioning_handle_unexpected_pdu(uint8_t * packet,uint16_t size)752 static void provisioning_handle_unexpected_pdu(uint8_t *packet, uint16_t size){
753     UNUSED(size);
754     printf("Unexpected PDU #%u in state #%u\n", packet[0], (int) device_state);
755     provisioning_handle_provisioning_error(0x03);
756 }
757 
provisioning_handle_pdu(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)758 static void provisioning_handle_pdu(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
759     UNUSED(channel);
760 
761     if (size < 1) return;
762 
763     switch (packet_type){
764         case HCI_EVENT_PACKET:
765 
766             if (hci_event_packet_get_type(packet) != HCI_EVENT_MESH_META)  break;
767 
768             switch (hci_event_mesh_meta_get_subevent_code(packet)){
769                 case MESH_SUBEVENT_PB_TRANSPORT_LINK_OPEN:
770                     pb_transport_cid = mesh_subevent_pb_transport_link_open_get_pb_transport_cid(packet);
771                     pb_type = mesh_subevent_pb_transport_link_open_get_pb_type(packet);
772                     printf("Link opened, reset state, transport cid 0x%02x, PB type %d\n", pb_transport_cid, pb_type);
773                     provisioning_done();
774                     break;
775                 case MESH_SUBEVENT_PB_TRANSPORT_PDU_SENT:
776                     printf("Outgoing packet acked\n");
777                     prov_waiting_for_outgoing_complete = 0;
778                     if (device_state == DEVICE_W4_DONE){
779                         pb_close_link(1, 0);
780                         provisioning_done();
781                     }
782                     break;
783                 case MESH_SUBEVENT_PB_TRANSPORT_LINK_CLOSED:
784                     printf("Link close, reset state\n");
785                     pb_transport_cid = MESH_PB_TRANSPORT_INVALID_CID;
786                     provisioning_done();
787                     break;
788                 default:
789                     break;
790             }
791             break;
792         case PROVISIONING_DATA_PACKET:
793             // check state
794             switch (device_state){
795                 case DEVICE_W4_INVITE:
796                     if (packet[0] != MESH_PROV_INVITE) provisioning_handle_unexpected_pdu(packet, size);
797                     printf("MESH_PROV_INVITE: ");
798                     printf_hexdump(&packet[1], size-1);
799                     provisioning_handle_invite(&packet[1], size-1);
800                     break;
801                 case DEVICE_W4_START:
802                     if (packet[0] != MESH_PROV_START) provisioning_handle_unexpected_pdu(packet, size);
803                     printf("MESH_PROV_START:  ");
804                     printf_hexdump(&packet[1], size-1);
805                     provisioning_handle_start(&packet[1], size-1);
806                     break;
807                 case DEVICE_W4_PUB_KEY:
808                     if (packet[0] != MESH_PROV_PUB_KEY) provisioning_handle_unexpected_pdu(packet, size);
809                     printf("MESH_PROV_PUB_KEY: ");
810                     printf_hexdump(&packet[1], size-1);
811                     provisioning_handle_public_key(&packet[1], size-1);
812                     break;
813                 case DEVICE_W4_CONFIRM:
814                     if (packet[0] != MESH_PROV_CONFIRM) provisioning_handle_unexpected_pdu(packet, size);
815                     printf("MESH_PROV_CONFIRM: ");
816                     printf_hexdump(&packet[1], size-1);
817                     provisioning_handle_confirmation(&packet[1], size-1);
818                     break;
819                 case DEVICE_W4_RANDOM:
820                     if (packet[0] != MESH_PROV_RANDOM) provisioning_handle_unexpected_pdu(packet, size);
821                     printf("MESH_PROV_RANDOM:  ");
822                     printf_hexdump(&packet[1], size-1);
823                     provisioning_handle_random(&packet[1], size-1);
824                     break;
825                 case DEVICE_W4_DATA:
826                     if (packet[0] != MESH_PROV_DATA) provisioning_handle_unexpected_pdu(packet, size);
827                     printf("MESH_PROV_DATA:  ");
828                     provisioning_handle_data(&packet[1], size-1);
829                     break;
830                 default:
831                     break;
832             }
833             break;
834         default:
835             break;
836     }
837     provisioning_run();
838 }
839 
prov_key_generated(void * arg)840 static void prov_key_generated(void * arg){
841     UNUSED(arg);
842     printf("ECC-P256: ");
843     printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
844     // allow override
845     if (prov_public_key_oob_available){
846         printf("Replace generated ECC with Public Key OOB:");
847         (void)memcpy(prov_ec_q, prov_public_key_oob_q, 64);
848         printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
849         btstack_crypto_ecc_p256_set_key(prov_public_key_oob_q, prov_public_key_oob_d);
850     }
851 }
852 
provisioning_device_init(void)853 void provisioning_device_init(void){
854 #ifdef ENABLE_MESH_ADV_BEARER
855     // setup PB ADV
856     pb_adv_init();
857     pb_adv_register_device_packet_handler(&provisioning_handle_pdu);
858 #endif
859 #ifdef ENABLE_MESH_GATT_BEARER
860     // setup PB GATT
861     pb_gatt_init();
862     pb_gatt_register_packet_handler(&provisioning_handle_pdu);
863 #endif
864 
865     pb_transport_cid = MESH_PB_TRANSPORT_INVALID_CID;
866 
867     // init provisioning state and generate ecc key
868     provisioning_done();
869 }
870 
provisioning_device_register_packet_handler(btstack_packet_handler_t packet_handler)871 void provisioning_device_register_packet_handler(btstack_packet_handler_t packet_handler){
872     prov_packet_handler = packet_handler;
873 }
874 
provisioning_device_set_public_key_oob(const uint8_t * public_key,const uint8_t * private_key)875 void provisioning_device_set_public_key_oob(const uint8_t * public_key, const uint8_t * private_key){
876     prov_public_key_oob_q = public_key;
877     prov_public_key_oob_d = private_key;
878     prov_public_key_oob_available = 1;
879     btstack_crypto_ecc_p256_set_key(prov_public_key_oob_q, prov_public_key_oob_d);
880 }
881 
provisioning_device_set_static_oob(uint16_t static_oob_len,const uint8_t * static_oob_data)882 void provisioning_device_set_static_oob(uint16_t static_oob_len, const uint8_t * static_oob_data){
883     prov_static_oob_available = 1;
884     prov_static_oob_data = static_oob_data;
885     prov_static_oob_len  = btstack_min(static_oob_len, 16);
886 }
887 
provisioning_device_set_output_oob_actions(uint16_t supported_output_oob_action_types,uint8_t max_oob_output_size)888 void provisioning_device_set_output_oob_actions(uint16_t supported_output_oob_action_types, uint8_t max_oob_output_size){
889     prov_output_oob_actions = supported_output_oob_action_types;
890     prov_output_oob_size    = max_oob_output_size;
891 }
892 
provisioning_device_set_input_oob_actions(uint16_t supported_input_oob_action_types,uint8_t max_oob_input_size)893 void provisioning_device_set_input_oob_actions(uint16_t supported_input_oob_action_types, uint8_t max_oob_input_size){
894     prov_input_oob_actions = supported_input_oob_action_types;
895     prov_input_oob_size    = max_oob_input_size;
896 }
897 
provisioning_device_input_oob_complete_numeric(uint16_t pb_adv_cid,uint32_t input_oob)898 void provisioning_device_input_oob_complete_numeric(uint16_t pb_adv_cid, uint32_t input_oob){
899     UNUSED(pb_adv_cid);
900     if (device_state != DEVICE_W4_INPUT_OOK) return;
901 
902     // store input_oob as auth value
903     big_endian_store_32(auth_value, 12, input_oob);
904     device_state = DEVICE_SEND_INPUT_COMPLETE;
905     provisioning_run();
906 }
907 
provisioning_device_input_oob_complete_alphanumeric(uint16_t pb_adv_cid,const uint8_t * input_oob_data,uint16_t input_oob_len)908 void provisioning_device_input_oob_complete_alphanumeric(uint16_t pb_adv_cid, const uint8_t * input_oob_data, uint16_t input_oob_len){
909     UNUSED(pb_adv_cid);
910     if (device_state != DEVICE_W4_INPUT_OOK) return;
911 
912     // store input_oob and fillup with zeros
913     input_oob_len = btstack_min(input_oob_len, 16);
914     memset(auth_value, 0, 16);
915     (void)memcpy(auth_value, input_oob_data, input_oob_len);
916     device_state = DEVICE_SEND_INPUT_COMPLETE;
917     provisioning_run();
918 }
919 
provisioning_device_data_get(mesh_provisioning_data_t * the_provisioning_data)920 void provisioning_device_data_get(mesh_provisioning_data_t * the_provisioning_data){
921     the_provisioning_data->unicast_address = unicast_address;
922     the_provisioning_data->iv_index = iv_index;
923     the_provisioning_data->flags = flags;
924     (void)memcpy(the_provisioning_data->device_key, device_key, 16);
925     the_provisioning_data->network_key = network_key;
926 }
927