448 lines
14 KiB
C
448 lines
14 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
****************************************************************************/
|
|
/**
|
|
****************************************************************************************
|
|
* @addtogroup APP
|
|
* @{
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* INCLUDE FILES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
#include "rwip_config.h"
|
|
|
|
#if (BLE_APP_SEC)
|
|
|
|
#include <string.h>
|
|
#include "co_math.h"
|
|
#include "gapc_task.h" // GAP Controller Task API Definition
|
|
#include "gap.h" // GAP Definition
|
|
#include "gapc.h" // GAPC Definition
|
|
#include "prf_types.h"
|
|
|
|
#include "app.h" // Application API Definition
|
|
#include "app_ble_include.h"
|
|
#include "app_sec.h" // Application Security API Definition
|
|
#include "app_task.h" // Application Manager API Definition
|
|
|
|
#if (DISPLAY_SUPPORT)
|
|
#include "app_display.h" // Display Application Definitions
|
|
#endif //(DISPLAY_SUPPORT)
|
|
|
|
#if (NVDS_SUPPORT)
|
|
#include "nvds.h" // NVDS API Definitions
|
|
#endif //(NVDS_SUPPORT)
|
|
|
|
#ifdef BLE_APP_AM0
|
|
#include "am0_app.h"
|
|
#endif // BLE_APP_AM0
|
|
|
|
#if (BLE_APP_ANCC)
|
|
#include "app_ancc.h" // ANC Module Definition
|
|
#endif // (BLE_APP_ANCC)
|
|
|
|
#if (BLE_APP_AMS)
|
|
#include "app_amsc.h" // AMS Module Definition
|
|
#endif // (BLE_APP_AMS)
|
|
|
|
#include "app_gfps.h"
|
|
#include "nvrecord_ble.h"
|
|
#include "tgt_hardware.h"
|
|
#include "nvrecord_extension.h"
|
|
|
|
#ifdef _BLE_NVDS_
|
|
#define BLE_KEY_PRINT
|
|
BleDeviceinfo ble_save_info;
|
|
#endif
|
|
|
|
#ifdef TWS_SYSTEM_ENABLED
|
|
#include "app_tws_if.h"
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* GLOBAL VARIABLE DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/// Application Security Environment Structure
|
|
struct app_sec_env_tag app_sec_env;
|
|
|
|
/*
|
|
* GLOBAL FUNCTION DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
void app_sec_init(void)
|
|
{
|
|
#ifdef _BLE_NVDS_
|
|
if (nv_record_ble_record_Once_a_device_has_been_bonded())
|
|
{
|
|
app_sec_env.bonded = true;
|
|
}
|
|
else
|
|
{
|
|
app_sec_env.bonded = false;
|
|
}
|
|
|
|
TRACE(2,"[%s] once bonded:%d", __func__, app_sec_env.bonded);
|
|
#endif
|
|
}
|
|
|
|
bool app_sec_get_bond_status(void)
|
|
{
|
|
return app_sec_env.bonded;
|
|
}
|
|
|
|
void app_sec_send_security_req(uint8_t conidx, enum gap_auth authority)
|
|
{
|
|
// Send security request
|
|
struct gapc_security_cmd *cmd = KE_MSG_ALLOC(GAPC_SECURITY_CMD,
|
|
KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
|
|
gapc_security_cmd);
|
|
|
|
cmd->operation = GAPC_SECURITY_REQ;
|
|
|
|
cmd->auth = authority;
|
|
|
|
// Send the message
|
|
ke_msg_send(cmd);
|
|
}
|
|
|
|
/*
|
|
* MESSAGE HANDLERS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
static int gapc_bond_req_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapc_bond_req_ind const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id)
|
|
{
|
|
TRACE(1,"Get bond req %d", param->request);
|
|
|
|
// Prepare the GAPC_BOND_CFM message
|
|
struct gapc_bond_cfm *cfm = KE_MSG_ALLOC(GAPC_BOND_CFM,
|
|
src_id, TASK_APP,
|
|
gapc_bond_cfm);
|
|
|
|
switch (param->request)
|
|
{
|
|
case (GAPC_PAIRING_REQ):
|
|
{
|
|
cfm->request = GAPC_PAIRING_RSP;
|
|
|
|
cfm->accept = true;
|
|
|
|
cfm->data.pairing_feat.auth = BLE_AUTHENTICATION_LEVEL;
|
|
|
|
#if (BLE_APP_GFPS)
|
|
cfm->data.pairing_feat.iocap = GAP_IO_CAP_DISPLAY_YES_NO;
|
|
#else
|
|
cfm->data.pairing_feat.iocap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
|
|
#endif
|
|
|
|
cfm->data.pairing_feat.key_size = 16;
|
|
cfm->data.pairing_feat.oob = GAP_OOB_AUTH_DATA_NOT_PRESENT;
|
|
#if (BLE_APP_GFPS)
|
|
cfm->data.pairing_feat.sec_req = GAP_SEC1_SEC_CON_PAIR_ENC;
|
|
#else
|
|
cfm->data.pairing_feat.sec_req = GAP_SEC1_NOAUTH_PAIR_ENC;
|
|
#endif
|
|
|
|
cfm->data.pairing_feat.ikey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY | GAP_KDIST_LINKKEY;
|
|
cfm->data.pairing_feat.rkey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY | GAP_KDIST_LINKKEY;
|
|
} break;
|
|
|
|
case (GAPC_LTK_EXCH):
|
|
{
|
|
// Counter
|
|
uint8_t counter;
|
|
|
|
cfm->accept = true;
|
|
cfm->request = GAPC_LTK_EXCH;
|
|
|
|
// Generate all the values
|
|
cfm->data.ltk.ediv = (uint16_t)co_rand_word();
|
|
|
|
for (counter = 0; counter < RAND_NB_LEN; counter++)
|
|
{
|
|
cfm->data.ltk.randnb.nb[counter] = (uint8_t)co_rand_word();
|
|
}
|
|
|
|
for (counter = 0; counter < GAP_KEY_LEN; counter++)
|
|
{
|
|
cfm->data.ltk.ltk.key[counter] = (uint8_t)co_rand_word();
|
|
}
|
|
|
|
#ifdef _BLE_NVDS_
|
|
#ifdef BLE_KEY_PRINT
|
|
TRACE(0,"<==============>LTK IS:");
|
|
DUMP8("%02x ",(uint8_t *)&cfm->data.ltk,16);
|
|
TRACE(1,"<==============>EDIV IS: %04x:",cfm->data.ltk.ediv);
|
|
TRACE(0,"<==============>RANDOM IS:");
|
|
DUMP8("%02x ",(uint8_t *)&cfm->data.ltk.randnb.nb,8);
|
|
#endif
|
|
ble_save_info.EDIV = cfm->data.ltk.ediv;
|
|
memcpy(&ble_save_info.RANDOM, (uint8_t *)&cfm->data.ltk.randnb.nb, 8);
|
|
memcpy(&ble_save_info.LTK, (uint8_t *)&cfm->data.ltk, 16);
|
|
|
|
ble_save_info.bonded = false;
|
|
#endif
|
|
} break;
|
|
|
|
case (GAPC_IRK_EXCH):
|
|
{
|
|
cfm->accept = true;
|
|
cfm->request = GAPC_IRK_EXCH;
|
|
|
|
// Load IRK
|
|
memcpy(cfm->data.irk.irk.key, app_env.loc_irk, KEY_LEN);
|
|
// load identity ble address
|
|
memcpy(cfm->data.irk.addr.addr.addr, ble_addr, BLE_ADDR_SIZE);
|
|
cfm->data.irk.addr.addr_type = ADDR_PUBLIC;
|
|
} break;
|
|
case (GAPC_TK_EXCH):
|
|
{
|
|
// Generate a PIN Code- (Between 100000 and 999999)
|
|
uint32_t pin_code = (100000 + (co_rand_word()%900000));
|
|
|
|
cfm->accept = true;
|
|
cfm->request = GAPC_TK_EXCH;
|
|
|
|
// Set the TK value
|
|
memset(cfm->data.tk.key, 0, KEY_LEN);
|
|
|
|
cfm->data.tk.key[0] = (uint8_t)((pin_code & 0x000000FF) >> 0);
|
|
cfm->data.tk.key[1] = (uint8_t)((pin_code & 0x0000FF00) >> 8);
|
|
cfm->data.tk.key[2] = (uint8_t)((pin_code & 0x00FF0000) >> 16);
|
|
cfm->data.tk.key[3] = (uint8_t)((pin_code & 0xFF000000) >> 24);
|
|
} break;
|
|
case GAPC_NC_EXCH:
|
|
cfm->accept = true;
|
|
cfm->request = GAPC_NC_EXCH;
|
|
break;
|
|
default:
|
|
{
|
|
ASSERT_ERR(0);
|
|
} break;
|
|
}
|
|
|
|
// Send the message
|
|
ke_msg_send(cfm);
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
void app_sec_reset_env_on_connection(void)
|
|
{
|
|
#ifdef _BLE_NVDS_
|
|
memset(&ble_save_info, 0, sizeof(BleDeviceinfo));
|
|
#endif
|
|
}
|
|
|
|
static int gapc_bond_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapc_bond_ind const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id)
|
|
{
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
switch (param->info)
|
|
{
|
|
case (GAPC_PAIRING_SUCCEED):
|
|
{
|
|
TRACE(0,"GAPC_PAIRING_SUCCEED");
|
|
// Update the bonding status in the environment
|
|
app_sec_env.bonded = true;
|
|
#ifdef _BLE_NVDS_
|
|
ble_save_info.bonded = true;
|
|
|
|
if (!nv_record_blerec_add(&ble_save_info))
|
|
{
|
|
#ifdef TWS_SYSTEM_ENABLED
|
|
app_ble_sync_ble_info();
|
|
TRACE(0,"BLE NVDS SETUP SUCCESS!!!,the key is the newest");
|
|
#endif
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
case (GAPC_REPEATED_ATTEMPT):
|
|
{
|
|
appm_disconnect(conidx);
|
|
break;
|
|
}
|
|
case (GAPC_IRK_EXCH):
|
|
{
|
|
TRACE(0,"Peer device IRK is:");
|
|
#ifdef _BLE_NVDS_
|
|
DUMP8("%02x ", param->data.irk.irk.key, BLE_IRK_SIZE);
|
|
DUMP8("%02x ", (uint8_t *)&(param->data.irk.addr), BLE_ADDR_SIZE+1);
|
|
app_env.context[conidx].isBdAddrResolvingInProgress = false;
|
|
app_env.context[conidx].isGotSolvedBdAddr = true;
|
|
memcpy(app_env.context[conidx].solvedBdAddr, param->data.irk.addr.addr.addr, BLE_ADDR_SIZE);
|
|
memcpy(ble_save_info.IRK, param->data.irk.irk.key, BLE_IRK_SIZE);
|
|
memcpy(ble_save_info.peer_bleAddr, param->data.irk.addr.addr.addr, BLE_ADDR_SIZE);
|
|
#endif
|
|
app_exchange_remote_feature(conidx);
|
|
break;
|
|
}
|
|
case (GAPC_PAIRING_FAILED):
|
|
{
|
|
TRACE(1,"GAPC_PAIRING_FAILED!!! Error code 0x%x", param->data.reason);
|
|
#ifdef _BLE_NVDS_
|
|
nv_record_ble_delete_entry(app_env.context[conidx].solvedBdAddr);
|
|
app_sec_env.bonded = false;
|
|
#endif
|
|
break;
|
|
}
|
|
case GAPC_LTK_EXCH:
|
|
{
|
|
#ifdef _BLE_NVDS_
|
|
TRACE(1,"isLocal %d", param->data.ltk.isLocal);
|
|
TRACE(0,"Peer device LTK is:");
|
|
|
|
DUMP8("%02x ", param->data.ltk.ltk.key, BLE_LTK_SIZE);
|
|
TRACE(1,"EDIV %04x ", param->data.ltk.ediv);
|
|
TRACE(0,"Peer device random number is:");
|
|
DUMP8("%02x ", param->data.ltk.randnb.nb, BLE_ENC_RANDOM_SIZE);
|
|
|
|
|
|
if (param->data.ltk.isLocal)
|
|
{
|
|
ble_save_info.EDIV = param->data.ltk.ediv;
|
|
memcpy(&ble_save_info.RANDOM, (uint8_t *)¶m->data.ltk.randnb.nb, BLE_ENC_RANDOM_SIZE);
|
|
memcpy(&ble_save_info.LTK, (uint8_t *)¶m->data.ltk, BLE_LTK_SIZE);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ASSERT_ERR(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapc_encrypt_req_ind const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id)
|
|
{
|
|
TRACE(1,"%s, master ask for LTK TO encrypt!!!!", __FUNCTION__);
|
|
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
|
|
appm_check_and_resolve_ble_address(conidx);
|
|
|
|
if (!app_env.context[conidx].isGotSolvedBdAddr)
|
|
{
|
|
return (KE_MSG_SAVED);
|
|
}
|
|
|
|
TRACE(0,"Random ble address solved. Can rsp enc req.");
|
|
|
|
// Prepare the GAPC_ENCRYPT_CFM message
|
|
struct gapc_encrypt_cfm *cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM,
|
|
src_id, TASK_APP,
|
|
gapc_encrypt_cfm);
|
|
|
|
cfm->found = false;
|
|
|
|
#ifdef _BLE_NVDS_
|
|
|
|
struct gapc_ltk ltk;
|
|
|
|
bool ret;
|
|
ret = nv_record_ble_record_find_ltk_through_static_bd_addr(
|
|
app_env.context[conidx].solvedBdAddr, ltk.ltk.key);
|
|
if(ret){
|
|
TRACE(0,"FIND LTK SUCCESSED!!!");
|
|
#ifdef BLE_KEY_PRINT
|
|
DUMP8("%02x ", (uint8_t *)ltk.ltk.key, 16);
|
|
#endif
|
|
cfm->found = true;
|
|
cfm->key_size = 16;
|
|
memcpy(&cfm->ltk, ltk.ltk.key, sizeof(struct gap_sec_key));
|
|
|
|
}else{
|
|
TRACE(0,"FIND LTK failed!!!");
|
|
}
|
|
#endif
|
|
|
|
TRACE(2,"%s app_sec_env.bonded %d", __FUNCTION__, app_sec_env.bonded);
|
|
|
|
// Send the message
|
|
ke_msg_send(cfm);
|
|
|
|
// encryption has been completed, we can start exchanging remote features now
|
|
app_exchange_remote_feature(conidx);
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
|
|
static int gapc_encrypt_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapc_encrypt_ind const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id)
|
|
{
|
|
TRACE(2,"%s param->auth %d", __FUNCTION__, param->auth);
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int app_sec_msg_dflt_handler(ke_msg_id_t const msgid,
|
|
void *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id)
|
|
{
|
|
// Drop the message
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
/*
|
|
* LOCAL VARIABLE DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/// Default State handlers definition
|
|
const struct ke_msg_handler app_sec_msg_handler_list[] =
|
|
{
|
|
// Note: first message is latest message checked by kernel so default is put on top.
|
|
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_sec_msg_dflt_handler},
|
|
|
|
{GAPC_BOND_REQ_IND, (ke_msg_func_t)gapc_bond_req_ind_handler},
|
|
{GAPC_BOND_IND, (ke_msg_func_t)gapc_bond_ind_handler},
|
|
|
|
{GAPC_ENCRYPT_REQ_IND, (ke_msg_func_t)gapc_encrypt_req_ind_handler},
|
|
{GAPC_ENCRYPT_IND, (ke_msg_func_t)gapc_encrypt_ind_handler},
|
|
};
|
|
|
|
const struct ke_state_handler app_sec_table_handler =
|
|
{&app_sec_msg_handler_list[0], (sizeof(app_sec_msg_handler_list)/sizeof(struct ke_msg_handler))};
|
|
|
|
#endif //(BLE_APP_SEC)
|
|
|
|
/// @} APP
|