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 ---