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