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