mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-25 16:43:28 +00:00
added a minimal security manager that just denies security requests
This commit is contained in:
parent
fe9d8984b7
commit
ef8a41e1e4
261
ble/sm_minimal.c
Normal file
261
ble/sm_minimal.c
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2012 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. Any redistribution, use, or modification is done solely for
|
||||
* personal benefit and not for any commercial purpose or for
|
||||
* monetary gain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "hci.h"
|
||||
#include "l2cap.h"
|
||||
#include "central_device_db.h"
|
||||
#include "sm.h"
|
||||
#include "gap_le.h"
|
||||
|
||||
//
|
||||
// SM internal types and globals
|
||||
//
|
||||
|
||||
typedef enum {
|
||||
SM_STATE_IDLE,
|
||||
SM_STATE_SEND_LTK_REQUESTED_NEGATIVE_REPLY,
|
||||
SM_STATE_SEND_PAIRING_FAILED,
|
||||
SM_STATE_PAIRING_FAILED
|
||||
|
||||
} security_manager_state_t;
|
||||
|
||||
static void sm_run();
|
||||
|
||||
// used to notify applicationss that user interaction is neccessary, see sm_notify_t below
|
||||
static btstack_packet_handler_t sm_client_packet_handler = NULL;
|
||||
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;
|
||||
|
||||
|
||||
|
||||
void sm_set_er(sm_key_t er){}
|
||||
void sm_set_ir(sm_key_t ir){}
|
||||
void sm_register_oob_data_callback( int (*get_oob_data_callback)(uint8_t addres_type, bd_addr_t * addr, uint8_t * oob_data)){}
|
||||
|
||||
void sm_set_accepted_stk_generation_methods(uint8_t accepted_stk_generation_methods){}
|
||||
void sm_set_encrypted_key_size_range(uint8_t min_size, uint8_t max_size){}
|
||||
void sm_set_authentication_requirements(uint8_t auth_req){}
|
||||
void sm_set_io_capabilities(io_capability_t io_capability){}
|
||||
void sm_set_request_security(int enable){}
|
||||
|
||||
void sm_bonding_decline(uint8_t addr_type, bd_addr_t address){}
|
||||
void sm_just_works_confirm(uint8_t addr_type, bd_addr_t address){}
|
||||
void sm_passkey_input(uint8_t addr_type, bd_addr_t address, uint32_t passkey){}
|
||||
|
||||
// @returns 0 if not encrypted, 7-16 otherwise
|
||||
int sm_encryption_key_size(uint8_t addr_type, bd_addr_t address){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @returns 1 if bonded with OOB/Passkey (AND MITM protection)
|
||||
int sm_authenticated(uint8_t addr_type, bd_addr_t address){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @returns authorization_state for the current session
|
||||
authorization_state_t sm_authorization_state(uint8_t addr_type, bd_addr_t address){
|
||||
return AUTHORIZATION_DECLINED;
|
||||
}
|
||||
|
||||
// request authorization
|
||||
void sm_request_authorization(uint8_t addr_type, bd_addr_t address){}
|
||||
|
||||
// called by client app on authorization request
|
||||
void sm_authorization_decline(uint8_t addr_type, bd_addr_t address){}
|
||||
void sm_authorization_grant(uint8_t addr_type, bd_addr_t address){}
|
||||
|
||||
// Support for signed writes
|
||||
int sm_cmac_ready(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sm_cmac_start(sm_key_t k, uint16_t message_len, uint8_t * message, void (*done_handler)(uint8_t hash[8])){}
|
||||
|
||||
void sm_register_packet_handler(btstack_packet_handler_t handler){
|
||||
sm_client_packet_handler = handler;
|
||||
}
|
||||
|
||||
static void sm_pdu_received_in_wrong_state(){
|
||||
sm_pairing_failed_reason = SM_REASON_UNSPECIFIED_REASON;
|
||||
sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||
}
|
||||
|
||||
static void sm_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
|
||||
|
||||
if (packet_type != SM_DATA_PACKET) return;
|
||||
|
||||
if (handle != sm_response_handle){
|
||||
printf("sm_packet_handler: packet from handle %u, but expecting from %u\n", handle, sm_response_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet[0] == SM_CODE_PAIRING_FAILED){
|
||||
sm_state_responding = SM_STATE_PAIRING_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sm_state_responding){
|
||||
|
||||
case SM_STATE_IDLE: {
|
||||
if (packet[0] != SM_CODE_PAIRING_REQUEST){
|
||||
sm_pdu_received_in_wrong_state();
|
||||
break;;
|
||||
}
|
||||
sm_state_responding = SM_STATE_SEND_PAIRING_FAILED;
|
||||
sm_pairing_failed_reason = SM_REASON_PAIRING_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// try to send preparared packet
|
||||
sm_run();
|
||||
}
|
||||
|
||||
static void sm_event_packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (packet[0]) {
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (packet[2]) {
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
||||
// only single connection for peripheral
|
||||
if (sm_response_handle){
|
||||
printf("Already connected, ignoring incoming connection\n");
|
||||
return;
|
||||
}
|
||||
sm_response_handle = READ_BT_16(packet, 4);
|
||||
sm_state_responding = SM_STATE_IDLE;
|
||||
break;
|
||||
|
||||
case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST:
|
||||
log_info("LTK Request: state %u", sm_state_responding);
|
||||
sm_state_responding = SM_STATE_SEND_LTK_REQUESTED_NEGATIVE_REPLY;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
sm_state_responding = SM_STATE_IDLE;
|
||||
sm_response_handle = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// forward packet to higher layer
|
||||
if (sm_client_packet_handler){
|
||||
sm_client_packet_handler(packet_type, 0, packet, size);
|
||||
}
|
||||
}
|
||||
|
||||
// try to send preparared packet
|
||||
sm_run();
|
||||
}
|
||||
|
||||
static void sm_run(void){
|
||||
|
||||
// assert that we can send either one
|
||||
if (!hci_can_send_packet_now(HCI_COMMAND_DATA_PACKET)) return;
|
||||
if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)) return;
|
||||
|
||||
switch (sm_state_responding){
|
||||
case SM_STATE_SEND_LTK_REQUESTED_NEGATIVE_REPLY:
|
||||
hci_send_cmd(&hci_le_long_term_key_negative_reply, sm_response_handle);
|
||||
sm_state_responding = SM_STATE_IDLE;
|
||||
return;
|
||||
case SM_STATE_SEND_PAIRING_FAILED: {
|
||||
uint8_t buffer[2];
|
||||
buffer[0] = SM_CODE_PAIRING_FAILED;
|
||||
buffer[1] = sm_pairing_failed_reason;
|
||||
l2cap_send_connectionless(sm_response_handle, L2CAP_CID_SECURITY_MANAGER_PROTOCOL, (uint8_t*) buffer, sizeof(buffer));
|
||||
sm_state_responding = SM_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sm_init(){
|
||||
// attach to lower layers
|
||||
l2cap_register_fixed_channel(sm_packet_handler, L2CAP_CID_SECURITY_MANAGER_PROTOCOL);
|
||||
l2cap_register_packet_handler(sm_event_packet_handler);
|
||||
}
|
||||
|
||||
// GAP LE
|
||||
void gap_random_address_set_mode(gap_random_address_type_t random_address_type){}
|
||||
void gap_random_address_set_update_period(int period_ms){}
|
||||
|
||||
// Central Device db interface
|
||||
void central_device_db_init(){}
|
||||
|
||||
// @returns index if successful, -1 otherwise
|
||||
int central_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk, sm_key_t csrk){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @returns number of device in db
|
||||
int central_device_db_count(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get device information: addr type and address
|
||||
void central_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t csrk){}
|
||||
|
||||
// get signature key
|
||||
void central_device_db_csrk(int index, sm_key_t csrk){}
|
||||
|
||||
// query last used/seen signing counter
|
||||
uint32_t central_device_db_counter_get(int index){
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
// update signing counter
|
||||
void central_device_db_counter_set(int index, uint32_t counter){}
|
||||
|
||||
// free device
|
||||
void central_device_db_remove(int index){}
|
||||
|
@ -28,23 +28,33 @@ COMMON = \
|
||||
${BTSTACK_ROOT}/src/sdp_parser.c \
|
||||
${BTSTACK_ROOT}/src/sdp_query_util.c \
|
||||
${BTSTACK_ROOT}/src/sdp_query_rfcomm.c \
|
||||
|
||||
ATT = \
|
||||
${BTSTACK_ROOT}/ble/att.c \
|
||||
${BTSTACK_ROOT}/ble/att_server.c \
|
||||
${BTSTACK_ROOT}/ble/sm.c \
|
||||
${BTSTACK_ROOT}/ble/central_device_db_memory.c \
|
||||
|
||||
CC2564 = \
|
||||
${BTSTACK_ROOT}/chipset-cc256x/bt_control_cc256x.c \
|
||||
${BTSTACK_ROOT}/chipset-cc256x/bluetooth_init_cc2564_2.10.c \
|
||||
|
||||
SM_REAL = \
|
||||
${BTSTACK_ROOT}/ble/sm.c \
|
||||
${BTSTACK_ROOT}/ble/central_device_db_memory.c \
|
||||
|
||||
SM_MINIMAL = \
|
||||
${BTSTACK_ROOT}/ble/sm_minimal.c \
|
||||
|
||||
CORE_OBJ = $(CORE:.c=.o)
|
||||
COMMON_OBJ = $(COMMON:.c=.o)
|
||||
CC2564_OBJ = $(CC2564:.c=.o)
|
||||
SM_REAL_OBJ = $(SM_REAL:.c=.o)
|
||||
SM_MINIMAL_OBJ = $(SM_MINIMAL:.c=.o)
|
||||
ATT_OBJ = $(ATT:.c=.o)
|
||||
|
||||
|
||||
# create firmware image from common objects and example source file
|
||||
|
||||
all: ../../include/btstack/version.h ble_client ble_client_uart sdp_rfcomm_query sdp_general_query spp_counter ble_peripheral
|
||||
all: ../../include/btstack/version.h ble_client ble_client_uart sdp_rfcomm_query sdp_general_query spp_counter ble_peripheral ble_peripheral_sm_minimal
|
||||
|
||||
#spp-usb l2cap-server-usb l2cap-client-usb l2cap-server-uart l2cap-client-uart
|
||||
|
||||
@ -67,8 +77,11 @@ spp_counter_ssp: ${CORE_OBJ} ${COMMON_OBJ} spp_counter_ssp.c
|
||||
profile.h: profile.gatt
|
||||
python ${BTSTACK_ROOT}/ble/compile-gatt.py $< $@
|
||||
|
||||
ble_peripheral: ${CORE_OBJ} ${COMMON_OBJ} ble_peripheral.c profile.h
|
||||
${CC} ${CORE_OBJ} ${COMMON_OBJ} ble_peripheral.c ${CFLAGS} ${LDFLAGS} -o $@
|
||||
ble_peripheral: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_REAL_OBJ} ble_peripheral.c profile.h
|
||||
${CC} ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_REAL_OBJ} ble_peripheral.c ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
ble_peripheral_sm_minimal: ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_MINIMAL_OBJ} ble_peripheral.c profile.h
|
||||
${CC} ${CORE_OBJ} ${COMMON_OBJ} ${ATT_OBJ} ${SM_MINIMAL_OBJ} ble_peripheral.c ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
ble_client: ${CORE_OBJ} ${COMMON_OBJ} ble_client.c ad_parser.c
|
||||
${CC} ${CORE_OBJ} ${COMMON_OBJ} ad_parser.c ble_client.c ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
Loading…
x
Reference in New Issue
Block a user