1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-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 GATT authentication handling functions
22  *
23  ******************************************************************************/
24 #include "bt_target.h"
25 #include "bt_utils.h"
26 
27 #include <string.h>
28 #include "bt_common.h"
29 
30 #include "btm_int.h"
31 #include "gatt_api.h"
32 #include "gatt_int.h"
33 #include "osi/include/osi.h"
34 
35 /*******************************************************************************
36  *
37  * Function         gatt_sign_data
38  *
39  * Description      This function sign the data for write command.
40  *
41  * Returns          true if encrypted, otherwise false.
42  *
43  ******************************************************************************/
gatt_sign_data(tGATT_CLCB * p_clcb)44 static bool gatt_sign_data(tGATT_CLCB* p_clcb) {
45   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
46   uint8_t *p_data = NULL, *p;
47   uint16_t payload_size = p_clcb->p_tcb->payload_size;
48   bool status = false;
49   uint8_t* p_signature;
50 
51   /* do not need to mark channel securoty activity for data signing */
52   gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_OK);
53 
54   p_data =
55       (uint8_t*)osi_malloc(p_attr->len + 3); /* 3 = 2 byte handle + opcode */
56 
57   p = p_data;
58   UINT8_TO_STREAM(p, GATT_SIGN_CMD_WRITE);
59   UINT16_TO_STREAM(p, p_attr->handle);
60   ARRAY_TO_STREAM(p, p_attr->value, p_attr->len);
61 
62   /* sign data length should be attribulte value length plus 2B handle + 1B op
63    * code */
64   if ((payload_size - GATT_AUTH_SIGN_LEN - 3) < p_attr->len)
65     p_attr->len = payload_size - GATT_AUTH_SIGN_LEN - 3;
66 
67   p_signature = p_attr->value + p_attr->len;
68   if (BTM_BleDataSignature(
69           p_clcb->p_tcb->peer_bda, p_data,
70           (uint16_t)(p_attr->len + 3), /* 3 = 2 byte handle + opcode */
71           p_signature)) {
72     p_attr->len += BTM_BLE_AUTH_SIGN_LEN;
73     gatt_set_ch_state(p_clcb->p_tcb, GATT_CH_OPEN);
74     gatt_act_write(p_clcb, GATT_SEC_SIGN_DATA);
75   } else {
76     gatt_end_operation(p_clcb, GATT_INTERNAL_ERROR, NULL);
77   }
78 
79   osi_free(p_data);
80 
81   return status;
82 }
83 
84 /*******************************************************************************
85  *
86  * Function         gatt_verify_signature
87  *
88  * Description      This function start to verify the sign data when receiving
89  *                  the data from peer device.
90  *
91  * Returns
92  *
93  ******************************************************************************/
gatt_verify_signature(tGATT_TCB * p_tcb,BT_HDR * p_buf)94 void gatt_verify_signature(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
95   uint16_t cmd_len;
96   uint8_t op_code;
97   uint8_t *p, *p_orig = (uint8_t *)(p_buf + 1) + p_buf->offset;
98   uint32_t counter;
99 
100   if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) {
101     GATT_TRACE_ERROR("%s: Data length %u less than expected %u", __func__,
102                      p_buf->len, GATT_AUTH_SIGN_LEN + 4);
103     return;
104   }
105   cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4;
106   p = p_orig + cmd_len - 4;
107   STREAM_TO_UINT32(counter, p);
108 
109   if (BTM_BleVerifySignature(p_tcb->peer_bda, p_orig, cmd_len, counter, p)) {
110     STREAM_TO_UINT8(op_code, p_orig);
111     gatt_server_handle_client_req(p_tcb, op_code, (uint16_t)(p_buf->len - 1),
112                                   p_orig);
113   } else {
114     /* if this is a bad signature, assume from attacker, ignore it  */
115     GATT_TRACE_ERROR("Signature Verification Failed, data ignored");
116   }
117 
118   return;
119 }
120 /*******************************************************************************
121  *
122  * Function         gatt_sec_check_complete
123  *
124  * Description      security check complete and proceed to data sending action.
125  *
126  * Returns          void.
127  *
128  ******************************************************************************/
gatt_sec_check_complete(bool sec_check_ok,tGATT_CLCB * p_clcb,uint8_t sec_act)129 void gatt_sec_check_complete(bool sec_check_ok, tGATT_CLCB* p_clcb,
130                              uint8_t sec_act) {
131   if (p_clcb && p_clcb->p_tcb &&
132       fixed_queue_is_empty(p_clcb->p_tcb->pending_enc_clcb)) {
133     gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
134   }
135 
136   if (!sec_check_ok) {
137     gatt_end_operation(p_clcb, GATT_AUTH_FAIL, NULL);
138   } else if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
139     gatt_act_write(p_clcb, sec_act);
140   } else if (p_clcb->operation == GATTC_OPTYPE_READ) {
141     gatt_act_read(p_clcb, p_clcb->counter);
142   }
143 }
144 /*******************************************************************************
145  *
146  * Function         gatt_enc_cmpl_cback
147  *
148  * Description      link encryption complete callback.
149  *
150  * Returns
151  *
152  ******************************************************************************/
gatt_enc_cmpl_cback(BD_ADDR bd_addr,tBT_TRANSPORT transport,UNUSED_ATTR void * p_ref_data,tBTM_STATUS result)153 void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
154                          UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
155   tGATT_TCB* p_tcb;
156   uint8_t sec_flag;
157   bool status = false;
158 
159   GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
160   p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
161   if (p_tcb != NULL) {
162     if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return;
163 
164     tGATT_PENDING_ENC_CLCB* p_buf =
165         (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
166             p_tcb->pending_enc_clcb);
167     if (p_buf != NULL) {
168       if (result == BTM_SUCCESS) {
169         if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
170           BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
171 
172           if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
173             status = true;
174           }
175         } else {
176           status = true;
177         }
178       }
179       gatt_sec_check_complete(status, p_buf->p_clcb, p_tcb->sec_act);
180       osi_free(p_buf);
181       /* start all other pending operation in queue */
182       for (size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
183            count > 0; count--) {
184         p_buf = (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
185             p_tcb->pending_enc_clcb);
186         if (p_buf != NULL) {
187           gatt_security_check_start(p_buf->p_clcb);
188           osi_free(p_buf);
189         } else
190           break;
191       }
192     } else {
193       GATT_TRACE_ERROR("Unknown operation encryption completed");
194     }
195   } else {
196     GATT_TRACE_ERROR("enc callback for unknown bd_addr");
197   }
198 }
199 
200 /*******************************************************************************
201  *
202  * Function         gatt_notify_enc_cmpl
203  *
204  * Description      link encryption complete notification for all encryption
205  *                  process initiated outside GATT.
206  *
207  * Returns
208  *
209  ******************************************************************************/
gatt_notify_enc_cmpl(BD_ADDR bd_addr)210 void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
211   tGATT_TCB* p_tcb;
212   uint8_t i = 0;
213 
214   p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
215   if (p_tcb != NULL) {
216     for (i = 0; i < GATT_MAX_APPS; i++) {
217       if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
218         (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if,
219                                                   bd_addr);
220       }
221     }
222 
223     if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
224       gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
225 
226       size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
227       for (; count > 0; count--) {
228         tGATT_PENDING_ENC_CLCB* p_buf =
229             (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
230                 p_tcb->pending_enc_clcb);
231         if (p_buf != NULL) {
232           gatt_security_check_start(p_buf->p_clcb);
233           osi_free(p_buf);
234         } else
235           break;
236       }
237     }
238   } else {
239     GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
240   }
241   return;
242 }
243 /*******************************************************************************
244  *
245  * Function         gatt_set_sec_act
246  *
247  * Description      This function set the sec_act in clcb
248  *
249  * Returns          none
250  *
251  ******************************************************************************/
gatt_set_sec_act(tGATT_TCB * p_tcb,tGATT_SEC_ACTION sec_act)252 void gatt_set_sec_act(tGATT_TCB* p_tcb, tGATT_SEC_ACTION sec_act) {
253   if (p_tcb) {
254     p_tcb->sec_act = sec_act;
255   }
256 }
257 /*******************************************************************************
258  *
259  * Function         gatt_get_sec_act
260  *
261  * Description      This function get the sec_act in clcb
262  *
263  * Returns          none
264  *
265  ******************************************************************************/
gatt_get_sec_act(tGATT_TCB * p_tcb)266 tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB* p_tcb) {
267   tGATT_SEC_ACTION sec_act = GATT_SEC_NONE;
268   if (p_tcb) {
269     sec_act = p_tcb->sec_act;
270   }
271   return sec_act;
272 }
273 /*******************************************************************************
274  *
275  * Function         gatt_determine_sec_act
276  *
277  * Description      This routine determine the security action based on
278  *                  auth_request and current link status
279  *
280  * Returns          tGATT_SEC_ACTION security action
281  *
282  ******************************************************************************/
gatt_determine_sec_act(tGATT_CLCB * p_clcb)283 tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB* p_clcb) {
284   tGATT_SEC_ACTION act = GATT_SEC_OK;
285   uint8_t sec_flag;
286   tGATT_TCB* p_tcb = p_clcb->p_tcb;
287   tGATT_AUTH_REQ auth_req = p_clcb->auth_req;
288   bool is_link_encrypted = false;
289   bool is_link_key_known = false;
290   bool is_key_mitm = false;
291   uint8_t key_type;
292   tBTM_BLE_SEC_REQ_ACT sec_act = BTM_LE_SEC_NONE;
293 
294   if (auth_req == GATT_AUTH_REQ_NONE) return act;
295 
296   BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag,
297                                   p_clcb->p_tcb->transport);
298 
299   btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act);
300 
301   /* if a encryption is pending, need to wait */
302   if (sec_act == BTM_BLE_SEC_REQ_ACT_DISCARD && auth_req != GATT_AUTH_REQ_NONE)
303     return GATT_SEC_ENC_PENDING;
304 
305   if (sec_flag & (BTM_SEC_FLAG_ENCRYPTED | BTM_SEC_FLAG_LKEY_KNOWN)) {
306     if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) is_link_encrypted = true;
307 
308     is_link_key_known = true;
309 
310     if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) is_key_mitm = true;
311   }
312 
313   /* first check link key upgrade required or not */
314   switch (auth_req) {
315     case GATT_AUTH_REQ_MITM:
316     case GATT_AUTH_REQ_SIGNED_MITM:
317       if (!is_key_mitm) act = GATT_SEC_ENCRYPT_MITM;
318       break;
319 
320     case GATT_AUTH_REQ_NO_MITM:
321     case GATT_AUTH_REQ_SIGNED_NO_MITM:
322       if (!is_link_key_known) act = GATT_SEC_ENCRYPT_NO_MITM;
323       break;
324     default:
325       break;
326   }
327 
328   /* now check link needs to be encrypted or not if the link key upgrade is not
329    * required */
330   if (act == GATT_SEC_OK) {
331     if (p_tcb->transport == BT_TRANSPORT_LE &&
332         (p_clcb->operation == GATTC_OPTYPE_WRITE) &&
333         (p_clcb->op_subtype == GATT_WRITE_NO_RSP)) {
334       /* this is a write command request
335          check data signing required or not */
336       if (!is_link_encrypted) {
337         btm_ble_get_enc_key_type(p_tcb->peer_bda, &key_type);
338 
339         if ((key_type & BTM_LE_KEY_LCSRK) &&
340             ((auth_req == GATT_AUTH_REQ_SIGNED_NO_MITM) ||
341              (auth_req == GATT_AUTH_REQ_SIGNED_MITM))) {
342           act = GATT_SEC_SIGN_DATA;
343         } else {
344           act = GATT_SEC_ENCRYPT;
345         }
346       }
347     } else {
348       if (!is_link_encrypted) {
349         act = GATT_SEC_ENCRYPT;
350       }
351     }
352   }
353 
354   return act;
355 }
356 
357 /*******************************************************************************
358  *
359  * Function         gatt_get_link_encrypt_status
360  *
361  * Description      This routine get the encryption status of the specified link
362  *
363  *
364  * Returns          tGATT_STATUS link encryption status
365  *
366  ******************************************************************************/
gatt_get_link_encrypt_status(tGATT_TCB * p_tcb)367 tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB* p_tcb) {
368   tGATT_STATUS encrypt_status = GATT_NOT_ENCRYPTED;
369   uint8_t sec_flag = 0;
370 
371   BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_tcb->transport);
372 
373   if ((sec_flag & BTM_SEC_FLAG_ENCRYPTED) &&
374       (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN)) {
375     encrypt_status = GATT_ENCRYPED_NO_MITM;
376     if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
377       encrypt_status = GATT_ENCRYPED_MITM;
378   }
379 
380   GATT_TRACE_DEBUG("gatt_get_link_encrypt_status status=0x%x", encrypt_status);
381   return encrypt_status;
382 }
383 
384 /*******************************************************************************
385  *
386  * Function         gatt_convert_sec_action
387  *
388  * Description      Convert GATT security action enum into equivalent
389  *                  BTM BLE security action enum
390  *
391  * Returns          bool    true - conversation is successful
392  *
393  ******************************************************************************/
gatt_convert_sec_action(tGATT_SEC_ACTION gatt_sec_act,tBTM_BLE_SEC_ACT * p_btm_sec_act)394 static bool gatt_convert_sec_action(tGATT_SEC_ACTION gatt_sec_act,
395                                     tBTM_BLE_SEC_ACT* p_btm_sec_act) {
396   bool status = true;
397   switch (gatt_sec_act) {
398     case GATT_SEC_ENCRYPT:
399       *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT;
400       break;
401     case GATT_SEC_ENCRYPT_NO_MITM:
402       *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT_NO_MITM;
403       break;
404     case GATT_SEC_ENCRYPT_MITM:
405       *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT_MITM;
406       break;
407     default:
408       status = false;
409       break;
410   }
411 
412   return status;
413 }
414 /*******************************************************************************
415  *
416  * Function         gatt_check_enc_req
417  *
418  * Description      check link security.
419  *
420  * Returns          true if encrypted, otherwise false.
421  *
422  ******************************************************************************/
gatt_security_check_start(tGATT_CLCB * p_clcb)423 bool gatt_security_check_start(tGATT_CLCB* p_clcb) {
424   tGATT_TCB* p_tcb = p_clcb->p_tcb;
425   tGATT_SEC_ACTION gatt_sec_act;
426   tBTM_BLE_SEC_ACT btm_ble_sec_act;
427   bool status = true;
428   tBTM_STATUS btm_status;
429   tGATT_SEC_ACTION sec_act_old = gatt_get_sec_act(p_tcb);
430 
431   gatt_sec_act = gatt_determine_sec_act(p_clcb);
432 
433   if (sec_act_old == GATT_SEC_NONE) gatt_set_sec_act(p_tcb, gatt_sec_act);
434 
435   switch (gatt_sec_act) {
436     case GATT_SEC_SIGN_DATA:
437       GATT_TRACE_DEBUG("gatt_security_check_start: Do data signing");
438       gatt_sign_data(p_clcb);
439       break;
440     case GATT_SEC_ENCRYPT:
441     case GATT_SEC_ENCRYPT_NO_MITM:
442     case GATT_SEC_ENCRYPT_MITM:
443       if (sec_act_old < GATT_SEC_ENCRYPT) {
444         GATT_TRACE_DEBUG(
445             "gatt_security_check_start: Encrypt now or key upgreade first");
446         gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
447         btm_status =
448             BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport,
449                               gatt_enc_cmpl_cback, NULL, btm_ble_sec_act);
450         if ((btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED)) {
451           GATT_TRACE_ERROR(
452               "gatt_security_check_start BTM_SetEncryption failed "
453               "btm_status=%d",
454               btm_status);
455           status = false;
456         }
457       }
458       if (status) gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
459       break;
460     case GATT_SEC_ENC_PENDING:
461       gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
462       /* wait for link encrypotion to finish */
463       break;
464     default:
465       gatt_sec_check_complete(true, p_clcb, gatt_sec_act);
466       break;
467   }
468 
469   if (status == false) {
470     gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
471     gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
472   }
473 
474   return status;
475 }
476