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