mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-10 06:40:23 +00:00
Merge branch 'develop' of https://github.com/bluekitchen/btstack into develop
This commit is contained in:
commit
e1cd7dec93
@ -76,6 +76,7 @@ ENABLE_LOG_INTO_HCI_DUMP | Log debug messages as part of packet log
|
||||
ENABLE_SCO_OVER_HCI | Enable SCO over HCI for chipsets (only CC256x/WL18xx and USB CSR controllers)
|
||||
ENABLE_LE_SECURE_CONNECTIONS | Enable LE Secure Connections using [mbed TLS library](https://tls.mbed.org)
|
||||
ENABLE_LE_DATA_CHANNELS | Enable LE Data Channels in credit-based flow control mode
|
||||
ENABLE_LE_SIGNED_WRITE | Enable LE Signed Writes in ATT/GATT
|
||||
|
||||
### Memory configuration directives {#sec:memoryConfigurationHowTo}
|
||||
|
||||
|
@ -1120,9 +1120,11 @@ uint16_t att_handle_request(att_connection_t * att_connection,
|
||||
case ATT_WRITE_COMMAND:
|
||||
handle_write_command(att_connection, request_buffer, request_len, response_buffer, response_buffer_size);
|
||||
break;
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
case ATT_SIGNED_WRITE_COMMAND:
|
||||
log_info("handle_signed_write_command preprocessed by att_server.c");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_info("Unhandled ATT Command: %02X, DATA: ", request_buffer[0]);
|
||||
log_info_hexdump(&request_buffer[9], request_len-9);
|
||||
|
@ -235,6 +235,7 @@ static void att_event_packet_handler (uint8_t packet_type, uint16_t channel, uin
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
|
||||
|
||||
att_server_t * att_server = att_server_for_state(ATT_SERVER_W4_SIGNED_WRITE_VALIDATION);
|
||||
@ -255,7 +256,7 @@ static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
|
||||
att_server->state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
|
||||
att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// pre: att_server->state == ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED
|
||||
// pre: can send now
|
||||
@ -303,6 +304,7 @@ static int att_server_process_validated_request(att_server_t * att_server){
|
||||
static void att_run_for_context(att_server_t * att_server){
|
||||
switch (att_server->state){
|
||||
case ATT_SERVER_REQUEST_RECEIVED:
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
if (att_server->request_buffer[0] == ATT_SIGNED_WRITE_COMMAND){
|
||||
log_info("ATT Signed Write!");
|
||||
if (!sm_cmac_ready()) {
|
||||
@ -344,7 +346,7 @@ static void att_run_for_context(att_server_t * att_server){
|
||||
sm_cmac_signed_write_start(csrk, att_server->request_buffer[0], attribute_handle, att_server->request_size - 15, &att_server->request_buffer[3], counter_packet, att_signed_write_handle_cmac_result);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
// move on
|
||||
att_server->state = ATT_SERVER_REQUEST_RECEIVED_AND_VALIDATED;
|
||||
att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
|
||||
|
@ -68,7 +68,10 @@ static uint8_t pts_suppress_mtu_exchange;
|
||||
static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
|
||||
static void gatt_client_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code);
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static void att_signed_write_handle_cmac_result(uint8_t hash[8]);
|
||||
#endif
|
||||
|
||||
static uint16_t peripheral_mtu(gatt_client_t *peripheral){
|
||||
if (peripheral->mtu > l2cap_max_le_mtu()){
|
||||
@ -275,6 +278,7 @@ static void att_read_multiple_request(uint16_t peripheral_handle, uint16_t num_v
|
||||
l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, offset);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
// precondition: can_send_packet_now == TRUE
|
||||
static void att_signed_write_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value, uint32_t sign_counter, uint8_t sgn[8]){
|
||||
l2cap_reserve_packet_buffer();
|
||||
@ -286,6 +290,7 @@ static void att_signed_write_request(uint16_t request_type, uint16_t peripheral_
|
||||
reverse_64(sgn, &request[3 + value_length + 4]);
|
||||
l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3 + value_length + 12);
|
||||
}
|
||||
#endif
|
||||
|
||||
// precondition: can_send_packet_now == TRUE
|
||||
static void att_write_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value){
|
||||
@ -424,9 +429,11 @@ static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * per
|
||||
att_read_request(ATT_READ_REQUEST, peripheral->con_handle, peripheral->attribute_handle);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static void send_gatt_signed_write_request(gatt_client_t * peripheral, uint32_t sign_counter){
|
||||
att_signed_write_request(ATT_SIGNED_WRITE_COMMAND, peripheral->con_handle, peripheral->attribute_handle, peripheral->attribute_length, peripheral->attribute_value, sign_counter, peripheral->cmac);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t get_last_result_handle_from_service_list(uint8_t * packet, uint16_t size){
|
||||
uint8_t attr_length = packet[1];
|
||||
@ -960,6 +967,7 @@ static void gatt_client_run(void){
|
||||
send_gatt_execute_write_request(peripheral);
|
||||
return;
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
case P_W4_CMAC_READY:
|
||||
if (sm_cmac_ready()){
|
||||
sm_key_t csrk;
|
||||
@ -982,6 +990,7 @@ static void gatt_client_run(void){
|
||||
gatt_client_handle_transaction_complete(peripheral);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -1346,6 +1355,7 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
gatt_client_run();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &gatt_client_connections);
|
||||
@ -1377,6 +1387,7 @@ uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callb
|
||||
gatt_client_run();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
|
||||
gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
|
||||
|
44
src/ble/sm.c
44
src/ble/sm.c
@ -68,6 +68,10 @@
|
||||
#include "sm_mbedtls_allocator.h"
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_LE_SIGNED_WRITE) || defined(ENABLE_LE_SECURE_CONNECTIONS)
|
||||
#define ENABLE_CMAC_ENGINE
|
||||
#endif
|
||||
|
||||
//
|
||||
// SM internal types and globals
|
||||
//
|
||||
@ -180,6 +184,7 @@ static random_address_update_t rau_state;
|
||||
static bd_addr_t sm_random_address;
|
||||
|
||||
// CMAC Calculation: General
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
static cmac_state_t sm_cmac_state;
|
||||
static uint16_t sm_cmac_message_len;
|
||||
static sm_key_t sm_cmac_k;
|
||||
@ -189,11 +194,14 @@ static uint8_t sm_cmac_block_current;
|
||||
static uint8_t sm_cmac_block_count;
|
||||
static uint8_t (*sm_cmac_get_byte)(uint16_t offset);
|
||||
static void (*sm_cmac_done_handler)(uint8_t * hash);
|
||||
#endif
|
||||
|
||||
// CMAC for ATT Signed Writes
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static uint8_t sm_cmac_header[3];
|
||||
static const uint8_t * sm_cmac_message;
|
||||
static uint8_t sm_cmac_sign_counter[4];
|
||||
#endif
|
||||
|
||||
// CMAC for Secure Connection functions
|
||||
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
||||
@ -363,7 +371,6 @@ static void sm_done_for_handle(hci_con_handle_t con_handle);
|
||||
static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle);
|
||||
static inline int sm_calc_actual_encryption_key_size(int other);
|
||||
static int sm_validate_stk_generation_method(void);
|
||||
static void sm_shift_left_by_one_bit_inplace(int len, uint8_t * data);
|
||||
|
||||
static void log_info_hex16(const char * name, uint16_t value){
|
||||
log_info("%-6s 0x%04x", name, value);
|
||||
@ -841,17 +848,6 @@ int sm_address_resolution_lookup(uint8_t address_type, bd_addr_t address){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CMAC Implementation using AES128 engine
|
||||
static void sm_shift_left_by_one_bit_inplace(int len, uint8_t * data){
|
||||
int i;
|
||||
int carry = 0;
|
||||
for (i=len-1; i >= 0 ; i--){
|
||||
int new_carry = data[i] >> 7;
|
||||
data[i] = data[i] << 1 | carry;
|
||||
carry = new_carry;
|
||||
}
|
||||
}
|
||||
|
||||
// while x_state++ for an enum is possible in C, it isn't in C++. we use this helpers to avoid compile errors for now
|
||||
static inline void sm_next_responding_state(sm_connection_t * sm_conn){
|
||||
sm_conn->sm_engine_state = (security_manager_state_t) (((int)sm_conn->sm_engine_state) + 1);
|
||||
@ -864,6 +860,7 @@ static inline void rau_next_state(void){
|
||||
}
|
||||
|
||||
// CMAC calculation using AES Engine
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
|
||||
static inline void sm_cmac_next_state(void){
|
||||
sm_cmac_state = (cmac_state_t) (((int)sm_cmac_state) + 1);
|
||||
@ -903,8 +900,10 @@ void sm_cmac_general_start(const sm_key_t key, uint16_t message_len, uint8_t (*g
|
||||
// let's go
|
||||
sm_run();
|
||||
}
|
||||
#endif
|
||||
|
||||
// cmac for ATT Message signing
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
static uint8_t sm_cmac_signed_write_message_get_byte(uint16_t offset){
|
||||
if (offset >= sm_cmac_message_len) {
|
||||
log_error("sm_cmac_signed_write_message_get_byte. out of bounds, access %u, len %u", offset, sm_cmac_message_len);
|
||||
@ -933,8 +932,9 @@ void sm_cmac_signed_write_start(const sm_key_t k, uint8_t opcode, hci_con_handle
|
||||
sm_cmac_message = message;
|
||||
sm_cmac_general_start(k, total_message_len, &sm_cmac_signed_write_message_get_byte, done_handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
static void sm_cmac_handle_aes_engine_ready(void){
|
||||
switch (sm_cmac_state){
|
||||
case CMAC_CALC_SUBKEYS: {
|
||||
@ -973,6 +973,17 @@ static void sm_cmac_handle_aes_engine_ready(void){
|
||||
}
|
||||
}
|
||||
|
||||
// CMAC Implementation using AES128 engine
|
||||
static void sm_shift_left_by_one_bit_inplace(int len, uint8_t * data){
|
||||
int i;
|
||||
int carry = 0;
|
||||
for (i=len-1; i >= 0 ; i--){
|
||||
int new_carry = data[i] >> 7;
|
||||
data[i] = data[i] << 1 | carry;
|
||||
carry = new_carry;
|
||||
}
|
||||
}
|
||||
|
||||
static void sm_cmac_handle_encryption_result(sm_key_t data){
|
||||
switch (sm_cmac_state){
|
||||
case CMAC_W4_SUBKEYS: {
|
||||
@ -1034,6 +1045,7 @@ static void sm_cmac_handle_encryption_result(sm_key_t data){
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sm_trigger_user_response(sm_connection_t * sm_conn){
|
||||
// notify client for: JUST WORKS confirm, Numeric comparison confirm, PASSKEY display or input
|
||||
@ -1857,6 +1869,7 @@ static void sm_run(void){
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
// CMAC
|
||||
switch (sm_cmac_state){
|
||||
case CMAC_CALC_SUBKEYS:
|
||||
@ -1869,6 +1882,7 @@ static void sm_run(void){
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// CSRK Lookup
|
||||
// -- if csrk lookup ready, find connection that require csrk lookup
|
||||
@ -2583,6 +2597,7 @@ static void sm_handle_encryption_result(uint8_t * data){
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
switch (sm_cmac_state){
|
||||
case CMAC_W4_SUBKEYS:
|
||||
case CMAC_W4_MI:
|
||||
@ -2596,6 +2611,7 @@ static void sm_handle_encryption_result(uint8_t * data){
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// retrieve sm_connection provided to sm_aes128_start_encryption
|
||||
sm_connection_t * connection = (sm_connection_t*) sm_aes128_context;
|
||||
@ -3635,7 +3651,9 @@ void sm_init(void){
|
||||
sm_max_encryption_key_size = 16;
|
||||
sm_min_encryption_key_size = 7;
|
||||
|
||||
#ifdef ENABLE_CMAC_ENGINE
|
||||
sm_cmac_state = CMAC_IDLE;
|
||||
#endif
|
||||
dkg_state = DKG_W4_WORKING;
|
||||
rau_state = RAU_W4_WORKING;
|
||||
sm_aes128_state = SM_AES128_IDLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user