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