mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-15 23:42:52 +00:00
extracted calculation of actual key size and validation of stk generation method
This commit is contained in:
parent
70e9b98021
commit
b95904ca68
91
ble/sm.c
91
ble/sm.c
@ -50,21 +50,23 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
||||||
|
// general states
|
||||||
SM_STATE_IDLE,
|
SM_STATE_IDLE,
|
||||||
|
SM_STATE_SEND_PAIRING_FAILED,
|
||||||
|
SM_STATE_SEND_LTK_REQUESTED_NEGATIVE_REPLY,
|
||||||
|
SM_STATE_TIMEOUT, // no other security messages are exchanged
|
||||||
|
|
||||||
// SLAVE ROLE
|
// SLAVE ROLE
|
||||||
|
|
||||||
SM_STATE_W4_PAIRING_REQUEST,
|
|
||||||
SM_STATE_SEND_SECURITY_REQUEST,
|
SM_STATE_SEND_SECURITY_REQUEST,
|
||||||
SM_STATE_SEND_LTK_REQUESTED_NEGATIVE_REPLY,
|
|
||||||
|
|
||||||
// Phase 1: Pairing Feature Exchange
|
// Phase 1: Pairing Feature Exchange
|
||||||
|
|
||||||
|
SM_STATE_W4_PAIRING_REQUEST,
|
||||||
SM_STATE_PH1_SEND_PAIRING_RESPONSE,
|
SM_STATE_PH1_SEND_PAIRING_RESPONSE,
|
||||||
SM_STATE_PH1_W4_PAIRING_CONFIRM,
|
SM_STATE_PH1_W4_PAIRING_CONFIRM,
|
||||||
SM_STATE_PH1_W4_USER_RESPONSE,
|
SM_STATE_PH1_W4_USER_RESPONSE,
|
||||||
|
|
||||||
SM_STATE_SEND_PAIRING_FAILED,
|
|
||||||
SM_STATE_SEND_PAIRING_RANDOM,
|
SM_STATE_SEND_PAIRING_RANDOM,
|
||||||
|
|
||||||
// Phase 2: Authenticating and Encrypting
|
// Phase 2: Authenticating and Encrypting
|
||||||
@ -118,16 +120,20 @@ typedef enum {
|
|||||||
SM_STATE_PH4_LTK_W4_ENC,
|
SM_STATE_PH4_LTK_W4_ENC,
|
||||||
SM_STATE_PH4_SEND_LTK,
|
SM_STATE_PH4_SEND_LTK,
|
||||||
|
|
||||||
SM_STATE_TIMEOUT, // no other security messages are exchanged
|
|
||||||
|
|
||||||
// MASTR ROLE
|
// MASTR ROLE
|
||||||
SM_STATE_INITIATOR_CONNECTED,
|
SM_STATE_INITIATOR_CONNECTED,
|
||||||
|
|
||||||
|
// PH1
|
||||||
SM_STATE_INITIATOR_SEND_PAIRING_REQUEST,
|
SM_STATE_INITIATOR_SEND_PAIRING_REQUEST,
|
||||||
SM_STATE_INITIATOR_W4_PAIRING_RESPONSE,
|
SM_STATE_INITIATOR_W4_PAIRING_RESPONSE,
|
||||||
SM_STATE_INITIATOR_PH1_SEND_PAIRING_CONFIRM,
|
SM_STATE_INITIATOR_PH1_SEND_PAIRING_CONFIRM,
|
||||||
|
|
||||||
|
// PH2
|
||||||
SM_STATE_INITIATOR_PH2_GET_RANDOM_TK,
|
SM_STATE_INITIATOR_PH2_GET_RANDOM_TK,
|
||||||
SM_STATE_INITIATOR_PH2_W4_RANDOM_TK,
|
SM_STATE_INITIATOR_PH2_W4_RANDOM_TK,
|
||||||
|
|
||||||
|
|
||||||
} security_manager_state_t;
|
} security_manager_state_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -1547,7 +1553,28 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
|||||||
|
|
||||||
sm_run();
|
sm_run();
|
||||||
}
|
}
|
||||||
|
static inline int sm_calc_actual_encryption_key_size(int other){
|
||||||
|
if (other < sm_min_encryption_key_size) return 0;
|
||||||
|
if (other < sm_max_encryption_key_size) return other;
|
||||||
|
return sm_max_encryption_key_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ok
|
||||||
|
*/
|
||||||
|
static int sm_validate_stk_generation_method(){
|
||||||
|
// check if STK generation method is acceptable by client
|
||||||
|
switch (sm_stk_generation_method){
|
||||||
|
case JUST_WORKS:
|
||||||
|
return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0;
|
||||||
|
case PK_RESP_INPUT:
|
||||||
|
case PK_INIT_INPUT:
|
||||||
|
case OK_BOTH_INPUT:
|
||||||
|
return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0;
|
||||||
|
case OOB:
|
||||||
|
return (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
|
static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
|
||||||
|
|
||||||
if (packet_type == HCI_EVENT_PACKET) {
|
if (packet_type == HCI_EVENT_PACKET) {
|
||||||
@ -1577,7 +1604,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
|||||||
case SM_STATE_INITIATOR_W4_PAIRING_RESPONSE:
|
case SM_STATE_INITIATOR_W4_PAIRING_RESPONSE:
|
||||||
if (packet[0] != SM_CODE_PAIRING_RESPONSE){
|
if (packet[0] != SM_CODE_PAIRING_RESPONSE){
|
||||||
sm_pdu_received_in_wrong_state();
|
sm_pdu_received_in_wrong_state();
|
||||||
break;;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store pairing request
|
// store pairing request
|
||||||
@ -1585,19 +1612,14 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
|||||||
|
|
||||||
// identical to responder, just other encryption size field
|
// identical to responder, just other encryption size field
|
||||||
|
|
||||||
// assert max encryption size above our minimum
|
// check key size
|
||||||
if (setup->sm_s_pres.max_encryption_key_size < sm_min_encryption_key_size){
|
connection->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(setup->sm_s_pres.max_encryption_key_size);
|
||||||
|
if (connection->sm_actual_encryption_key_size == 0){
|
||||||
setup->sm_pairing_failed_reason = SM_REASON_ENCRYPTION_KEY_SIZE;
|
setup->sm_pairing_failed_reason = SM_REASON_ENCRYPTION_KEY_SIZE;
|
||||||
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// min{}
|
|
||||||
connection->sm_actual_encryption_key_size = sm_max_encryption_key_size;
|
|
||||||
if (setup->sm_s_pres.max_encryption_key_size < sm_max_encryption_key_size){
|
|
||||||
connection->sm_actual_encryption_key_size = setup->sm_s_pres.max_encryption_key_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup key distribution
|
// setup key distribution
|
||||||
sm_setup_key_distribution(setup->sm_s_pres.initiator_key_distribution);
|
sm_setup_key_distribution(setup->sm_s_pres.initiator_key_distribution);
|
||||||
|
|
||||||
@ -1611,21 +1633,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
|||||||
printf("SMP: generation method %u\n", sm_stk_generation_method);
|
printf("SMP: generation method %u\n", sm_stk_generation_method);
|
||||||
|
|
||||||
// check if STK generation method is acceptable by client
|
// check if STK generation method is acceptable by client
|
||||||
int ok = 0;
|
if (!sm_validate_stk_generation_method()){
|
||||||
switch (sm_stk_generation_method){
|
|
||||||
case JUST_WORKS:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0;
|
|
||||||
break;
|
|
||||||
case PK_RESP_INPUT:
|
|
||||||
case PK_INIT_INPUT:
|
|
||||||
case OK_BOTH_INPUT:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0;
|
|
||||||
break;
|
|
||||||
case OOB:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!ok){
|
|
||||||
setup->sm_pairing_failed_reason = SM_REASON_AUTHENTHICATION_REQUIREMENTS;
|
setup->sm_pairing_failed_reason = SM_REASON_AUTHENTHICATION_REQUIREMENTS;
|
||||||
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||||
break;
|
break;
|
||||||
@ -1655,19 +1663,14 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
|||||||
// store pairing request
|
// store pairing request
|
||||||
memcpy(&setup->sm_m_preq, packet, sizeof(sm_pairing_packet_t));
|
memcpy(&setup->sm_m_preq, packet, sizeof(sm_pairing_packet_t));
|
||||||
|
|
||||||
// assert max encryption size above our minimum
|
// check key size
|
||||||
if (setup->sm_m_preq.max_encryption_key_size < sm_min_encryption_key_size){
|
connection->sm_actual_encryption_key_size = sm_calc_actual_encryption_key_size(setup->sm_s_pres.max_encryption_key_size);
|
||||||
|
if (connection->sm_actual_encryption_key_size == 0){
|
||||||
setup->sm_pairing_failed_reason = SM_REASON_ENCRYPTION_KEY_SIZE;
|
setup->sm_pairing_failed_reason = SM_REASON_ENCRYPTION_KEY_SIZE;
|
||||||
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// min{}
|
|
||||||
connection->sm_actual_encryption_key_size = sm_max_encryption_key_size;
|
|
||||||
if (setup->sm_m_preq.max_encryption_key_size < sm_max_encryption_key_size){
|
|
||||||
connection->sm_actual_encryption_key_size = setup->sm_m_preq.max_encryption_key_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup key distribution
|
// setup key distribution
|
||||||
sm_setup_key_distribution(setup->sm_m_preq.responder_key_distribution);
|
sm_setup_key_distribution(setup->sm_m_preq.responder_key_distribution);
|
||||||
|
|
||||||
@ -1679,21 +1682,7 @@ static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pac
|
|||||||
printf("SMP: generation method %u\n", sm_stk_generation_method);
|
printf("SMP: generation method %u\n", sm_stk_generation_method);
|
||||||
|
|
||||||
// check if STK generation method is acceptable by client
|
// check if STK generation method is acceptable by client
|
||||||
int ok = 0;
|
if (!sm_validate_stk_generation_method()){
|
||||||
switch (sm_stk_generation_method){
|
|
||||||
case JUST_WORKS:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_JUST_WORKS) != 0;
|
|
||||||
break;
|
|
||||||
case PK_RESP_INPUT:
|
|
||||||
case PK_INIT_INPUT:
|
|
||||||
case OK_BOTH_INPUT:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_PASSKEY) != 0;
|
|
||||||
break;
|
|
||||||
case OOB:
|
|
||||||
ok = (sm_accepted_stk_generation_methods & SM_STK_GENERATION_METHOD_OOB) != 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!ok){
|
|
||||||
setup->sm_pairing_failed_reason = SM_REASON_AUTHENTHICATION_REQUIREMENTS;
|
setup->sm_pairing_failed_reason = SM_REASON_AUTHENTHICATION_REQUIREMENTS;
|
||||||
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
connection->sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user