1 /****************************************************************************** 2 * 3 * Copyright (C) 2008-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains the implementation of the SMP interface used by 22 * applications that can run over an SMP. 23 * 24 ******************************************************************************/ 25 #include <string.h> 26 27 #include "bt_target.h" 28 #include "bt_utils.h" 29 #if SMP_INCLUDED == TRUE 30 #include "smp_int.h" 31 #include "smp_api.h" 32 #include "l2cdefs.h" 33 #include "l2c_int.h" 34 #include "btm_int.h" 35 #include "hcimsgs.h" 36 37 #include "btu.h" 38 39 40 /******************************************************************************* 41 ** 42 ** Function SMP_Init 43 ** 44 ** Description This function initializes the SMP unit. 45 ** 46 ** Returns void 47 ** 48 *******************************************************************************/ 49 void SMP_Init(void) 50 { 51 52 SMP_TRACE_EVENT ("SMP_Init"); 53 memset(&smp_cb, 0, sizeof(tSMP_CB)); 54 55 #if defined(SMP_INITIAL_TRACE_LEVEL) 56 smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL; 57 #else 58 smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 59 #endif 60 61 smp_l2cap_if_init(); 62 } 63 64 65 /******************************************************************************* 66 ** 67 ** Function SMP_SetTraceLevel 68 ** 69 ** Description This function sets the trace level for SMP. If called with 70 ** a value of 0xFF, it simply returns the current trace level. 71 ** 72 ** Input Parameters: 73 ** level: The level to set the GATT tracing to: 74 ** 0xff-returns the current setting. 75 ** 0-turns off tracing. 76 ** >= 1-Errors. 77 ** >= 2-Warnings. 78 ** >= 3-APIs. 79 ** >= 4-Events. 80 ** >= 5-Debug. 81 ** 82 ** Returns The new or current trace level 83 ** 84 *******************************************************************************/ 85 SMP_API extern UINT8 SMP_SetTraceLevel (UINT8 new_level) 86 { 87 if (new_level != 0xFF) 88 smp_cb.trace_level = new_level; 89 90 return(smp_cb.trace_level); 91 } 92 93 94 /******************************************************************************* 95 ** 96 ** Function SMP_Register 97 ** 98 ** Description This function register for the SMP services callback. 99 ** 100 ** Returns void 101 ** 102 *******************************************************************************/ 103 BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback) 104 { 105 SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state); 106 107 if (smp_cb.p_callback != NULL) 108 { 109 SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it"); 110 } 111 smp_cb.p_callback = p_cback; 112 113 return(TRUE); 114 115 } 116 117 /******************************************************************************* 118 ** 119 ** Function SMP_Pair 120 ** 121 ** Description This function call to perform a SMP pairing with peer device. 122 ** Device support one SMP pairing at one time. 123 ** 124 ** Parameters bd_addr - peer device bd address. 125 ** 126 ** Returns None 127 ** 128 *******************************************************************************/ 129 tSMP_STATUS SMP_Pair (BD_ADDR bd_addr) 130 { 131 tSMP_CB *p_cb = &smp_cb; 132 UINT8 status = SMP_PAIR_INTERNAL_ERR; 133 134 BTM_TRACE_EVENT ("SMP_Pair state=%d flag=0x%x ", p_cb->state, p_cb->flags); 135 if (p_cb->state != SMP_ST_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) 136 { 137 /* pending security on going, reject this one */ 138 return SMP_BUSY; 139 } 140 else 141 { 142 p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD; 143 144 memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN); 145 146 if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr)) 147 { 148 SMP_TRACE_ERROR("SMP_Pair: L2C connect fixed channel failed."); 149 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); 150 return status; 151 } 152 153 return SMP_STARTED; 154 } 155 } 156 157 158 /******************************************************************************* 159 ** 160 ** Function SMP_PairCancel 161 ** 162 ** Description This function call to cancel a SMP pairing with peer device. 163 ** 164 ** Parameters bd_addr - peer device bd address. 165 ** 166 ** Returns TRUE - Pairining is cancelled 167 ** 168 *******************************************************************************/ 169 BOOLEAN SMP_PairCancel (BD_ADDR bd_addr) 170 { 171 tSMP_CB *p_cb = &smp_cb; 172 UINT8 err_code = SMP_PAIR_FAIL_UNKNOWN; 173 BOOLEAN status = FALSE; 174 175 BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags); 176 if ( (p_cb->state != SMP_ST_IDLE) && 177 (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) ) 178 { 179 p_cb->is_pair_cancel = TRUE; 180 SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown"); 181 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code); 182 status = TRUE; 183 } 184 185 return status; 186 } 187 /******************************************************************************* 188 ** 189 ** Function SMP_SecurityGrant 190 ** 191 ** Description This function is called to grant security process. 192 ** 193 ** Parameters bd_addr - peer device bd address. 194 ** res - result of the operation SMP_SUCCESS if success. 195 ** Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts. 196 ** 197 ** Returns None 198 ** 199 *******************************************************************************/ 200 void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res) 201 { 202 SMP_TRACE_EVENT ("SMP_SecurityGrant "); 203 if (smp_cb.state != SMP_ST_WAIT_APP_RSP || 204 smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || 205 memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) 206 return; 207 208 /* clear the SMP_SEC_REQUEST_EVT event after get grant */ 209 /* avoid generate duplicate pair request */ 210 smp_cb.cb_evt = 0; 211 smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res); 212 } 213 214 /******************************************************************************* 215 ** 216 ** Function SMP_PasskeyReply 217 ** 218 ** Description This function is called after Security Manager submitted 219 ** passkey request to the application. 220 ** 221 ** Parameters: bd_addr - Address of the device for which passkey was requested 222 ** res - result of the operation SMP_SUCCESS if success 223 ** passkey - numeric value in the range of 224 ** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)). 225 ** 226 *******************************************************************************/ 227 void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey) 228 { 229 tSMP_CB *p_cb = & smp_cb; 230 UINT8 failure = SMP_PASSKEY_ENTRY_FAIL; 231 tBTM_SEC_DEV_REC *p_dev_rec; 232 233 SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d Result:%d", 234 passkey, res); 235 236 /* If timeout already expired or has been canceled, ignore the reply */ 237 if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT) 238 { 239 SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state); 240 return; 241 } 242 243 if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) 244 { 245 SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr"); 246 return; 247 } 248 249 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL) 250 { 251 SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB"); 252 return; 253 } 254 255 256 if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS) 257 { 258 SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey); 259 /* send pairing failure */ 260 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 261 262 } 263 else 264 { 265 smp_convert_string_to_tk(p_cb->tk, passkey); 266 } 267 268 return; 269 } 270 271 /******************************************************************************* 272 ** 273 ** Function SMP_OobDataReply 274 ** 275 ** Description This function is called to provide the OOB data for 276 ** SMP in response to SMP_OOB_REQ_EVT 277 ** 278 ** Parameters: bd_addr - Address of the peer device 279 ** res - result of the operation SMP_SUCCESS if success 280 ** p_data - simple pairing Randomizer C. 281 ** 282 *******************************************************************************/ 283 void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data) 284 { 285 tSMP_CB *p_cb = & smp_cb; 286 UINT8 failure = SMP_OOB_FAIL; 287 tSMP_KEY key; 288 UNUSED(bd_addr); 289 290 SMP_TRACE_EVENT ("SMP_OobDataReply State: %d res:%d", 291 smp_cb.state, res); 292 293 /* If timeout already expired or has been canceled, ignore the reply */ 294 if (p_cb->state != SMP_ST_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT) 295 return; 296 297 if (res != SMP_SUCCESS || len == 0 || !p_data) 298 { 299 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 300 } 301 else 302 { 303 if (len > BT_OCTET16_LEN) 304 len = BT_OCTET16_LEN; 305 306 memcpy(p_cb->tk, p_data, len); 307 308 key.key_type = SMP_KEY_TYPE_TK; 309 key.p_data = p_cb->tk; 310 311 smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key); 312 } 313 } 314 315 /******************************************************************************* 316 ** 317 ** Function SMP_Encrypt 318 ** 319 ** Description This function is called to encrypt the data with the specified 320 ** key 321 ** 322 ** Parameters: key - Pointer to key key[0] conatins the MSB 323 ** key_len - key length 324 ** plain_text - Pointer to data to be encrypted 325 ** plain_text[0] conatins the MSB 326 ** pt_len - plain text length 327 ** p_out - output of the encrypted texts 328 ** 329 ** Returns Boolean - request is successful 330 *******************************************************************************/ 331 BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len, 332 UINT8 *plain_text, UINT8 pt_len, 333 tSMP_ENC *p_out) 334 335 { 336 BOOLEAN status=FALSE; 337 status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out); 338 return status; 339 } 340 #endif /* SMP_INCLUDED */ 341 342 343