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 #include "p_256_ecc_pp.h"
39
40 /*******************************************************************************
41 **
42 ** Function SMP_Init
43 **
44 ** Description This function initializes the SMP unit.
45 **
46 ** Returns void
47 **
48 *******************************************************************************/
SMP_Init(void)49 void SMP_Init(void)
50 {
51 memset(&smp_cb, 0, sizeof(tSMP_CB));
52
53 #if defined(SMP_INITIAL_TRACE_LEVEL)
54 smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
55 #else
56 smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
57 #endif
58 SMP_TRACE_EVENT ("%s", __FUNCTION__);
59
60 smp_l2cap_if_init();
61 /* initialization of P-256 parameters */
62 p_256_init_curve(KEY_LENGTH_DWORDS_P256);
63 }
64
65
66 /*******************************************************************************
67 **
68 ** Function SMP_SetTraceLevel
69 **
70 ** Description This function sets the trace level for SMP. If called with
71 ** a value of 0xFF, it simply returns the current trace level.
72 **
73 ** Input Parameters:
74 ** level: The level to set the GATT tracing to:
75 ** 0xff-returns the current setting.
76 ** 0-turns off tracing.
77 ** >= 1-Errors.
78 ** >= 2-Warnings.
79 ** >= 3-APIs.
80 ** >= 4-Events.
81 ** >= 5-Debug.
82 **
83 ** Returns The new or current trace level
84 **
85 *******************************************************************************/
SMP_SetTraceLevel(UINT8 new_level)86 extern UINT8 SMP_SetTraceLevel (UINT8 new_level)
87 {
88 if (new_level != 0xFF)
89 smp_cb.trace_level = new_level;
90
91 return(smp_cb.trace_level);
92 }
93
94
95 /*******************************************************************************
96 **
97 ** Function SMP_Register
98 **
99 ** Description This function register for the SMP services callback.
100 **
101 ** Returns void
102 **
103 *******************************************************************************/
SMP_Register(tSMP_CALLBACK * p_cback)104 BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback)
105 {
106 SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state);
107
108 if (smp_cb.p_callback != NULL)
109 {
110 SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it");
111 }
112 smp_cb.p_callback = p_cback;
113
114 return(TRUE);
115
116 }
117
118 /*******************************************************************************
119 **
120 ** Function SMP_Pair
121 **
122 ** Description This function call to perform a SMP pairing with peer device.
123 ** Device support one SMP pairing at one time.
124 **
125 ** Parameters bd_addr - peer device bd address.
126 **
127 ** Returns None
128 **
129 *******************************************************************************/
SMP_Pair(BD_ADDR bd_addr)130 tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
131 {
132 tSMP_CB *p_cb = &smp_cb;
133 UINT8 status = SMP_PAIR_INTERNAL_ERR;
134
135 SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
136 __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
137 if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
138 p_cb->smp_over_br)
139 {
140 /* pending security on going, reject this one */
141 return SMP_BUSY;
142 }
143 else
144 {
145 p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
146
147 memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
148
149 if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
150 {
151 SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
152 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
153 return status;
154 }
155
156 return SMP_STARTED;
157 }
158 }
159
160 /*******************************************************************************
161 **
162 ** Function SMP_BR_PairWith
163 **
164 ** Description This function is called to start a SMP pairing over BR/EDR.
165 ** Device support one SMP pairing at one time.
166 **
167 ** Parameters bd_addr - peer device bd address.
168 **
169 ** Returns SMP_STARTED if pairing started, otherwise reason for failure.
170 **
171 *******************************************************************************/
SMP_BR_PairWith(BD_ADDR bd_addr)172 tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
173 {
174 tSMP_CB *p_cb = &smp_cb;
175 UINT8 status = SMP_PAIR_INTERNAL_ERR;
176
177 SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
178 __func__, p_cb->state, p_cb->br_state, p_cb->flags);
179
180 if (p_cb->state != SMP_STATE_IDLE ||
181 p_cb->smp_over_br ||
182 p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
183 {
184 /* pending security on going, reject this one */
185 return SMP_BUSY;
186 }
187
188 p_cb->role = HCI_ROLE_MASTER;
189 p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
190 p_cb->smp_over_br = TRUE;
191
192 memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
193
194 if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr))
195 {
196 SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.",__FUNCTION__);
197 smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
198 return status;
199 }
200
201 return SMP_STARTED;
202 }
203
204 /*******************************************************************************
205 **
206 ** Function SMP_PairCancel
207 **
208 ** Description This function call to cancel a SMP pairing with peer device.
209 **
210 ** Parameters bd_addr - peer device bd address.
211 **
212 ** Returns TRUE - Pairining is cancelled
213 **
214 *******************************************************************************/
SMP_PairCancel(BD_ADDR bd_addr)215 BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
216 {
217 tSMP_CB *p_cb = &smp_cb;
218 UINT8 err_code = SMP_PAIR_FAIL_UNKNOWN;
219 BOOLEAN status = FALSE;
220
221 BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
222 if ( (p_cb->state != SMP_STATE_IDLE) &&
223 (!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
224 {
225 p_cb->is_pair_cancel = TRUE;
226 SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
227 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
228 status = TRUE;
229 }
230
231 return status;
232 }
233 /*******************************************************************************
234 **
235 ** Function SMP_SecurityGrant
236 **
237 ** Description This function is called to grant security process.
238 **
239 ** Parameters bd_addr - peer device bd address.
240 ** res - result of the operation SMP_SUCCESS if success.
241 ** Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
242 **
243 ** Returns None
244 **
245 *******************************************************************************/
SMP_SecurityGrant(BD_ADDR bd_addr,UINT8 res)246 void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
247 {
248 SMP_TRACE_EVENT ("SMP_SecurityGrant ");
249
250 if (smp_cb.smp_over_br)
251 {
252 if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
253 smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
254 memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
255 {
256 return;
257 }
258
259 /* clear the SMP_SEC_REQUEST_EVT event after get grant */
260 /* avoid generating duplicate pair request */
261 smp_cb.cb_evt = 0;
262 smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
263 return;
264 }
265
266 if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
267 smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
268 memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
269 return;
270 /* clear the SMP_SEC_REQUEST_EVT event after get grant */
271 /* avoid generate duplicate pair request */
272 smp_cb.cb_evt = 0;
273 smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
274 }
275
276 /*******************************************************************************
277 **
278 ** Function SMP_PasskeyReply
279 **
280 ** Description This function is called after Security Manager submitted
281 ** passkey request to the application.
282 **
283 ** Parameters: bd_addr - Address of the device for which passkey was requested
284 ** res - result of the operation SMP_SUCCESS if success
285 ** passkey - numeric value in the range of
286 ** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
287 **
288 *******************************************************************************/
SMP_PasskeyReply(BD_ADDR bd_addr,UINT8 res,UINT32 passkey)289 void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
290 {
291 tSMP_CB *p_cb = & smp_cb;
292 UINT8 failure = SMP_PASSKEY_ENTRY_FAIL;
293
294 SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d Result:%d",
295 passkey, res);
296
297 /* If timeout already expired or has been canceled, ignore the reply */
298 if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT)
299 {
300 SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong State: %d", p_cb->state);
301 return;
302 }
303
304 if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
305 {
306 SMP_TRACE_ERROR ("SMP_PasskeyReply() - Wrong BD Addr");
307 return;
308 }
309
310 if (btm_find_dev (bd_addr) == NULL)
311 {
312 SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
313 return;
314 }
315
316 if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
317 {
318 SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
319 /* send pairing failure */
320 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
321
322 }
323 else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT)
324 {
325 smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
326 }
327 else
328 {
329 smp_convert_string_to_tk(p_cb->tk, passkey);
330 }
331
332 return;
333 }
334
335 /*******************************************************************************
336 **
337 ** Function SMP_ConfirmReply
338 **
339 ** Description This function is called after Security Manager submitted
340 ** numeric comparison request to the application.
341 **
342 ** Parameters: bd_addr - Address of the device with which numeric
343 ** comparison was requested
344 ** res - comparison result SMP_SUCCESS if success
345 **
346 *******************************************************************************/
SMP_ConfirmReply(BD_ADDR bd_addr,UINT8 res)347 void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
348 {
349 tSMP_CB *p_cb = & smp_cb;
350 UINT8 failure = SMP_NUMERIC_COMPAR_FAIL;
351
352 SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
353
354 /* If timeout already expired or has been canceled, ignore the reply */
355 if (p_cb->cb_evt != SMP_NC_REQ_EVT)
356 {
357 SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__,p_cb->state);
358 return;
359 }
360
361 if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
362 {
363 SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
364 return;
365 }
366
367 if (btm_find_dev (bd_addr) == NULL)
368 {
369 SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
370 return;
371 }
372
373 if (res != SMP_SUCCESS)
374 {
375 SMP_TRACE_WARNING ("%s() - Numeric Comparison fails",__FUNCTION__);
376 /* send pairing failure */
377 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
378 }
379 else
380 {
381 smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
382 }
383 }
384
385 /*******************************************************************************
386 **
387 ** Function SMP_OobDataReply
388 **
389 ** Description This function is called to provide the OOB data for
390 ** SMP in response to SMP_OOB_REQ_EVT
391 **
392 ** Parameters: bd_addr - Address of the peer device
393 ** res - result of the operation SMP_SUCCESS if success
394 ** p_data - simple pairing Randomizer C.
395 **
396 *******************************************************************************/
SMP_OobDataReply(BD_ADDR bd_addr,tSMP_STATUS res,UINT8 len,UINT8 * p_data)397 void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data)
398 {
399 tSMP_CB *p_cb = & smp_cb;
400 UINT8 failure = SMP_OOB_FAIL;
401 tSMP_KEY key;
402
403 SMP_TRACE_EVENT ("%s State: %d res:%d", __FUNCTION__, smp_cb.state, res);
404
405 /* If timeout already expired or has been canceled, ignore the reply */
406 if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
407 return;
408
409 if (res != SMP_SUCCESS || len == 0 || !p_data)
410 {
411 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
412 }
413 else
414 {
415 if (len > BT_OCTET16_LEN)
416 len = BT_OCTET16_LEN;
417
418 memcpy(p_cb->tk, p_data, len);
419
420 key.key_type = SMP_KEY_TYPE_TK;
421 key.p_data = p_cb->tk;
422
423 smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key);
424 }
425 }
426
427 /*******************************************************************************
428 **
429 ** Function SMP_SecureConnectionOobDataReply
430 **
431 ** Description This function is called to provide the SC OOB data for
432 ** SMP in response to SMP_SC_OOB_REQ_EVT
433 **
434 ** Parameters: p_data - pointer to the data
435 **
436 *******************************************************************************/
SMP_SecureConnectionOobDataReply(UINT8 * p_data)437 void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
438 {
439 tSMP_CB *p_cb = &smp_cb;
440
441 UINT8 failure = SMP_OOB_FAIL;
442 tSMP_SC_OOB_DATA *p_oob = (tSMP_SC_OOB_DATA *) p_data;
443 if (!p_oob)
444 {
445 SMP_TRACE_ERROR("%s received no data",__FUNCTION__);
446 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
447 return;
448 }
449
450 SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
451 "peer_oob_data.present: %d",
452 __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
453 p_oob->peer_oob_data.present);
454
455 if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT)
456 return;
457
458 BOOLEAN data_missing = FALSE;
459 switch (p_cb->req_oob_type)
460 {
461 case SMP_OOB_PEER:
462 if (!p_oob->peer_oob_data.present)
463 data_missing = TRUE;
464 break;
465 case SMP_OOB_LOCAL:
466 if (!p_oob->loc_oob_data.present)
467 data_missing = TRUE;
468 break;
469 case SMP_OOB_BOTH:
470 if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present)
471 data_missing = TRUE;
472 break;
473 default:
474 SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
475 data_missing = TRUE;
476 break;
477 }
478
479 if (data_missing)
480 {
481 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
482 return;
483 }
484
485 p_cb->sc_oob_data = *p_oob;
486
487 smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
488 }
489
490 /*******************************************************************************
491 **
492 ** Function SMP_Encrypt
493 **
494 ** Description This function is called to encrypt the data with the specified
495 ** key
496 **
497 ** Parameters: key - Pointer to key key[0] conatins the MSB
498 ** key_len - key length
499 ** plain_text - Pointer to data to be encrypted
500 ** plain_text[0] conatins the MSB
501 ** pt_len - plain text length
502 ** p_out - output of the encrypted texts
503 **
504 ** Returns Boolean - request is successful
505 *******************************************************************************/
SMP_Encrypt(UINT8 * key,UINT8 key_len,UINT8 * plain_text,UINT8 pt_len,tSMP_ENC * p_out)506 BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
507 UINT8 *plain_text, UINT8 pt_len,
508 tSMP_ENC *p_out)
509
510 {
511 BOOLEAN status=FALSE;
512 status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
513 return status;
514 }
515
516 /*******************************************************************************
517 **
518 ** Function SMP_KeypressNotification
519 **
520 ** Description This function is called to notify Security Manager about Keypress Notification.
521 **
522 ** Parameters: bd_addr Address of the device to send keypress notification to
523 ** value Keypress notification parameter value
524 **
525 *******************************************************************************/
SMP_KeypressNotification(BD_ADDR bd_addr,UINT8 value)526 void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
527 {
528 tSMP_CB *p_cb = &smp_cb;
529
530 SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__,value);
531
532 if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
533 {
534 SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
535 return;
536 }
537
538 if (btm_find_dev (bd_addr) == NULL)
539 {
540 SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
541 return;
542 }
543
544 /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
545 /* during the passkey entry protocol */
546 if (p_cb->local_io_capability != SMP_IO_CAP_IN)
547 {
548 SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
549 __FUNCTION__, p_cb->local_io_capability);
550 return;
551 }
552
553 if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT)
554 {
555 SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
556 p_cb->selected_association_model);
557 return;
558 }
559
560 smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
561 }
562
563 /*******************************************************************************
564 **
565 ** Function SMP_CreateLocalSecureConnectionsOobData
566 **
567 ** Description This function is called to start creation of local SC OOB
568 ** data set (tSMP_LOC_OOB_DATA).
569 **
570 ** Parameters: bd_addr - Address of the device to send OOB data block to
571 **
572 ** Returns Boolean - TRUE: creation of local SC OOB data set started.
573 *******************************************************************************/
SMP_CreateLocalSecureConnectionsOobData(tBLE_BD_ADDR * addr_to_send_to)574 BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to)
575 {
576 tSMP_CB *p_cb = &smp_cb;
577 UINT8 *bd_addr;
578
579 if (addr_to_send_to == NULL)
580 {
581 SMP_TRACE_ERROR ("%s addr_to_send_to is not provided",__FUNCTION__);
582 return FALSE;
583 }
584
585 bd_addr = addr_to_send_to->bda;
586
587 SMP_TRACE_EVENT ("%s addr type: %u, BDA: %08x%04x, state: %u, br_state: %u",
588 __FUNCTION__, addr_to_send_to->type,
589 (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
590 (bd_addr[4]<<8)+bd_addr[5],
591 p_cb->state,
592 p_cb->br_state);
593
594 if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br))
595 {
596 SMP_TRACE_WARNING ("%s creation of local OOB data set "\
597 "starts only in IDLE state",__FUNCTION__);
598 return FALSE;
599 }
600
601 p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to;
602 smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
603
604 return TRUE;
605 }
606
607 #endif /* SMP_INCLUDED */
608