store sm_s_stk in sm_s_ltk

This commit is contained in:
matthias.ringwald@gmail.com 2013-11-29 22:53:26 +00:00
parent eabb4ec387
commit 9383decc66

View File

@ -251,6 +251,8 @@ static bd_addr_t sm_s_address;
// PER INSTANCE DATA // PER INSTANCE DATA
static security_manager_state_t sm_state_responding = SM_STATE_IDLE; static security_manager_state_t sm_state_responding = SM_STATE_IDLE;
static uint16_t sm_response_handle = 0;
static uint8_t sm_pairing_failed_reason = 0;
// SM timeout // SM timeout
static timer_source_t sm_timeout; static timer_source_t sm_timeout;
@ -259,12 +261,12 @@ static timer_source_t sm_timeout;
static key_t sm_aes128_key; static key_t sm_aes128_key;
static key_t sm_aes128_plaintext; static key_t sm_aes128_plaintext;
// // generation method and temporary key for STK - STK is stored in sm_s_ltk
static uint16_t sm_response_handle = 0;
// generation method and temporary key for STK
static stk_generation_method_t sm_stk_generation_method; static stk_generation_method_t sm_stk_generation_method;
static key_t sm_tk; static key_t sm_tk;
// user response
static uint8_t sm_user_response;
// defines which keys will be send after connection is encrypted // defines which keys will be send after connection is encrypted
static int sm_key_distribution_send_set; static int sm_key_distribution_send_set;
@ -276,24 +278,22 @@ static int sm_key_distribution_received_set;
// The device in the slave role shall be the responding device." // The device in the slave role shall be the responding device."
// -> master := initiator, slave := responder // -> master := initiator, slave := responder
// //
static key_t sm_m_random; static key_t sm_m_random;
static key_t sm_m_confirm; static key_t sm_m_confirm;
static uint8_t sm_m_have_oob_data; static uint8_t sm_m_have_oob_data;
static uint8_t sm_m_auth_req; static uint8_t sm_m_auth_req;
static uint8_t sm_m_io_capabilities = 0; static uint8_t sm_m_io_capabilities;
static uint8_t sm_preq[7]; static uint8_t sm_m_preq[7];
static uint8_t sm_pres[7];
static key_t sm_s_random; static key_t sm_s_random;
static key_t sm_s_confirm; static key_t sm_s_confirm;
static key_t sm_stk; static uint8_t sm_s_pres[7];
static uint8_t sm_pairing_failed_reason = 0;
static uint16_t sm_s_div;
static uint16_t sm_s_y;
static uint8_t sm_user_response;
// key distribution, slave sends // key distribution, slave sends
static key_t sm_s_ltk; static key_t sm_s_ltk;
static uint16_t sm_s_y;
static uint16_t sm_s_div;
static uint16_t sm_s_ediv; static uint16_t sm_s_ediv;
static uint8_t sm_s_rand[8]; static uint8_t sm_s_rand[8];
static key_t sm_s_csrk; static key_t sm_s_csrk;
@ -579,15 +579,17 @@ static void sm_run(void){
// TODO use locally defined max encryption key size // TODO use locally defined max encryption key size
uint8_t buffer[7]; uint8_t buffer[7];
memcpy(buffer, sm_preq, 7);
memcpy(buffer, sm_m_preq, 7);
buffer[0] = SM_CODE_PAIRING_RESPONSE; buffer[0] = SM_CODE_PAIRING_RESPONSE;
buffer[1] = sm_s_io_capabilities; buffer[1] = sm_s_io_capabilities;
buffer[2] = sm_stk_generation_method == OOB ? 1 : 0; buffer[2] = sm_stk_generation_method == OOB ? 1 : 0;
buffer[3] = sm_s_auth_req; buffer[3] = sm_s_auth_req;
buffer[4] = 0x10; // maxium encryption key size buffer[4] = 0x10; // maxium encryption key size
memcpy(sm_s_pres, buffer, 7);
// for validate // for validate
memcpy(sm_pres, buffer, 7);
l2cap_send_connectionless(sm_response_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer)); l2cap_send_connectionless(sm_response_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
sm_timeout_reset(); sm_timeout_reset();
@ -687,7 +689,7 @@ static void sm_run(void){
} }
case SM_STATE_PH2_SEND_STK: { case SM_STATE_PH2_SEND_STK: {
key_t stk_flipped; key_t stk_flipped;
swap128(sm_stk, stk_flipped); swap128(sm_s_ltk, stk_flipped);
hci_send_cmd(&hci_le_long_term_key_request_reply, sm_response_handle, stk_flipped); hci_send_cmd(&hci_le_long_term_key_request_reply, sm_response_handle, stk_flipped);
sm_state_responding = SM_STATE_PH2_W4_CONNECTION_ENCRYPTED; sm_state_responding = SM_STATE_PH2_W4_CONNECTION_ENCRYPTED;
return; return;
@ -778,7 +780,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
sm_setup_key_distribution(packet[6]); sm_setup_key_distribution(packet[6]);
// for validate // for validate
memcpy(sm_preq, packet, 7); memcpy(sm_m_preq, packet, 7);
// start sm timeout // start sm timeout
sm_timeout_start(); sm_timeout_start();
@ -821,6 +823,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
sm_state_responding = SM_STATE_PH2_C1_GET_RANDOM_A; sm_state_responding = SM_STATE_PH2_C1_GET_RANDOM_A;
break; break;
case SM_CODE_PAIRING_RANDOM: case SM_CODE_PAIRING_RANDOM:
// received random value // received random value
swap128(&packet[1], sm_m_random); swap128(&packet[1], sm_m_random);
@ -828,9 +831,10 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
// use aes128 engine // use aes128 engine
// calculate m_confirm using aes128 engine - step 1 // calculate m_confirm using aes128 engine - step 1
sm_aes128_set_key(sm_tk); sm_aes128_set_key(sm_tk);
sm_c1_t1(sm_m_random, sm_preq, sm_pres, sm_m_addr_type, sm_s_addr_type, sm_aes128_plaintext);
sm_state_responding = SM_STATE_PH2_C1_GET_ENC_C; sm_state_responding = SM_STATE_PH2_C1_GET_ENC_C;
break; break;
sm_c1_t1(sm_m_random, sm_m_preq, sm_s_pres, sm_m_addr_type, sm_s_addr_type, sm_aes128_plaintext);
case SM_CODE_ENCRYPTION_INFORMATION: case SM_CODE_ENCRYPTION_INFORMATION:
sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION; sm_key_distribution_received_set |= SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION;
@ -942,8 +946,6 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
if (sm_state_responding == SM_STATE_PH2_W4_LTK_REQUEST){ if (sm_state_responding == SM_STATE_PH2_W4_LTK_REQUEST){
// calculate STK // calculate STK
log_info("LTK Request: calculating STK"); log_info("LTK Request: calculating STK");
// key_t sm_stk;
// sm_s1(sm_tk, sm_s_random, sm_m_random, sm_stk);
sm_aes128_set_key(sm_tk); sm_aes128_set_key(sm_tk);
sm_s1_r_prime(sm_s_random, sm_m_random, sm_aes128_plaintext); sm_s1_r_prime(sm_s_random, sm_m_random, sm_aes128_plaintext);
sm_state_responding = SM_STATE_PH2_CALC_STK; sm_state_responding = SM_STATE_PH2_CALC_STK;
@ -974,7 +976,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
sm_state_responding = SM_STATE_PH4_DHK_GET_ENC; sm_state_responding = SM_STATE_PH4_DHK_GET_ENC;
// sm_s_div = sm_div(sm_persistent_dhk, sm_s_rand, sm_s_ediv); // sm_s_div = sm_div(sm_persistent_dhk, sm_s_rand, sm_s_ediv);
// sm_ltk(sm_persistent_er, sm_s_div, sm_s_ltk); // sm_s_ltk(sm_persistent_er, sm_s_div, sm_s_ltk);
break; break;
default: default:
@ -1050,8 +1052,8 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
} }
break; break;
case SM_STATE_PH2_W4_STK: case SM_STATE_PH2_W4_STK:
swap128(&packet[6], sm_stk); swap128(&packet[6], sm_s_ltk);
print_key("stk", sm_stk); print_key("stk", sm_s_ltk);
sm_state_responding = SM_STATE_PH2_SEND_STK; sm_state_responding = SM_STATE_PH2_SEND_STK;
break; break;
case SM_STATE_PH3_DHK_W4_ENC: case SM_STATE_PH3_DHK_W4_ENC:
@ -1134,6 +1136,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
break; break;
} }
case SM_STATE_PH2_C1_W4_RANDOM_A: case SM_STATE_PH2_C1_W4_RANDOM_A:
memcpy(&sm_s_random[0], &packet[6], 8); // random endinaness memcpy(&sm_s_random[0], &packet[6], 8); // random endinaness
sm_state_responding = SM_STATE_PH2_C1_GET_RANDOM_B; sm_state_responding = SM_STATE_PH2_C1_GET_RANDOM_B;
break; break;
@ -1141,15 +1144,18 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
memcpy(&sm_s_random[8], &packet[6], 8); // random endinaness memcpy(&sm_s_random[8], &packet[6], 8); // random endinaness
// calculate s_confirm manually // calculate s_confirm manually
// sm_c1(sm_tk, sm_s_random, sm_preq, sm_pres, sm_m_addr_type, sm_s_addr_type, sm_m_address, sm_s_address, sm_s_confirm);
// send s_confirm // send s_confirm
// sm_state_responding = SM_STATE_PH2_C1_SEND; // sm_state_responding = SM_STATE_PH2_C1_SEND;
// sm_c1(sm_tk, sm_s_random, sm_m_preq, sm_s_pres, sm_m_addr_type, sm_s_addr_type, sm_m_address, sm_s_address, sm_s_confirm);
// calculate s_confirm using aes128 engine - step 1 // calculate s_confirm using aes128 engine - step 1
sm_aes128_set_key(sm_tk); sm_aes128_set_key(sm_tk);
sm_c1_t1(sm_s_random, sm_preq, sm_pres, sm_m_addr_type, sm_s_addr_type, sm_aes128_plaintext);
sm_state_responding = SM_STATE_PH2_C1_GET_ENC_A; sm_state_responding = SM_STATE_PH2_C1_GET_ENC_A;
break; break;
sm_c1_t1(sm_s_random, sm_m_preq, sm_s_pres, sm_m_addr_type, sm_s_addr_type, sm_aes128_plaintext);
case SM_STATE_PH3_W4_RANDOM: case SM_STATE_PH3_W4_RANDOM:
swap64(&packet[6], sm_s_rand); swap64(&packet[6], sm_s_rand);
sm_state_responding = SM_STATE_PH3_GET_DIV; sm_state_responding = SM_STATE_PH3_GET_DIV;
@ -1172,7 +1178,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha
// // calculate EDIV and LTK // // calculate EDIV and LTK
// sm_s_ediv = sm_ediv(sm_persistent_dhk, sm_s_rand, sm_s_div); // sm_s_ediv = sm_ediv(sm_persistent_dhk, sm_s_rand, sm_s_div);
// sm_ltk(sm_persistent_er, sm_s_div, sm_s_ltk); // sm_s_ltk(sm_persistent_er, sm_s_div, sm_s_ltk);
// print_key("ltk", sm_s_ltk); // print_key("ltk", sm_s_ltk);
// print_hex16("ediv", sm_s_ediv); // print_hex16("ediv", sm_s_ediv);
// // distribute keys // // distribute keys
@ -1293,6 +1299,7 @@ static void sm_s1(key_t k, key_t r1, key_t r2, key_t s1){
int nrounds = rijndaelSetupEncrypt(rk, &k[0], KEYBITS); int nrounds = rijndaelSetupEncrypt(rk, &k[0], KEYBITS);
rijndaelEncrypt(rk, nrounds, r_prime, s1); rijndaelEncrypt(rk, nrounds, r_prime, s1);
print_key("s1", s1); print_key("s1", s1);
} }
// test code using aes128 c implementation // test code using aes128 c implementation
@ -1300,9 +1307,10 @@ static int sm_validate_m_confirm(void){
printf("sm_validate_m_confirm\n"); printf("sm_validate_m_confirm\n");
key_t c1; key_t c1;
sm_c1(sm_tk, sm_m_random, sm_preq, sm_pres, sm_m_addr_type, sm_s_addr_type, sm_m_address, sm_s_address, c1);
print_key("mc", sm_m_confirm); print_key("mc", sm_m_confirm);
sm_c1(sm_tk, sm_m_random, sm_m_preq, sm_s_pres, sm_m_addr_type, sm_s_addr_type, sm_m_address, sm_s_address, c1);
int m_confirm_valid = memcmp(c1, sm_m_confirm, 16) == 0; int m_confirm_valid = memcmp(c1, sm_m_confirm, 16) == 0;
printf("m_confirm_valid: %u\n", m_confirm_valid); printf("m_confirm_valid: %u\n", m_confirm_valid);
return m_confirm_valid; return m_confirm_valid;