sm.c (9305033e0290a73b79a29900c5b9f35f77d880b1) | sm.c (1979f09cf045e87f55a9cd8067e8ef902cc8d78b) |
---|---|
1/* 2 * Copyright (C) 2014 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 --- 181 unchanged lines hidden (view full) --- 190// configuration 191static uint8_t sm_accepted_stk_generation_methods; 192static uint8_t sm_max_encryption_key_size; 193static uint8_t sm_min_encryption_key_size; 194static uint8_t sm_auth_req = 0; 195static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT; 196static uint8_t sm_slave_request_security; 197static uint32_t sm_fixed_passkey_in_display_role; | 1/* 2 * Copyright (C) 2014 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 --- 181 unchanged lines hidden (view full) --- 190// configuration 191static uint8_t sm_accepted_stk_generation_methods; 192static uint8_t sm_max_encryption_key_size; 193static uint8_t sm_min_encryption_key_size; 194static uint8_t sm_auth_req = 0; 195static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT; 196static uint8_t sm_slave_request_security; 197static uint32_t sm_fixed_passkey_in_display_role; |
198static uint8_t sm_reconstruct_ltk_without_le_device_db_entry; | 198static bool sm_reconstruct_ltk_without_le_device_db_entry; |
199 200#ifdef ENABLE_LE_SECURE_CONNECTIONS 201static bool sm_sc_only_mode; 202static uint8_t sm_sc_oob_random[16]; 203static void (*sm_sc_oob_callback)(const uint8_t * confirm_value, const uint8_t * random_value); 204static sm_sc_oob_state_t sm_sc_oob_state; 205#endif 206 207 | 199 200#ifdef ENABLE_LE_SECURE_CONNECTIONS 201static bool sm_sc_only_mode; 202static uint8_t sm_sc_oob_random[16]; 203static void (*sm_sc_oob_callback)(const uint8_t * confirm_value, const uint8_t * random_value); 204static sm_sc_oob_state_t sm_sc_oob_state; 205#endif 206 207 |
208static uint8_t sm_persistent_keys_random_active; | 208static bool sm_persistent_keys_random_active; |
209static const btstack_tlv_t * sm_tlv_impl; 210static void * sm_tlv_context; 211 212// Security Manager Master Keys, please use sm_set_er(er) and sm_set_ir(ir) with your own 128 bit random values 213static sm_key_t sm_persistent_er; 214static sm_key_t sm_persistent_ir; 215 216// derived from sm_persistent_ir --- 243 unchanged lines hidden (view full) --- 460static inline void sm_pairing_packet_set_initiator_key_distribution(sm_pairing_packet_t packet, uint8_t initiator_key_distribution){ 461 packet[5] = initiator_key_distribution; 462} 463static inline void sm_pairing_packet_set_responder_key_distribution(sm_pairing_packet_t packet, uint8_t responder_key_distribution){ 464 packet[6] = responder_key_distribution; 465} 466 467// @returns 1 if all bytes are 0 | 209static const btstack_tlv_t * sm_tlv_impl; 210static void * sm_tlv_context; 211 212// Security Manager Master Keys, please use sm_set_er(er) and sm_set_ir(ir) with your own 128 bit random values 213static sm_key_t sm_persistent_er; 214static sm_key_t sm_persistent_ir; 215 216// derived from sm_persistent_ir --- 243 unchanged lines hidden (view full) --- 460static inline void sm_pairing_packet_set_initiator_key_distribution(sm_pairing_packet_t packet, uint8_t initiator_key_distribution){ 461 packet[5] = initiator_key_distribution; 462} 463static inline void sm_pairing_packet_set_responder_key_distribution(sm_pairing_packet_t packet, uint8_t responder_key_distribution){ 464 packet[6] = responder_key_distribution; 465} 466 467// @returns 1 if all bytes are 0 |
468static int sm_is_null(uint8_t * data, int size){ | 468static bool sm_is_null(uint8_t * data, int size){ |
469 int i; 470 for (i=0; i < size ; i++){ 471 if (data[i] != 0) { | 469 int i; 470 for (i=0; i < size ; i++){ 471 if (data[i] != 0) { |
472 return 0; | 472 return false; |
473 } 474 } | 473 } 474 } |
475 return 1; | 475 return true; |
476} 477 | 476} 477 |
478static int sm_is_null_random(uint8_t random[8]){ | 478static bool sm_is_null_random(uint8_t random[8]){ |
479 return sm_is_null(random, 8); 480} 481 | 479 return sm_is_null(random, 8); 480} 481 |
482static int sm_is_null_key(uint8_t * key){ | 482static bool sm_is_null_key(uint8_t * key){ |
483 return sm_is_null(key, 16); 484} 485 486// sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 487static void sm_run_timer_handler(btstack_timer_source_t * ts){ 488 UNUSED(ts); 489 sm_run(); 490} --- 346 unchanged lines hidden (view full) --- 837 & SM_AUTHREQ_SECURE_CONNECTION ) != 0u; 838#else 839 setup->sm_use_secure_connections = 0; 840#endif 841 log_info("Secure pairing: %u", setup->sm_use_secure_connections); 842 843 844 // decide if OOB will be used based on SC vs. Legacy and oob flags | 483 return sm_is_null(key, 16); 484} 485 486// sm_trigger_run allows to schedule callback from main run loop // reduces stack depth 487static void sm_run_timer_handler(btstack_timer_source_t * ts){ 488 UNUSED(ts); 489 sm_run(); 490} --- 346 unchanged lines hidden (view full) --- 837 & SM_AUTHREQ_SECURE_CONNECTION ) != 0u; 838#else 839 setup->sm_use_secure_connections = 0; 840#endif 841 log_info("Secure pairing: %u", setup->sm_use_secure_connections); 842 843 844 // decide if OOB will be used based on SC vs. Legacy and oob flags |
845 int use_oob = 0; | 845 bool use_oob; |
846 if (setup->sm_use_secure_connections){ 847 // In LE Secure Connections pairing, the out of band method is used if at least 848 // one device has the peer device's out of band authentication data available. | 846 if (setup->sm_use_secure_connections){ 847 // In LE Secure Connections pairing, the out of band method is used if at least 848 // one device has the peer device's out of band authentication data available. |
849 use_oob = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) | sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); | 849 use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) | sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; |
850 } else { 851 // In LE legacy pairing, the out of band method is used if both the devices have 852 // the other device's out of band authentication data available. | 850 } else { 851 // In LE legacy pairing, the out of band method is used if both the devices have 852 // the other device's out of band authentication data available. |
853 use_oob = sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) & sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres); | 853 use_oob = (sm_pairing_packet_get_oob_data_flag(setup->sm_m_preq) & sm_pairing_packet_get_oob_data_flag(setup->sm_s_pres)) != 0; |
854 } 855 if (use_oob){ 856 log_info("SM: have OOB data"); 857 log_info_key("OOB", setup->sm_tk); 858 setup->sm_stk_generation_method = OOB; 859 return; 860 } 861 --- 394 unchanged lines hidden (view full) --- 1256 // reset context 1257 sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 1258 sm_address_resolution_context = NULL; 1259 sm_address_resolution_test = -1; 1260 hci_con_handle_t con_handle = 0; 1261 1262 sm_connection_t * sm_connection; 1263 sm_key_t ltk; | 854 } 855 if (use_oob){ 856 log_info("SM: have OOB data"); 857 log_info_key("OOB", setup->sm_tk); 858 setup->sm_stk_generation_method = OOB; 859 return; 860 } 861 --- 394 unchanged lines hidden (view full) --- 1256 // reset context 1257 sm_address_resolution_mode = ADDRESS_RESOLUTION_IDLE; 1258 sm_address_resolution_context = NULL; 1259 sm_address_resolution_test = -1; 1260 hci_con_handle_t con_handle = 0; 1261 1262 sm_connection_t * sm_connection; 1263 sm_key_t ltk; |
1264 int have_ltk; | 1264 bool have_ltk; |
1265#ifdef ENABLE_LE_CENTRAL | 1265#ifdef ENABLE_LE_CENTRAL |
1266 int trigger_pairing; | 1266 bool trigger_pairing; |
1267#endif 1268 switch (mode){ 1269 case ADDRESS_RESOLUTION_GENERAL: 1270 break; 1271 case ADDRESS_RESOLUTION_FOR_CONNECTION: 1272 sm_connection = (sm_connection_t *) context; 1273 con_handle = sm_connection->sm_handle; 1274 --- 25 unchanged lines hidden (view full) --- 1300 bool trigger_security_request = (sm_connection->sm_pairing_requested != 0) || (sm_slave_request_security != 0); 1301 sm_connection->sm_pairing_requested = 0; 1302#ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1303 // trigger security request for Proactive Authentication if LTK available 1304 trigger_security_request = trigger_security_request || have_ltk; 1305#endif 1306 1307 log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", | 1267#endif 1268 switch (mode){ 1269 case ADDRESS_RESOLUTION_GENERAL: 1270 break; 1271 case ADDRESS_RESOLUTION_FOR_CONNECTION: 1272 sm_connection = (sm_connection_t *) context; 1273 con_handle = sm_connection->sm_handle; 1274 --- 25 unchanged lines hidden (view full) --- 1300 bool trigger_security_request = (sm_connection->sm_pairing_requested != 0) || (sm_slave_request_security != 0); 1301 sm_connection->sm_pairing_requested = 0; 1302#ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1303 // trigger security request for Proactive Authentication if LTK available 1304 trigger_security_request = trigger_security_request || have_ltk; 1305#endif 1306 1307 log_info("peripheral: pairing request local %u, have_ltk %u => trigger_security_request %u", |
1308 sm_connection->sm_pairing_requested, have_ltk, trigger_security_request); | 1308 sm_connection->sm_pairing_requested, (int) have_ltk, trigger_security_request); |
1309 1310 if (trigger_security_request){ 1311 sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 1312 if (have_ltk){ 1313 sm_reencryption_started(sm_connection); 1314 } else { 1315 sm_pairing_started(sm_connection); 1316 } 1317 sm_trigger_run(); 1318 } 1319#endif 1320 } else { 1321 1322#ifdef ENABLE_LE_CENTRAL 1323 // check if pairing already requested and reset requests 1324 trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 1325 log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", | 1309 1310 if (trigger_security_request){ 1311 sm_connection->sm_engine_state = SM_RESPONDER_SEND_SECURITY_REQUEST; 1312 if (have_ltk){ 1313 sm_reencryption_started(sm_connection); 1314 } else { 1315 sm_pairing_started(sm_connection); 1316 } 1317 sm_trigger_run(); 1318 } 1319#endif 1320 } else { 1321 1322#ifdef ENABLE_LE_CENTRAL 1323 // check if pairing already requested and reset requests 1324 trigger_pairing = sm_connection->sm_pairing_requested || sm_connection->sm_security_request_received; 1325 log_info("central: pairing request local %u, remote %u => trigger_pairing %u. have_ltk %u", |
1326 sm_connection->sm_pairing_requested, sm_connection->sm_security_request_received, trigger_pairing, have_ltk); | 1326 sm_connection->sm_pairing_requested, sm_connection->sm_security_request_received, (int) trigger_pairing, (int) have_ltk); |
1327 sm_connection->sm_security_request_received = 0; 1328 sm_connection->sm_pairing_requested = 0; 1329 bool trigger_reencryption = false; 1330 1331 if (have_ltk){ 1332#ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1333 trigger_reencryption = true; 1334#else --- 67 unchanged lines hidden (view full) --- 1402 } 1403} 1404 1405static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 1406 1407 int le_db_index = -1; 1408 1409 // only store pairing information if both sides are bondable, i.e., the bonadble flag is set | 1327 sm_connection->sm_security_request_received = 0; 1328 sm_connection->sm_pairing_requested = 0; 1329 bool trigger_reencryption = false; 1330 1331 if (have_ltk){ 1332#ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1333 trigger_reencryption = true; 1334#else --- 67 unchanged lines hidden (view full) --- 1402 } 1403} 1404 1405static void sm_key_distribution_handle_all_received(sm_connection_t * sm_conn){ 1406 1407 int le_db_index = -1; 1408 1409 // only store pairing information if both sides are bondable, i.e., the bonadble flag is set |
1410 int bonding_enabed = ( sm_pairing_packet_get_auth_req(setup->sm_m_preq) | 1410 bool bonding_enabed = ( sm_pairing_packet_get_auth_req(setup->sm_m_preq) |
1411 & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 1412 & SM_AUTHREQ_BONDING ) != 0u; 1413 1414 if (bonding_enabed){ 1415 1416 // lookup device based on IRK 1417 if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){ 1418 int i; --- 792 unchanged lines hidden (view full) --- 2211static void sm_run_activate_connection(void){ 2212 // Find connections that requires setup context and make active if no other is locked 2213 btstack_linked_list_iterator_t it; 2214 hci_connections_get_iterator(&it); 2215 while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2216 hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 2217 sm_connection_t * sm_connection = &hci_connection->sm_connection; 2218 // - if no connection locked and we're ready/waiting for setup context, fetch it and start | 1411 & sm_pairing_packet_get_auth_req(setup->sm_s_pres) 1412 & SM_AUTHREQ_BONDING ) != 0u; 1413 1414 if (bonding_enabed){ 1415 1416 // lookup device based on IRK 1417 if (setup->sm_key_distribution_received_set & SM_KEYDIST_FLAG_IDENTITY_INFORMATION){ 1418 int i; --- 792 unchanged lines hidden (view full) --- 2211static void sm_run_activate_connection(void){ 2212 // Find connections that requires setup context and make active if no other is locked 2213 btstack_linked_list_iterator_t it; 2214 hci_connections_get_iterator(&it); 2215 while((sm_active_connection_handle == HCI_CON_HANDLE_INVALID) && btstack_linked_list_iterator_has_next(&it)){ 2216 hci_connection_t * hci_connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it); 2217 sm_connection_t * sm_connection = &hci_connection->sm_connection; 2218 // - if no connection locked and we're ready/waiting for setup context, fetch it and start |
2219 int done = 1; | 2219 bool done = true; |
2220 int err; 2221 UNUSED(err); 2222 2223#ifdef ENABLE_LE_SECURE_CONNECTIONS 2224 // assert ec key is ready 2225 if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2226 || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2227 || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ --- 17 unchanged lines hidden (view full) --- 2245#endif 2246#ifdef ENABLE_LE_CENTRAL 2247 case SM_INITIATOR_PH4_HAS_LTK: 2248 case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2249#endif 2250 // just lock context 2251 break; 2252 default: | 2220 int err; 2221 UNUSED(err); 2222 2223#ifdef ENABLE_LE_SECURE_CONNECTIONS 2224 // assert ec key is ready 2225 if ( (sm_connection->sm_engine_state == SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED) 2226 || (sm_connection->sm_engine_state == SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST) 2227 || (sm_connection->sm_engine_state == SM_RESPONDER_SEND_SECURITY_REQUEST)){ --- 17 unchanged lines hidden (view full) --- 2245#endif 2246#ifdef ENABLE_LE_CENTRAL 2247 case SM_INITIATOR_PH4_HAS_LTK: 2248 case SM_INITIATOR_PH1_W2_SEND_PAIRING_REQUEST: 2249#endif 2250 // just lock context 2251 break; 2252 default: |
2253 done = 0; | 2253 done = false; |
2254 break; 2255 } 2256 if (done){ 2257 sm_active_connection_handle = sm_connection->sm_handle; 2258 log_info("sm: connection 0x%04x locked setup context as %s, state %u", sm_active_connection_handle, sm_connection->sm_role ? "responder" : "initiator", sm_connection->sm_engine_state); 2259 } 2260 } 2261} --- 64 unchanged lines hidden (view full) --- 2326 // send keypress notifications 2327 if (setup->sm_keypress_notification){ 2328 int i; 2329 uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2330 uint8_t num_actions = setup->sm_keypress_notification >> 5; 2331 uint8_t action = 0; 2332 for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 2333 if (flags & (1u<<i)){ | 2254 break; 2255 } 2256 if (done){ 2257 sm_active_connection_handle = sm_connection->sm_handle; 2258 log_info("sm: connection 0x%04x locked setup context as %s, state %u", sm_active_connection_handle, sm_connection->sm_role ? "responder" : "initiator", sm_connection->sm_engine_state); 2259 } 2260 } 2261} --- 64 unchanged lines hidden (view full) --- 2326 // send keypress notifications 2327 if (setup->sm_keypress_notification){ 2328 int i; 2329 uint8_t flags = setup->sm_keypress_notification & 0x1fu; 2330 uint8_t num_actions = setup->sm_keypress_notification >> 5; 2331 uint8_t action = 0; 2332 for (i=SM_KEYPRESS_PASSKEY_ENTRY_STARTED;i<=SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED;i++){ 2333 if (flags & (1u<<i)){ |
2334 int clear_flag = 1; | 2334 bool clear_flag = true; |
2335 switch (i){ 2336 case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2337 case SM_KEYPRESS_PASSKEY_CLEARED: 2338 case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2339 default: 2340 break; 2341 case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2342 case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: --- 136 unchanged lines hidden (view full) --- 2479 l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 2480 sm_timeout_reset(connection); 2481 break; 2482#endif 2483 2484#ifdef ENABLE_LE_SECURE_CONNECTIONS 2485 2486 case SM_SC_SEND_PUBLIC_KEY_COMMAND: { | 2335 switch (i){ 2336 case SM_KEYPRESS_PASSKEY_ENTRY_STARTED: 2337 case SM_KEYPRESS_PASSKEY_CLEARED: 2338 case SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED: 2339 default: 2340 break; 2341 case SM_KEYPRESS_PASSKEY_DIGIT_ENTERED: 2342 case SM_KEYPRESS_PASSKEY_DIGIT_ERASED: --- 136 unchanged lines hidden (view full) --- 2479 l2cap_send_connectionless(connection->sm_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) &setup->sm_m_preq, sizeof(sm_pairing_packet_t)); 2480 sm_timeout_reset(connection); 2481 break; 2482#endif 2483 2484#ifdef ENABLE_LE_SECURE_CONNECTIONS 2485 2486 case SM_SC_SEND_PUBLIC_KEY_COMMAND: { |
2487 int trigger_user_response = 0; 2488 int trigger_start_calculating_local_confirm = 0; | 2487 bool trigger_user_response = false; 2488 bool trigger_start_calculating_local_confirm = false; |
2489 uint8_t buffer[65]; 2490 buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2491 // 2492 reverse_256(&ec_q[0], &buffer[1]); 2493 reverse_256(&ec_q[32], &buffer[33]); 2494 2495#ifdef ENABLE_TESTING_SUPPORT 2496 if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ --- 5 unchanged lines hidden (view full) --- 2502 2503 // stk generation method 2504 // passkey entry: notify app to show passkey or to request passkey 2505 switch (setup->sm_stk_generation_method){ 2506 case JUST_WORKS: 2507 case NUMERIC_COMPARISON: 2508 if (IS_RESPONDER(connection->sm_role)){ 2509 // responder | 2489 uint8_t buffer[65]; 2490 buffer[0] = SM_CODE_PAIRING_PUBLIC_KEY; 2491 // 2492 reverse_256(&ec_q[0], &buffer[1]); 2493 reverse_256(&ec_q[32], &buffer[33]); 2494 2495#ifdef ENABLE_TESTING_SUPPORT 2496 if (test_pairing_failure == SM_REASON_DHKEY_CHECK_FAILED){ --- 5 unchanged lines hidden (view full) --- 2502 2503 // stk generation method 2504 // passkey entry: notify app to show passkey or to request passkey 2505 switch (setup->sm_stk_generation_method){ 2506 case JUST_WORKS: 2507 case NUMERIC_COMPARISON: 2508 if (IS_RESPONDER(connection->sm_role)){ 2509 // responder |
2510 trigger_start_calculating_local_confirm = 1; | 2510 trigger_start_calculating_local_confirm = true; |
2511 connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2512 } else { 2513 // initiator 2514 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2515 } 2516 break; 2517 case PK_INIT_INPUT: 2518 case PK_RESP_INPUT: --- 5 unchanged lines hidden (view full) --- 2524 2525 if (IS_RESPONDER(connection->sm_role)){ 2526 // responder 2527 connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2528 } else { 2529 // initiator 2530 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2531 } | 2511 connection->sm_engine_state = SM_SC_W4_LOCAL_NONCE; 2512 } else { 2513 // initiator 2514 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2515 } 2516 break; 2517 case PK_INIT_INPUT: 2518 case PK_RESP_INPUT: --- 5 unchanged lines hidden (view full) --- 2524 2525 if (IS_RESPONDER(connection->sm_role)){ 2526 // responder 2527 connection->sm_engine_state = SM_SC_W4_CONFIRMATION; 2528 } else { 2529 // initiator 2530 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; 2531 } |
2532 trigger_user_response = 1; | 2532 trigger_user_response = true; |
2533 break; 2534 case OOB: 2535 if (IS_RESPONDER(connection->sm_role)){ 2536 // responder 2537 connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2538 } else { 2539 // initiator 2540 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; --- 798 unchanged lines hidden (view full) --- 3339 // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 3340 setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 3341 // no db for authenticated flag hack: store flag in bit 4 of LSB 3342 setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 3343 btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 2, &sm_handle_random_result_ph3_div, (void *)(uintptr_t) connection->sm_handle); 3344} 3345static void sm_validate_er_ir(void){ 3346 // warn about default ER/IR | 2533 break; 2534 case OOB: 2535 if (IS_RESPONDER(connection->sm_role)){ 2536 // responder 2537 connection->sm_engine_state = SM_SC_W4_PAIRING_RANDOM; 2538 } else { 2539 // initiator 2540 connection->sm_engine_state = SM_SC_W4_PUBLIC_KEY_COMMAND; --- 798 unchanged lines hidden (view full) --- 3339 // no db for encryption size hack: encryption size is stored in lowest nibble of setup->sm_local_rand 3340 setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xf0u) + (connection->sm_actual_encryption_key_size - 1u); 3341 // no db for authenticated flag hack: store flag in bit 4 of LSB 3342 setup->sm_local_rand[7u] = (setup->sm_local_rand[7u] & 0xefu) + (connection->sm_connection_authenticated << 4u); 3343 btstack_crypto_random_generate(&sm_crypto_random_request, sm_random_data, 2, &sm_handle_random_result_ph3_div, (void *)(uintptr_t) connection->sm_handle); 3344} 3345static void sm_validate_er_ir(void){ 3346 // warn about default ER/IR |
3347 int warning = 0; | 3347 bool warning = false; |
3348 if (sm_ir_is_default()){ | 3348 if (sm_ir_is_default()){ |
3349 warning = 1; | 3349 warning = true; |
3350 log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3351 } 3352 if (sm_er_is_default()){ | 3350 log_error("Persistent IR not set with sm_set_ir. Use of private addresses will cause pairing issues"); 3351 } 3352 if (sm_er_is_default()){ |
3353 warning = 1; | 3353 warning = true; |
3354 log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3355 } 3356 if (warning) { 3357 log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3358 } 3359} 3360 3361static void sm_handle_random_result_ir(void *arg){ | 3354 log_error("Persistent ER not set with sm_set_er. Legacy Pairing LTK is not secure"); 3355 } 3356 if (warning) { 3357 log_error("Please configure btstack_tlv to let BTstack setup ER and IR keys"); 3358 } 3359} 3360 3361static void sm_handle_random_result_ir(void *arg){ |
3362 sm_persistent_keys_random_active = 0; | 3362 sm_persistent_keys_random_active = false; |
3363 if (arg != NULL){ 3364 // key generated, store in tlv 3365 int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3366 log_info("Generated IR key. Store in TLV status: %d", status); 3367 UNUSED(status); 3368 } 3369 log_info_key("IR", sm_persistent_ir); 3370 dkg_state = DKG_CALC_IRK; 3371 3372 if (test_use_fixed_local_irk){ 3373 log_info_key("IRK", sm_persistent_irk); 3374 dkg_state = DKG_CALC_DHK; 3375 } 3376 3377 sm_trigger_run(); 3378} 3379 3380static void sm_handle_random_result_er(void *arg){ | 3363 if (arg != NULL){ 3364 // key generated, store in tlv 3365 int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3366 log_info("Generated IR key. Store in TLV status: %d", status); 3367 UNUSED(status); 3368 } 3369 log_info_key("IR", sm_persistent_ir); 3370 dkg_state = DKG_CALC_IRK; 3371 3372 if (test_use_fixed_local_irk){ 3373 log_info_key("IRK", sm_persistent_irk); 3374 dkg_state = DKG_CALC_DHK; 3375 } 3376 3377 sm_trigger_run(); 3378} 3379 3380static void sm_handle_random_result_er(void *arg){ |
3381 sm_persistent_keys_random_active = 0; | 3381 sm_persistent_keys_random_active = false; |
3382 if (arg != 0){ 3383 // key generated, store in tlv 3384 int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3385 log_info("Generated ER key. Store in TLV status: %d", status); 3386 UNUSED(status); 3387 } 3388 log_info_key("ER", sm_persistent_er); 3389 3390 // try load ir 3391 int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3392 if (key_size == 16){ 3393 // ok, let's continue 3394 log_info("IR from TLV"); 3395 sm_handle_random_result_ir( NULL ); 3396 } else { 3397 // invalid, generate new random one | 3382 if (arg != 0){ 3383 // key generated, store in tlv 3384 int status = sm_tlv_impl->store_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3385 log_info("Generated ER key. Store in TLV status: %d", status); 3386 UNUSED(status); 3387 } 3388 log_info_key("ER", sm_persistent_er); 3389 3390 // try load ir 3391 int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','I','R'), sm_persistent_ir, 16u); 3392 if (key_size == 16){ 3393 // ok, let's continue 3394 log_info("IR from TLV"); 3395 sm_handle_random_result_ir( NULL ); 3396 } else { 3397 // invalid, generate new random one |
3398 sm_persistent_keys_random_active = 1; | 3398 sm_persistent_keys_random_active = true; |
3399 btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3400 } 3401} 3402 3403static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 3404 3405 UNUSED(channel); // ok: there is no channel 3406 UNUSED(size); // ok: fixed format HCI events --- 16 unchanged lines hidden (view full) --- 3423 if (sm_tlv_impl != NULL){ 3424 int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3425 if (key_size == 16){ 3426 // ok, let's continue 3427 log_info("ER from TLV"); 3428 sm_handle_random_result_er( NULL ); 3429 } else { 3430 // invalid, generate random one | 3399 btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_ir, 16, &sm_handle_random_result_ir, &sm_persistent_ir); 3400 } 3401} 3402 3403static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 3404 3405 UNUSED(channel); // ok: there is no channel 3406 UNUSED(size); // ok: fixed format HCI events --- 16 unchanged lines hidden (view full) --- 3423 if (sm_tlv_impl != NULL){ 3424 int key_size = sm_tlv_impl->get_tag(sm_tlv_context, BTSTACK_TAG32('S','M','E','R'), sm_persistent_er, 16u); 3425 if (key_size == 16){ 3426 // ok, let's continue 3427 log_info("ER from TLV"); 3428 sm_handle_random_result_er( NULL ); 3429 } else { 3430 // invalid, generate random one |
3431 sm_persistent_keys_random_active = 1; | 3431 sm_persistent_keys_random_active = true; |
3432 btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3433 } 3434 } else { 3435 sm_validate_er_ir(); 3436 dkg_state = DKG_CALC_IRK; 3437 3438 if (test_use_fixed_local_irk){ 3439 log_info_key("IRK", sm_persistent_irk); --- 914 unchanged lines hidden (view full) --- 4354 | SM_STK_GENERATION_METHOD_OOB 4355 | SM_STK_GENERATION_METHOD_PASSKEY 4356 | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 4357 4358 sm_max_encryption_key_size = 16; 4359 sm_min_encryption_key_size = 7; 4360 4361 sm_fixed_passkey_in_display_role = 0xffffffff; | 3432 btstack_crypto_random_generate(&sm_crypto_random_request, sm_persistent_er, 16, &sm_handle_random_result_er, &sm_persistent_er); 3433 } 3434 } else { 3435 sm_validate_er_ir(); 3436 dkg_state = DKG_CALC_IRK; 3437 3438 if (test_use_fixed_local_irk){ 3439 log_info_key("IRK", sm_persistent_irk); --- 914 unchanged lines hidden (view full) --- 4354 | SM_STK_GENERATION_METHOD_OOB 4355 | SM_STK_GENERATION_METHOD_PASSKEY 4356 | SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON; 4357 4358 sm_max_encryption_key_size = 16; 4359 sm_min_encryption_key_size = 7; 4360 4361 sm_fixed_passkey_in_display_role = 0xffffffff; |
4362 sm_reconstruct_ltk_without_le_device_db_entry = 1; | 4362 sm_reconstruct_ltk_without_le_device_db_entry = true; |
4363 4364#ifdef USE_CMAC_ENGINE 4365 sm_cmac_active = 0; 4366#endif 4367 dkg_state = DKG_W4_WORKING; 4368 rau_state = RAU_IDLE; 4369 sm_aes128_state = SM_AES128_IDLE; 4370 sm_address_resolution_test = -1; // no private address to resolve yet --- 26 unchanged lines hidden (view full) --- 4397#endif 4398} 4399 4400void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 4401 sm_fixed_passkey_in_display_role = passkey; 4402} 4403 4404void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ | 4363 4364#ifdef USE_CMAC_ENGINE 4365 sm_cmac_active = 0; 4366#endif 4367 dkg_state = DKG_W4_WORKING; 4368 rau_state = RAU_IDLE; 4369 sm_aes128_state = SM_AES128_IDLE; 4370 sm_address_resolution_test = -1; // no private address to resolve yet --- 26 unchanged lines hidden (view full) --- 4397#endif 4398} 4399 4400void sm_use_fixed_passkey_in_display_role(uint32_t passkey){ 4401 sm_fixed_passkey_in_display_role = passkey; 4402} 4403 4404void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){ |
4405 sm_reconstruct_ltk_without_le_device_db_entry = allow; | 4405 sm_reconstruct_ltk_without_le_device_db_entry = allow != 0; |
4406} 4407 4408static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 4409 hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 4410 if (!hci_con) return NULL; 4411 return &hci_con->sm_connection; 4412} 4413 --- 394 unchanged lines hidden --- | 4406} 4407 4408static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){ 4409 hci_connection_t * hci_con = hci_connection_for_handle(con_handle); 4410 if (!hci_con) return NULL; 4411 return &hci_con->sm_connection; 4412} 4413 --- 394 unchanged lines hidden --- |