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