xref: /btstack/src/mesh/provisioning_provisioner.c (revision f4854a5efbe174cdf16fcaf3de7491781eef80ab)
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_provisioner.c"
39 
40 #include "mesh/provisioning_provisioner.h"
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 
46 #include "btstack.h"
47 #include "classic/rfcomm.h" // for crc8
48 
49 #include "mesh/mesh_crypto.h"
50 #include "mesh/pb_adv.h"
51 #include "mesh/provisioning.h"
52 
53 static void provisioning_public_key_ready(void);
54 
55 // global
56 static uint8_t         prov_ec_q[64];
57 static const uint8_t * prov_public_key_oob_q;
58 static const uint8_t * prov_public_key_oob_d;
59 static uint8_t  prov_public_key_oob_available;
60 
61 static btstack_packet_handler_t prov_packet_handler;
62 
63 // NetKey
64 static uint8_t  net_key[16];
65 // NetKeyIndex
66 static uint16_t net_key_index;
67 // Flags
68 static uint8_t  flags;
69 // IV Index
70 static uint32_t iv_index;
71 
72 // either used once or per session
73 static btstack_crypto_aes128_cmac_t prov_cmac_request;
74 static btstack_crypto_random_t      prov_random_request;
75 static btstack_crypto_ecc_p256_t    prov_ecc_p256_request;
76 static btstack_crypto_ccm_t         prov_ccm_request;
77 
78 // data per provisioning session
79 static btstack_timer_source_t       prov_protocol_timer;
80 
81 static uint16_t pb_adv_cid;
82 static uint8_t  prov_attention_timer;
83 static uint8_t  prov_buffer_out[100];   // TODO: how large are prov messages?
84 static uint8_t  prov_waiting_for_outgoing_complete;
85 static uint8_t  prov_error_code;
86 static uint8_t  prov_start_algorithm;
87 static uint8_t  prov_start_public_key_used;
88 static uint8_t  prov_start_authentication_method;
89 static uint8_t  prov_start_authentication_action;
90 static uint8_t  prov_start_authentication_size;
91 static uint8_t  prov_authentication_string;
92 static uint8_t  prov_confirmation_inputs[1 + 11 + 5 + 64 + 64];
93 static uint8_t  confirmation_provisioner[16];
94 static uint8_t  random_provisioner[16];
95 static uint8_t  auth_value[16];
96 static uint8_t  remote_ec_q[64];
97 static uint8_t  dhkey[32];
98 static uint8_t  confirmation_salt[16];
99 static uint8_t  confirmation_key[16];
100 // ConfirmationInputs = ProvisioningInvitePDUValue || ProvisioningCapabilitiesPDUValue || ProvisioningStartPDUValue || PublicKeyProvisioner || PublicKeyDevice
101 static uint8_t  prov_confirmation_inputs[1 + 11 + 5 + 64 + 64];
102 static uint8_t provisioning_salt[16];
103 static uint8_t session_key[16];
104 static uint8_t session_nonce[16];
105 static uint16_t unicast_address;
106 static uint8_t provisioning_data[25];
107 static uint8_t enc_provisioning_data[25];
108 static uint8_t provisioning_data_mic[8];
109 static uint8_t  prov_emit_output_oob_active;
110 
111 static const uint8_t * prov_static_oob_data;
112 static uint16_t  prov_static_oob_len;
113 
114 #if 0
115 static uint8_t  prov_public_key_oob_used;
116 static uint8_t  prov_emit_public_key_oob_active;
117 
118 // capabilites
119 
120 static uint16_t  prov_output_oob_actions;
121 static uint16_t  prov_input_oob_actions;
122 static uint8_t   prov_output_oob_size;
123 static uint8_t   prov_input_oob_size;
124 
125 // derived
126 static uint8_t network_id[8];
127 static uint8_t beacon_key[16];
128 
129 static void provisioning_attention_timer_timeout(btstack_timer_source_t * ts){
130     UNUSED(ts);
131     if (prov_attention_timer_timeout == 0) return;
132     prov_attention_timer_timeout--;
133     provisioning_attention_timer_set();
134 }
135 
136 static void provisioning_attention_timer_set(void){
137     provisioning_emit_attention_timer_event(1, prov_attention_timer_timeout);
138     if (prov_attention_timer_timeout){
139         btstack_run_loop_set_timer_handler(&prov_attention_timer, &provisioning_attention_timer_timeout);
140         btstack_run_loop_set_timer(&prov_attention_timer, 1000);
141         btstack_run_loop_add_timer(&prov_attention_timer);
142     }
143 }
144 #endif
145 
146 static void provisioning_emit_output_oob_event(uint16_t pb_adv_cid, uint32_t number){
147     if (!prov_packet_handler) return;
148     uint8_t event[9] = { HCI_EVENT_MESH_META, 7, MESH_SUBEVENT_PB_PROV_START_EMIT_OUTPUT_OOB};
149     little_endian_store_16(event, 3, pb_adv_cid);
150     little_endian_store_16(event, 5, number);
151     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
152 }
153 
154 static void provisioning_emit_event(uint8_t mesh_subevent, uint16_t pb_adv_cid){
155     if (!prov_packet_handler) return;
156     uint8_t event[5] = { HCI_EVENT_MESH_META, 3, mesh_subevent};
157     little_endian_store_16(event, 3, pb_adv_cid);
158     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
159 }
160 
161 static void provisiong_timer_handler(btstack_timer_source_t * ts){
162     UNUSED(ts);
163     printf("Provisioning Protocol Timeout -> Close Link!\n");
164     // TODO: use actual pb_adv_cid
165     pb_adv_close_link(1, 1);
166 }
167 
168 // The provisioning protocol shall have a minimum timeout of 60 seconds that is reset
169 // each time a provisioning protocol PDU is sent or received
170 static void provisioning_timer_start(void){
171     btstack_run_loop_remove_timer(&prov_protocol_timer);
172     btstack_run_loop_set_timer_handler(&prov_protocol_timer, &provisiong_timer_handler);
173     btstack_run_loop_set_timer(&prov_protocol_timer, PROVISIONING_PROTOCOL_TIMEOUT_MS);
174     btstack_run_loop_add_timer(&prov_protocol_timer);
175 }
176 
177 static void provisioning_timer_stop(void){
178     btstack_run_loop_remove_timer(&prov_protocol_timer);
179 }
180 
181 // Outgoing Provisioning PDUs
182 
183 static void provisioning_send_invite(uint16_t pb_adv_cid){
184     prov_buffer_out[0] = MESH_PROV_INVITE;
185     prov_buffer_out[1] = prov_attention_timer;
186     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 2);
187     // collect confirmation_inputs
188     memcpy(&prov_confirmation_inputs[0], &prov_buffer_out[1], 1);
189 }
190 
191 static void provisioning_send_start(uint16_t pb_adv_cid){
192     prov_buffer_out[0] = MESH_PROV_START;
193     prov_buffer_out[1] = prov_start_algorithm;
194     prov_buffer_out[2] = prov_start_public_key_used;
195     prov_buffer_out[3] = prov_start_authentication_method;
196     prov_buffer_out[4] = prov_start_authentication_action;
197     prov_buffer_out[5] = prov_start_authentication_size;
198     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 6);
199     // store for confirmation inputs: len 5
200     memcpy(&prov_confirmation_inputs[12], &prov_buffer_out[1], 5);
201 }
202 
203 static void provisioning_send_provisioning_error(void){
204     prov_buffer_out[0] = MESH_PROV_FAILED;
205     prov_buffer_out[1] = prov_error_code;
206     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 2);
207 }
208 
209 static void provisioning_send_public_key(void){
210     prov_buffer_out[0] = MESH_PROV_PUB_KEY;
211     memcpy(&prov_buffer_out[1], prov_ec_q, 64);
212     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 65);
213     // store for confirmation inputs: len 64
214     memcpy(&prov_confirmation_inputs[17], &prov_buffer_out[1], 64);
215 }
216 
217 static void provisioning_send_confirm(void){
218     prov_buffer_out[0] = MESH_PROV_CONFIRM;
219     memcpy(&prov_buffer_out[1], confirmation_provisioner, 16);
220     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 17);
221 }
222 
223 static void provisioning_send_random(void){
224     prov_buffer_out[0] = MESH_PROV_RANDOM;
225     memcpy(&prov_buffer_out[1], random_provisioner, 16);
226     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 17);
227 }
228 
229 static void provisioning_send_data(void){
230     prov_buffer_out[0] = MESH_PROV_DATA;
231     memcpy(&prov_buffer_out[1], enc_provisioning_data, 25);
232     memcpy(&prov_buffer_out[26], provisioning_data_mic, 8);
233     pb_adv_send_pdu(pb_adv_cid, prov_buffer_out, 34);
234 }
235 
236 typedef enum {
237     PROVISIONER_IDLE,
238     PROVISIONER_SEND_INVITE,
239     PROVISIONER_W4_CAPABILITIES,
240     PROVISIONER_W4_AUTH_CONFIGURATION,
241     PROVISIONER_SEND_START,
242     PROVISIONED_W2_EMIT_READ_PUB_KEY_OOB,
243     PROVISIONER_SEND_PUB_KEY,
244     PROVISIONER_W4_PUB_KEY,
245     PROVISIONER_W4_PUB_KEY_OOB,
246     PROVISIONER_W4_INPUT_OOK,
247     PROVISIONER_W4_INPUT_COMPLETE,
248     PROVISIONER_SEND_CONFIRM,
249     PROVISIONER_W4_CONFIRM,
250     PROVISIONER_SEND_RANDOM,
251     PROVISIONER_W4_RANDOM,
252     PROVISIONER_SEND_DATA,
253     PROVISIONER_W4_COMPLETE,
254     PROVISIONER_SEND_ERROR,
255 } provisioner_state_t;
256 
257 static provisioner_state_t provisioner_state;
258 
259 static void provisioning_run(void){
260     if (prov_waiting_for_outgoing_complete) return;
261     int start_timer = 1;
262     switch (provisioner_state){
263         case PROVISIONER_SEND_ERROR:
264             start_timer = 0;    // game over
265             provisioning_send_provisioning_error();
266             break;
267         case PROVISIONER_SEND_INVITE:
268             provisioning_send_invite(pb_adv_cid);
269             provisioner_state = PROVISIONER_W4_CAPABILITIES;
270             break;
271         case PROVISIONER_SEND_START:
272             provisioning_send_start(pb_adv_cid);
273             if (prov_start_public_key_used){
274                 provisioner_state = PROVISIONED_W2_EMIT_READ_PUB_KEY_OOB;
275             } else {
276                 provisioner_state = PROVISIONER_SEND_PUB_KEY;
277             }
278             break;
279         case PROVISIONED_W2_EMIT_READ_PUB_KEY_OOB:
280             printf("Public OOB: please read OOB from remote device\n");
281             provisioner_state = PROVISIONER_W4_PUB_KEY_OOB;
282             provisioning_emit_event(MESH_SUBEVENT_PB_PROV_START_RECEIVE_PUBLIC_KEY_OOB, 1);
283             break;
284         case PROVISIONER_SEND_PUB_KEY:
285             provisioning_send_public_key();
286             if (prov_start_public_key_used){
287                 provisioning_public_key_ready();
288             } else {
289                 provisioner_state = PROVISIONER_W4_PUB_KEY;
290             }
291             break;
292         case PROVISIONER_SEND_CONFIRM:
293             provisioning_send_confirm();
294             provisioner_state = PROVISIONER_W4_CONFIRM;
295             break;
296         case PROVISIONER_SEND_RANDOM:
297             provisioning_send_random();
298             provisioner_state = PROVISIONER_W4_RANDOM;
299             break;
300         case PROVISIONER_SEND_DATA:
301             provisioning_send_data();
302             provisioner_state = PROVISIONER_W4_COMPLETE;
303             break;
304         default:
305             return;
306     }
307     if (start_timer){
308         provisioning_timer_start();
309     }
310     prov_waiting_for_outgoing_complete = 1;
311 }
312 
313 // End of outgoing PDUs
314 
315 static void provisioning_done(void){
316     // if (prov_emit_public_key_oob_active){
317     //     prov_emit_public_key_oob_active = 0;
318     //     provisioning_emit_event(MESH_PB_PROV_STOP_EMIT_PUBLIC_KEY_OOB, 1);
319     // }
320     if (prov_emit_output_oob_active){
321         prov_emit_output_oob_active = 0;
322         provisioning_emit_event(MESH_SUBEVENT_PB_PROV_STOP_EMIT_OUTPUT_OOB, 1);
323     }
324     provisioner_state = PROVISIONER_IDLE;
325 }
326 
327 
328 static void provisioning_handle_provisioning_error(uint8_t error_code){
329     provisioning_timer_stop();
330     prov_error_code = error_code;
331     provisioner_state = PROVISIONER_SEND_ERROR;
332     provisioning_run();
333 }
334 
335 static void provisioning_handle_link_opened(uint16_t pb_adv_cid){
336     provisioner_state = PROVISIONER_SEND_INVITE;
337 }
338 
339 static void provisioning_handle_capabilities(uint16_t pb_adv_cid, const uint8_t * packet_data, uint16_t packet_len){
340 
341     if (packet_len != 11) return;
342 
343     // collect confirmation_inputs
344     memcpy(&prov_confirmation_inputs[1], packet_data, packet_len);
345 
346     provisioner_state = PROVISIONER_W4_AUTH_CONFIGURATION;
347 
348     // notify client and wait for auth method selection
349     uint8_t event[16] = { HCI_EVENT_MESH_META, 3, MESH_SUBEVENT_PB_PROV_CAPABILITIES};
350     little_endian_store_16(event, 3, pb_adv_cid);
351     event[5] = packet_data[0];
352     little_endian_store_16(event, 6, big_endian_read_16(packet_data, 1));
353     event[8] = packet_data[3];
354     event[9] = packet_data[4];
355     event[10] = packet_data[5];
356     little_endian_store_16(event, 11, big_endian_read_16(packet_data, 6));
357     event[13] = packet_data[8];
358     little_endian_store_16(event, 14, big_endian_read_16(packet_data, 9));
359     prov_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
360 }
361 
362 static void provisioning_handle_confirmation_provisioner_calculated(void * arg){
363     UNUSED(arg);
364 
365     printf("ConfirmationProvisioner: ");
366     printf_hexdump(confirmation_provisioner, sizeof(confirmation_provisioner));
367 
368     provisioner_state = PROVISIONER_SEND_CONFIRM;
369     provisioning_run();
370 }
371 
372 static void provisioning_handle_random_provisioner(void * arg){
373     printf("RandomProvisioner:   ");
374     printf_hexdump(random_provisioner, sizeof(random_provisioner));
375 
376     // re-use prov_confirmation_inputs buffer
377     memcpy(&prov_confirmation_inputs[0],  random_provisioner, 16);
378     memcpy(&prov_confirmation_inputs[16], auth_value, 16);
379 
380     // calc confirmation device
381     btstack_crypto_aes128_cmac_message(&prov_cmac_request, confirmation_key, 32, prov_confirmation_inputs, confirmation_provisioner, &provisioning_handle_confirmation_provisioner_calculated, NULL);
382 }
383 
384 static void provisioning_handle_confirmation_k1_calculated(void * arg){
385     printf("ConfirmationKey:   ");
386     printf_hexdump(confirmation_key, sizeof(confirmation_key));
387 
388     // generate random_device
389     btstack_crypto_random_generate(&prov_random_request,random_provisioner, 16, &provisioning_handle_random_provisioner, NULL);
390 }
391 
392 static void provisioning_handle_confirmation_salt(void * arg){
393     UNUSED(arg);
394 
395     // dump
396     printf("ConfirmationSalt:   ");
397     printf_hexdump(confirmation_salt, sizeof(confirmation_salt));
398 
399     // ConfirmationKey
400     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), confirmation_salt, (const uint8_t*) "prck", 4, confirmation_key, &provisioning_handle_confirmation_k1_calculated, NULL);
401 }
402 
403 static void provisioning_handle_auth_value_ready(void){
404     // CalculationInputs
405     printf("ConfirmationInputs: ");
406     printf_hexdump(prov_confirmation_inputs, sizeof(prov_confirmation_inputs));
407 
408     // calculate s1
409     btstack_crypto_aes128_cmac_zero(&prov_cmac_request, sizeof(prov_confirmation_inputs), prov_confirmation_inputs, confirmation_salt, &provisioning_handle_confirmation_salt, NULL);
410 }
411 
412 static void provisioning_handle_auth_value_input_oob(void * arg){
413 
414     // limit auth value to single digit
415     auth_value[15] = auth_value[15] % 9 + 1;
416     printf("Input OOB: %u\n", auth_value[15]);
417 
418     if (prov_authentication_string){
419         // strings start at 0 while numbers are stored as 16-byte big endian
420         auth_value[0] = auth_value[15] + '0';
421         auth_value[15] = 0;
422     }
423 
424     printf("AuthValue: ");
425     printf_hexdump(auth_value, sizeof(auth_value));
426 
427     // emit output oob value
428     provisioning_emit_output_oob_event(1, auth_value[15]);
429     prov_emit_output_oob_active = 1;
430 
431     provisioner_state = PROVISIONER_W4_INPUT_COMPLETE;
432 }
433 
434 static void provisioning_handle_input_complete(uint16_t pb_adv_cid){
435     provisioning_handle_auth_value_ready();
436 }
437 
438 static void provisioning_public_key_exchange_complete(void){
439     // reset auth_value
440     memset(auth_value, 0, sizeof(auth_value));
441 
442     // handle authentication method
443     switch (prov_start_authentication_method){
444         case 0x00:
445             provisioning_handle_auth_value_ready();
446             break;
447         case 0x01:
448             memcpy(&auth_value[16-prov_static_oob_len], prov_static_oob_data, prov_static_oob_len);
449             provisioning_handle_auth_value_ready();
450             break;
451         case 0x02:
452             // Output OOB
453             prov_authentication_string = prov_start_authentication_action == 0x04;
454             printf("Output OOB requested (and we're in Provisioniner role), string %u\n", prov_authentication_string);
455             provisioner_state = PROVISIONER_W4_INPUT_OOK;
456             provisioning_emit_event(MESH_SUBEVENT_PB_PROV_OUTPUT_OOB_REQUEST, 1);
457             break;
458         case 0x03:
459             // Input OOB
460             prov_authentication_string = prov_start_authentication_action == 0x03;
461             printf("Input OOB requested, string %u\n", prov_authentication_string);
462             printf("Generate random for auth_value\n");
463             // generate single byte of random data to use for authentication
464             btstack_crypto_random_generate(&prov_random_request, &auth_value[15], 1, &provisioning_handle_auth_value_input_oob, NULL);
465             provisioning_emit_event(MESH_SUBEVENT_PB_PROV_START_EMIT_INPUT_OOB, 1);
466             break;
467         default:
468             break;
469     }
470 }
471 
472 static void provisioning_handle_public_key_dhkey(void * arg){
473     UNUSED(arg);
474 
475     printf("DHKEY: ");
476     printf_hexdump(dhkey, sizeof(dhkey));
477 
478 #if 0
479     // skip sending own public key when public key oob is used
480     if (prov_public_key_oob_available && prov_public_key_oob_used){
481         // just copy key for confirmation inputs
482         memcpy(&prov_confirmation_inputs[81], prov_ec_q, 64);
483     } else {
484         // queue public key pdu
485         provisioning_queue_pdu(MESH_PROV_PUB_KEY);
486     }
487 #endif
488 
489     provisioning_public_key_exchange_complete();
490 }
491 
492 static void provisioning_public_key_ready(void){
493     // calculate DHKey
494     btstack_crypto_ecc_p256_calculate_dhkey(&prov_ecc_p256_request, remote_ec_q, dhkey, provisioning_handle_public_key_dhkey, NULL);
495 }
496 
497 static void provisioning_handle_public_key(uint16_t pb_adv_cid, const uint8_t *packet_data, uint16_t packet_len){
498 
499     // validate public key
500     if (packet_len != sizeof(remote_ec_q) || btstack_crypto_ecc_p256_validate_public_key(packet_data) != 0){
501         printf("Public Key invalid, abort provisioning\n");
502 
503         // disconnect provisioning link
504         pb_adv_close_link(pb_adv_cid, 0x02);    // reason: fail
505         provisioning_timer_stop();
506         return;
507     }
508 
509 #if 0
510     // stop emit public OOK if specified and send to crypto module
511     if (prov_public_key_oob_available && prov_public_key_oob_used){
512         provisioning_emit_event(MESH_PB_PROV_STOP_EMIT_PUBLIC_KEY_OOB, 1);
513 
514         printf("Replace generated ECC with Public Key OOB:");
515         memcpy(prov_ec_q, prov_public_key_oob_q, 64);
516         printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
517         btstack_crypto_ecc_p256_set_key(prov_public_key_oob_q, prov_public_key_oob_d);
518     }
519 #endif
520 
521     // store for confirmation inputs: len 64
522     memcpy(&prov_confirmation_inputs[81], packet_data, 64);
523 
524     // store remote q
525     memcpy(remote_ec_q, packet_data, sizeof(remote_ec_q));
526 
527     provisioning_public_key_ready();
528 }
529 
530 static void provisioning_handle_confirmation(uint16_t pb_adv_cid, const uint8_t *packet_data, uint16_t packet_len){
531 
532     UNUSED(packet_data);
533     UNUSED(packet_len);
534 
535     //
536     if (prov_emit_output_oob_active){
537         prov_emit_output_oob_active = 0;
538         provisioning_emit_event(MESH_SUBEVENT_PB_PROV_STOP_EMIT_OUTPUT_OOB, 1);
539     }
540 
541 #if 0
542     // CalculationInputs
543     printf("ConfirmationInputs: ");
544     printf_hexdump(prov_confirmation_inputs, sizeof(prov_confirmation_inputs));
545 
546     // calculate s1
547     btstack_crypto_aes128_cmac_zero(&prov_cmac_request, sizeof(prov_confirmation_inputs), prov_confirmation_inputs, confirmation_salt, &provisioning_handle_confirmation_s1_calculated, NULL);
548 #endif
549     provisioner_state = PROVISIONER_SEND_RANDOM;
550 }
551 
552 static void provisioning_handle_data_encrypted(void * arg){
553     UNUSED(arg);
554 
555     // enc_provisioning_data
556     printf("EncProvisioningData:   ");
557     printf_hexdump(enc_provisioning_data, sizeof(enc_provisioning_data));
558 
559     btstack_crypto_ccm_get_authentication_value(&prov_ccm_request, provisioning_data_mic);
560     printf("MIC:   ");
561     printf_hexdump(provisioning_data_mic, sizeof(provisioning_data_mic));
562 
563     // send
564     provisioner_state = PROVISIONER_SEND_DATA;
565     provisioning_run();
566 }
567 
568 static void provisioning_handle_session_nonce_calculated(void * arg){
569     UNUSED(arg);
570 
571     // The nonce shall be the 13 least significant octets == zero most significant octets
572     uint8_t temp[13];
573     memcpy(temp, &session_nonce[3], 13);
574     memcpy(session_nonce, temp, 13);
575 
576     // SessionNonce
577     printf("SessionNonce:   ");
578     printf_hexdump(session_nonce, 13);
579 
580     // setup provisioning data
581     memcpy(&provisioning_data[0], net_key, 16);
582     big_endian_store_16(provisioning_data, 16, net_key_index);
583     provisioning_data[18] = flags;
584     big_endian_store_32(provisioning_data, 19, iv_index);
585     big_endian_store_16(provisioning_data, 23, unicast_address);
586 
587     btstack_crypto_ccm_init(&prov_ccm_request, session_key, session_nonce, 25, 0, 8);
588     btstack_crypto_ccm_encrypt_block(&prov_ccm_request, 25, provisioning_data, enc_provisioning_data, &provisioning_handle_data_encrypted, NULL);
589 }
590 
591 static void provisioning_handle_session_key_calculated(void * arg){
592     UNUSED(arg);
593 
594     // SessionKey
595     printf("SessionKey:   ");
596     printf_hexdump(session_key, sizeof(session_key));
597 
598     // SessionNonce
599     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), provisioning_salt, (const uint8_t*) "prsn", 4, session_nonce, &provisioning_handle_session_nonce_calculated, NULL);
600 }
601 
602 
603 static void provisioning_handle_provisioning_salt_calculated(void * arg){
604     UNUSED(arg);
605 
606     // ProvisioningSalt
607     printf("ProvisioningSalt:   ");
608     printf_hexdump(provisioning_salt, sizeof(provisioning_salt));
609 
610     // SessionKey
611     mesh_k1(&prov_cmac_request, dhkey, sizeof(dhkey), provisioning_salt, (const uint8_t*) "prsk", 4, session_key, &provisioning_handle_session_key_calculated, NULL);
612 }
613 
614 static void provisioning_handle_random(uint16_t pb_adv_cid, const uint8_t *packet_data, uint16_t packet_len){
615 
616     UNUSED(packet_data);
617     UNUSED(packet_len);
618 
619     // TODO: validate Confirmation
620 
621     // calc ProvisioningSalt = s1(ConfirmationSalt || RandomProvisioner || RandomDevice)
622     memcpy(&prov_confirmation_inputs[0], confirmation_salt, 16);
623     memcpy(&prov_confirmation_inputs[16], random_provisioner, 16);
624     memcpy(&prov_confirmation_inputs[32], packet_data, 16);
625     btstack_crypto_aes128_cmac_zero(&prov_cmac_request, 48, prov_confirmation_inputs, provisioning_salt, &provisioning_handle_provisioning_salt_calculated, NULL);
626 }
627 
628 static void provisioning_handle_complete(uint16_t pb_adv_cid){
629 }
630 
631 static void provisioning_handle_pdu(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
632 
633     if (size < 1) return;
634 
635     switch (packet_type){
636         case HCI_EVENT_PACKET:
637             if (packet[0] != HCI_EVENT_MESH_META)  break;
638             switch (packet[2]){
639                 case MESH_SUBEVENT_PB_TRANSPORT_LINK_OPEN:
640                     printf("Link opened, sending Invite\n");
641                     provisioning_handle_link_opened(pb_adv_cid);
642                     break;
643                 case MESH_SUBEVENT_PB_TRANSPORT_PDU_SENT:
644                     printf("Outgoing packet acked\n");
645                     prov_waiting_for_outgoing_complete = 0;
646                     break;
647                 case MESH_SUBEVENT_PB_TRANSPORT_LINK_CLOSED:
648                     printf("Link close, reset state\n");
649                     provisioning_done();
650                     break;
651             }
652             break;
653         case PROVISIONING_DATA_PACKET:
654             // check state
655             switch (provisioner_state){
656                 case PROVISIONER_W4_CAPABILITIES:
657                     if (packet[0] != MESH_PROV_CAPABILITIES) provisioning_handle_provisioning_error(0x03);
658                     printf("MESH_PROV_CAPABILITIES: ");
659                     printf_hexdump(&packet[1], size-1);
660                     provisioning_handle_capabilities(pb_adv_cid, &packet[1], size-1);
661                     break;
662                 case PROVISIONER_W4_PUB_KEY:
663                     if (packet[0] != MESH_PROV_PUB_KEY) provisioning_handle_provisioning_error(0x03);
664                     printf("MESH_PROV_PUB_KEY: ");
665                     printf_hexdump(&packet[1], size-1);
666                     provisioning_handle_public_key(pb_adv_cid, &packet[1], size-1);
667                     break;
668                 case PROVISIONER_W4_INPUT_COMPLETE:
669                     if (packet[0] != MESH_PROV_INPUT_COMPLETE) provisioning_handle_provisioning_error(0x03);
670                     printf("MESH_PROV_INPUT_COMPLETE: ");
671                     printf_hexdump(&packet[1], size-1);
672                     provisioning_handle_input_complete(pb_adv_cid);
673                     break;
674                 case PROVISIONER_W4_CONFIRM:
675                     if (packet[0] != MESH_PROV_CONFIRM) provisioning_handle_provisioning_error(0x03);
676                     printf("MESH_PROV_CONFIRM: ");
677                     printf_hexdump(&packet[1], size-1);
678                     provisioning_handle_confirmation(pb_adv_cid, &packet[1], size-1);
679                     break;
680                 case PROVISIONER_W4_RANDOM:
681                     if (packet[0] != MESH_PROV_RANDOM) provisioning_handle_provisioning_error(0x03);
682                     printf("MESH_PROV_RANDOM:  ");
683                     printf_hexdump(&packet[1], size-1);
684                     provisioning_handle_random(pb_adv_cid, &packet[1], size-1);
685                     break;
686                 case PROVISIONER_W4_COMPLETE:
687                     if (packet[0] != MESH_PROV_COMPLETE) provisioning_handle_provisioning_error(0x03);
688                     printf("MESH_PROV_COMPLETE:  ");
689                     provisioning_handle_complete(pb_adv_cid);
690                     break;
691                 default:
692                     printf("TODO: handle provisioning state %x\n", provisioner_state);
693                     break;
694             }
695             break;
696         default:
697             break;
698     }
699     provisioning_run();
700 }
701 
702 static void prov_key_generated(void * arg){
703     UNUSED(arg);
704     printf("ECC-P256: ");
705     printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
706     // allow override
707     if (prov_public_key_oob_available){
708         printf("Replace generated ECC with Public Key OOB:");
709         memcpy(prov_ec_q, prov_public_key_oob_q, 64);
710         printf_hexdump(prov_ec_q, sizeof(prov_ec_q));
711         btstack_crypto_ecc_p256_set_key(prov_public_key_oob_q, prov_public_key_oob_d);
712     }
713 }
714 
715 void provisioning_provisioner_init(void){
716     pb_adv_cid = MESH_PB_TRANSPORT_INVALID_CID;
717     pb_adv_init();
718     pb_adv_register_packet_handler(&provisioning_handle_pdu);
719 }
720 
721 void provisioning_provisioner_register_packet_handler(btstack_packet_handler_t packet_handler){
722     prov_packet_handler = packet_handler;
723 }
724 
725 uint16_t provisioning_provisioner_start_provisioning(const uint8_t * device_uuid){
726     // generate new public key
727     btstack_crypto_ecc_p256_generate_key(&prov_ecc_p256_request, prov_ec_q, &prov_key_generated, NULL);
728 
729     if (pb_adv_cid == MESH_PB_TRANSPORT_INVALID_CID) {
730         pb_adv_cid = pb_adv_create_link(device_uuid);
731     }
732     return pb_adv_cid;
733 }
734 
735 void provisioning_provisioner_set_static_oob(uint16_t pb_adv_cid, uint16_t static_oob_len, const uint8_t * static_oob_data){
736     UNUSED(pb_adv_cid);
737     prov_static_oob_data = static_oob_data;
738     prov_static_oob_len  = btstack_min(static_oob_len, 16);
739 }
740 
741 uint8_t provisioning_provisioner_select_authentication_method(uint16_t pb_adv_cid, uint8_t algorithm, uint8_t public_key_used, uint8_t authentication_method, uint8_t authentication_action, uint8_t authentication_size){
742 
743     if (provisioner_state != PROVISIONER_W4_AUTH_CONFIGURATION) return ERROR_CODE_COMMAND_DISALLOWED;
744 
745     prov_start_algorithm = algorithm;
746     prov_start_public_key_used = public_key_used;
747     prov_start_authentication_method = authentication_method;
748     prov_start_authentication_action = authentication_action;
749     prov_start_authentication_size   = authentication_size;
750     provisioner_state = PROVISIONER_SEND_START;
751 
752     return ERROR_CODE_SUCCESS;
753 }
754 
755 uint8_t provisioning_provisioner_public_key_oob_received(uint16_t pb_adv_cid, const uint8_t * public_key){
756 
757     if (provisioner_state != PROVISIONER_W4_PUB_KEY_OOB) return ERROR_CODE_COMMAND_DISALLOWED;
758 
759     // store for confirmation inputs: len 64
760     memcpy(&prov_confirmation_inputs[81], public_key, 64);
761 
762     // store remote q
763     memcpy(remote_ec_q, public_key, sizeof(remote_ec_q));
764 
765     // continue procedure
766     provisioner_state = PROVISIONER_SEND_PUB_KEY;
767     provisioning_run();
768 
769     return ERROR_CODE_SUCCESS;
770 }
771 
772 void provisioning_provisioner_input_oob_complete_numeric(uint16_t pb_adv_cid, uint32_t input_oob){
773     UNUSED(pb_adv_cid);
774     if (provisioner_state != PROVISIONER_W4_INPUT_OOK) return;
775 
776     // store input_oob as auth value
777     big_endian_store_32(auth_value, 12, input_oob);
778     provisioning_handle_auth_value_ready();
779 }
780 
781 void provisioning_provisioner_input_oob_complete_alphanumeric(uint16_t pb_adv_cid, const uint8_t * input_oob_data, uint16_t input_oob_len){
782     UNUSED(pb_adv_cid);
783     if (provisioner_state != PROVISIONER_W4_INPUT_OOK) return;
784 
785     // store input_oob and fillup with zeros
786     input_oob_len = btstack_min(input_oob_len, 16);
787     memset(auth_value, 0, 16);
788     memcpy(auth_value, input_oob_data, input_oob_len);
789     provisioning_handle_auth_value_ready();
790 }
791 
792