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