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