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