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